From patchwork Wed Mar 15 18:20:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gary R Hook X-Patchwork-Id: 9626393 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 558BC6048C for ; Wed, 15 Mar 2017 18:25:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4A68728629 for ; Wed, 15 Mar 2017 18:25:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3ED002864D; Wed, 15 Mar 2017 18:25:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A24F228629 for ; Wed, 15 Mar 2017 18:25:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753085AbdCOSXX (ORCPT ); Wed, 15 Mar 2017 14:23:23 -0400 Received: from mail-by2nam03on0089.outbound.protection.outlook.com ([104.47.42.89]:14016 "EHLO NAM03-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753519AbdCOSWT (ORCPT ); Wed, 15 Mar 2017 14:22:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=FygHEWnGkVIvBPBun62P31Fy4rzyBdnKQ/G356ML2eY=; b=Fs6PSD3ffsJDK3hpT89yqK5f7WbuL/f5Yqtn1dcUcPQu6/Fty/O8q2UW72yti/NsKXn+vrZTAGQd8f4CgSygIRmO4srzf+EIekfB5fr/iYV3aUPRQBCr5jZNhcv6sSJ9MzStr3skRvnZtIFQ6DHXasFPcS8z3m4CGHZsJ55cLPY= Authentication-Results: amd.com; dkim=none (message not signed) header.d=none;amd.com; dmarc=none action=none header.from=amd.com; Received: from [10.236.19.42] (165.204.77.1) by SN1PR12MB0477.namprd12.prod.outlook.com (10.162.105.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.961.17; Wed, 15 Mar 2017 18:21:00 +0000 Subject: [PATCH V3 2/3] crypto: ccp - Enable 3DES function on v5 CCPs From: Gary R Hook To: CC: , , , Date: Wed, 15 Mar 2017 13:20:52 -0500 Message-ID: <20170315182052.29335.14999.stgit@taos> In-Reply-To: <20170315182014.29335.93268.stgit@taos> References: <20170315182014.29335.93268.stgit@taos> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: BN6PR15CA0003.namprd15.prod.outlook.com (10.172.204.141) To SN1PR12MB0477.namprd12.prod.outlook.com (10.162.105.146) X-MS-Office365-Filtering-Correlation-Id: d20f56bb-1ee2-4f19-e330-08d46bd008e8 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:SN1PR12MB0477; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0477; 3:ipo2PZfiYnAN+VledKZQSSz/TVfYADSaJzGAMpbcGvRta92MU2ETbPKCgEfWsx5BPuHVNLi3DB93bHbLFuJdYTv21UKQKObXh7jFDqxbI9OzcikV48RWrBk3LNOXkiZl6MWfUe2sBaKwdojoX+lTyhNgZtvO8Gq8UoCf1j2Lc0HlibWNBY/RvotDJisN2sei7madEy0jxa4lbFO6YGQElMLjjIg3gTpytH0apx2ikkAHhJvuIbR7o1Qs5eXGksS2St1z7ku9+vUcCKdHTnWkFCc240QZuKX6ytV9Jbr1Dog=; 25:PyNYZj0hU/hPx6k+TMyKvuzKMdzcX0TJKOtcRt42ERecvJNsz5STApvrI1EoNz963Cd4oDQMwt9JK0T5Jbd6ry9JPrqzLsTSV2oGat64WZq6425jI75ZsvnJf10XgeZw1F/cso9BDA9QUW0VVP7aRzhL4fYt5C3tnRUUL6ZGmg16IXnBCZx1NHXNrvlHVCG8+uGmXfcdQNB5Tc4bkPAPyWXtqtlH50QUtZXM8DY7p6qz9LofW2wrqvD4Eled1X7rzawxC4B7XANp9yKR4ytCr2CEg61RqV0QdHc0uU7zOVyxdY7UkOyWLMSrZWh7l2IGFDfJVLyeMPe09Gm2p9L6KDM9xDkNy7zMQm81gks6hi6qgy48Eui5Dp84zBxa1DwV9NHun0UEElbjHZn2uNcBkxi4bqCUiPd4kzwKonXu5NG+dFEPb61DR40XgB3Ay61ZXP3388GkFqLx6YgzJlIcVg== X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0477; 31:FhXzqTR7kanvKJsJIT9JWveMoGGhQHqhWzGBu1n5yttiJHjLgmvlRlhQbTCrGvdkkKxrcBNR6unmbDivCWHET71IYG4mHn7LtX/tbXlcdyg4rcy5Sqn3GoqxNYe5TWtd5MvRXc66sx6VApK9q+yXXsf25VKQZWcT8xx96ZdE491A/rbBBIhvX5rbP7BwXXJNIFnQwm3Ai3XeevgW44jj1oSMn6xmBBqfY7Tj76zow1tRTiZ36ZTC23zAYn9UVUQW; 20:GzrKOQikuES1hg5Gj8mrpCvatQwPLturMyMKwj3F8eMM757HmK5oZvEZpTwHwKam2SVHh0Er5yZ1OWIpY6h/mhwqqs+WBwyf9+pv8QJxN3G4BbTg5ZWQPvEB39SVBLs9Iqedb2/zuc6rLFzhCiIS3lxB3q/BwxIHhd3WauvkcSGc5aXETd+dwVOs0M0NY+nGOWPAhN86Vpa8bz3n7HJS8aoMwGs3i9RnL6LS+HkIMWGChVFyMy9+NL0W5g76WIDlwG4rWUlLw30zyNOSKOUvKT1FVFtjfxBFg1Q17PXc6PMm8r6Nw6ekHzF9S1patx8YZvrdYChg4rvy6ul54QgFdWHe88MwgrZKlXc8nKyROcPUWUkxrxckYPOipZnklmbCEPZCnaLSqOeMIC5iRl6xk1AsTS0Ws3ASUt2KzvD2WQZHPHVJWPdy6nGqPi/pxibC5mjaWbTjqgVjfiHELyFnfbJo1yVecCOAchaEpuStWuvwKq8ejcCl9vW9uLyJk9ZP X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6041248)(20161123560025)(20161123558025)(20161123555025)(20161123564025)(20161123562025)(6072148); SRVR:SN1PR12MB0477; BCL:0; PCL:0; RULEID:; SRVR:SN1PR12MB0477; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0477; 4:GXHbe1XvM5Cv4D6nubKvmtcvOfwCmvZExXq7EWr7kkfw7dJGKFwiasm3Pz8/P+cflqOlXrSICxYXpuoN/z7nW/1PZV+epcfxlGHhZ/qg5CT6GJxqIkM3bcfqKuElKm+Ure0NVoSj3juUCI7yUzmGRntoTgFGngIUAozSMKNM1sh6pP163G1J8x+B9Mm5oXDnCL0h8fKWI0SFbsbvu0ylTZLrCw6xrWdrtIDTOYCXDjKu5ohyxh5s0scXeygrXw9usfnWeWVEG/fdwTD5/An44oGQ3Tu6yQXKV8EotdAnFWQk6QI68Pj0DFImC8LqNKdQFXW/+gKqjdabXTjNMYcPVi8PGxVXsPspNWAfK0qXlxW9NgYdxzU2hCpe8SuGhbD1SUqr06x+QXWjWHpO/qoCo+AXpDv/RNUr31tBGwdlALxlWuDgRbqqHmLe330aKj2xPL7hrNGItGvz/U7xWi73yR0SrfPe/kC6MOcMQwtdjZffx6fchlROaraUyA6pSaZRG/JmM+C06lmpryQQsznwD6U5MNb/+rWo2ZKYnh+7oEb2w0B2OnpBvKFBgJcbtnc8Ebmu12mZcE6/kRPTJvMKIAZZz5QCPlu7TbscmB9vMvSQN8m57xXVkBO7cpUb5al6wY42/y71FhLxsHBcMGG6nTAUzqYi5Y6MzsqeirlTMpM= X-Forefront-PRVS: 02475B2A01 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6049001)(6009001)(39850400002)(39450400003)(39860400002)(39410400002)(6116002)(50986999)(6916009)(230700001)(2950100002)(6666003)(3846002)(76176999)(81166006)(4326008)(6486002)(2906002)(54356999)(5660300001)(83506001)(33716001)(77096006)(2351001)(53936002)(50466002)(305945005)(42186005)(9686003)(1076002)(23676002)(86362001)(189998001)(38730400002)(47776003)(103116003)(4001350100001)(7736002)(110136004)(25786008)(8676002)(33646002)(54906002)(66066001)(97746001)(2004002); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1PR12MB0477; H:[10.236.19.42]; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtTTjFQUjEyTUIwNDc3OzIzOm9IdFZ6NkZGSzBQMWxOOTRWR3NNV0k3dEEr?= =?utf-8?B?YXVvbnNaRWxuTTNzMU1UYmNDRmNyVzd1ak1vQzUrNFdLcnA1U0xEUHFKb2tX?= =?utf-8?B?alpoWkFqMDErWmJUMm9kN3ROVERlSk5YT21mNlNmWkRPc2JWeC9QZlFLMGxP?= =?utf-8?B?VmNtd0hLZTFJWVN6SzAyTy9XUGdpZXd5cXdHbjR2UHhiUENwQmJzLytwZXVj?= =?utf-8?B?L1dkdXNYUGV0MzRPY1dvTFFoNDl0K3pJNjd2ZnRXVjRUNFBHSml4TUFZMnQz?= =?utf-8?B?YlNTOW0wbHJxQ0s4ZVMveXdFcjkvc3FxKzlyS2hoZUphUGRtYnF2QkZpRkQr?= =?utf-8?B?WXpteUZzT1V6ZzNBVkV3MnZTeW5kRGYzem9lVUh4SStBczl5S0Nud2kyWCtF?= =?utf-8?B?TXRMdWRRVzRGSFhMZW4rNDVuSlhSNS80dC85SUpaWG9CNzhydU1VcDZqVE5U?= =?utf-8?B?RXNiRHQwdUNlVmJTbGZ1K0FZWGJLY0h3WVdrSk1qZGZHbDJwQWFqYkcwUkZO?= =?utf-8?B?eEU3eUxsQ0lQTmRsTS84aHlVN2pDVmtDMFdlTkZaVVpFMEtLNHF4N1lxMWFw?= =?utf-8?B?Z0ZYSmlSdndaeElYbFVTa2cwRTh4TGpVMENOL05LcXlvY25ZRHd6RTFBSnR6?= =?utf-8?B?b1p3ODJDSFVYTFlzV0FoT3Q4VldsYXJkVHNpR29iN0pReWQxNDZZUFJLSGpu?= =?utf-8?B?SkVUYllHOVEzK2NpZTAxSnJiTk1RTk5sZjI0ZDY2QldvaG5VMTRpL3hKblp2?= =?utf-8?B?c2EwbUZOUWNKMytkeE9KclBONXJ2N2IvSjM1K3J1SFp3a0l5eU1MZVRHS0Y3?= =?utf-8?B?ZmF5WjhxSk0vRXI2d0J0TW9rcTJ0aWlxWHFUdGpacFRoaUZYeXBueHcycjU3?= =?utf-8?B?Q1Q1Q0RyRjNZdE5WT3JIa2RKTTNVTzJpZ3JoNk1uNUw2VGhIaHI1RDVhc3Z2?= =?utf-8?B?NFBSQmllZ0Eyc2o3aW5SV25NRld3UUx3K3hCUElOcmtRL3dUeDBCRzNhemRn?= =?utf-8?B?ZTFEMEJoQmFGcFJTNDdtQS9QR04zM09TdnMvaFYzRnZ6MEpCM0pxYzBMKzhE?= =?utf-8?B?S0tCcHpaUTZVUWhoQ1cxdXdQcmNTdFFWMzh6ZmVrMnpSK3dyNDJQYzMrTE1Q?= =?utf-8?B?cXoycU50MXBmSUs0REN3Rm5mLzVrSDlacjJFRXZQcGt5SVM0aFhGbTExT1Fm?= =?utf-8?B?UCtZbm1hTGtvM09oM3R0VXREZEZDT0FTTk85Z25ma3VzeTg5ZEtFdXRjd240?= =?utf-8?B?Rk1kalp5VTRvM0paczZaSi9BY3RkcDFZUHkwQi9aRlBKazRmeCtvdnFXN3Mr?= =?utf-8?B?YjlPR011YmZFNm1PRzNLV2c4aDJScXNDTVo4eWpEYzN0WW5Ya0NtYWV2Nmpx?= =?utf-8?B?bzlqOGF6WmpnSVRGTVpJempLMEhNVVJYazMzaEpZdDRHWHc3ZnFuMHBQM21o?= =?utf-8?B?aURKa0IzMmFVWFNqOEtxTWh2dzFSUEFOUlRDWEI0ZnA0Sk92WUROVHdVbktN?= =?utf-8?B?Ri9WRjJveklyU3hCakN4RHlTbUVRUXlFNU8zQWgzdHo5NHNaanEyMGdNSjRR?= =?utf-8?B?T0lOZWNlYjVuK2ljSi9JZ01vS2hpcVE9PQ==?= X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0477; 6:w+luC+bIWraJ6fWJrrSEtNGF6h2FGW+hp9M31eJbtJcQJwwtgkDY9/5QzTKAVhJ/fC4fsPo8G5X44PWFsi7gQEsGFA7dEsrvJ3VZNckNLCO8HMutRD6AGKzKP6hVd895QeFPVzk7mhFOwpoxygW41Qpxzpoqj/bx4tWv6qihtMO8Cg2XMjLKr799ogAqurhfqRlt2R8/CwUA/VsuYJGL9NXGTlsLsnqGz68QsL4jPEp3rmU4meM1TEmz70/RnCwdqTgDpoZ1F1cvHudeuTWD2fsFTIHLaZnmYFQyDyL1tfZn+EVcVtCtM63foktPlsg60tvOaP08H+4nxM0rBwED3AoQ62dRjfIFQ4FluKXlQ+hdTWfHyIOhbnaVdIEUeJmSi5JWoB4lBa3qpGcSWm9G+5UXNweWw1jCl7P8dglY0/M=; 5:eWbCNgVQe3vm+FLBLVulbqMlaJ3BR34irUl/hEtgWIdvcwfBqOooBRRudacM061gAlSfoYS7rLrSBBpKwAVeGBg7+WFqwhmzi6/oj67s4OLKDfMVIomTZY/QWosiR6GFisiKDinTiOMb5Ejpo6QbFQ==; 24:oEsd4AbaJ5cGYqBxV36eUIOI0+Ytcys3LQkGwX/5ouZhG5nxwfy8G8oufS8XO5mB+0a8kWu4HLm9xGp17l2uPAKQZHOjzrFy30+Nj1pqP64= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0477; 7:gBuuORiK3Il0v3wI55uh3BbTR2QQd9eUWb1oOAhQgMSDFmN1/nKQ10CjpKQzfm12mH/UynUr7/53KXn1ekkNlxHyCpxAaRXI82VI8i3lyGEtk4werrPgafGVScxHaxX7ascNWPAhJGPE3PvQEtxhwgHXioBgWklndG0a+NIgKWrlTnnJDy5vajw1FS1nsEWieJ9dntcLnO6LqAhzeM+eQqpANJlm0FWN/OfU4BuCGJvqn3hM5fxdmpE9MWGLFG+N+vbkyWCRzq1YXvmSYCFdMtFHI9rXStXHxze7Zm3K9uP8EDONVT68OpnwJUKkr47TDbpswiewxzSLAX5z27t+uw==; 20:N1Z3R0Ms1yA2jSkQGh7YC7FUA2D5haLNwOuXo/oWTFs6R3/0dDOlSDPMMjPqUG9r4gey6boykiCfTBuDGw6vVhTBQ932FyR5+m1/ltFokXohydceRlF7/7JrZSrX4e7wfV35HtQFFuyNYqdsS8EBI2f6G0al8YUGDTmjLs83MFwGeIhJ3+3STJsB/LGDgSH/CJh2p68Nshkl0xyTe+s4jidBRLzPUUu92wlRmVInKCc0y9oU20B/0Q7QAKVXnvJV X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Mar 2017 18:21:00.6994 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0477 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Wire up support for Triple DES in ECB mode. Signed-off-by: Gary R Hook --- drivers/crypto/ccp/Makefile | 1 drivers/crypto/ccp/ccp-crypto-des3.c | 254 ++++++++++++++++++++++++++++++++++ drivers/crypto/ccp/ccp-crypto-main.c | 10 + drivers/crypto/ccp/ccp-crypto.h | 22 +++ drivers/crypto/ccp/ccp-dev-v3.c | 1 drivers/crypto/ccp/ccp-dev-v5.c | 54 +++++++ drivers/crypto/ccp/ccp-dev.h | 14 ++ drivers/crypto/ccp/ccp-ops.c | 198 +++++++++++++++++++++++++++ include/linux/ccp.h | 57 +++++++- 9 files changed, 608 insertions(+), 3 deletions(-) create mode 100644 drivers/crypto/ccp/ccp-crypto-des3.c diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index 346ceb8..d2044b7 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -12,4 +12,5 @@ ccp-crypto-objs := ccp-crypto-main.o \ ccp-crypto-aes.o \ ccp-crypto-aes-cmac.o \ ccp-crypto-aes-xts.o \ + ccp-crypto-des3.o \ ccp-crypto-sha.o diff --git a/drivers/crypto/ccp/ccp-crypto-des3.c b/drivers/crypto/ccp/ccp-crypto-des3.c new file mode 100644 index 0000000..5af7347 --- /dev/null +++ b/drivers/crypto/ccp/ccp-crypto-des3.c @@ -0,0 +1,254 @@ +/* + * AMD Cryptographic Coprocessor (CCP) DES3 crypto API support + * + * Copyright (C) 2016 Advanced Micro Devices, Inc. + * + * Author: Gary R Hook + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ccp-crypto.h" + +static int ccp_des3_complete(struct crypto_async_request *async_req, int ret) +{ + struct ablkcipher_request *req = ablkcipher_request_cast(async_req); + struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm); + struct ccp_des3_req_ctx *rctx = ablkcipher_request_ctx(req); + + if (ret) + return ret; + + if (ctx->u.des3.mode != CCP_DES3_MODE_ECB) + memcpy(req->info, rctx->iv, DES3_EDE_BLOCK_SIZE); + + return 0; +} + +static int ccp_des3_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int key_len) +{ + struct ccp_ctx *ctx = crypto_tfm_ctx(crypto_ablkcipher_tfm(tfm)); + struct ccp_crypto_ablkcipher_alg *alg = + ccp_crypto_ablkcipher_alg(crypto_ablkcipher_tfm(tfm)); + u32 *flags = &tfm->base.crt_flags; + + + /* From des_generic.c: + * + * RFC2451: + * If the first two or last two independent 64-bit keys are + * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the + * same as DES. Implementers MUST reject keys that exhibit this + * property. + */ + const u32 *K = (const u32 *)key; + + if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || + !((K[2] ^ K[4]) | (K[3] ^ K[5]))) && + (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { + *flags |= CRYPTO_TFM_RES_WEAK_KEY; + return -EINVAL; + } + + /* It's not clear that there is any support for a keysize of 112. + * If needed, the caller should make K1 == K3 + */ + ctx->u.des3.type = CCP_DES3_TYPE_168; + ctx->u.des3.mode = alg->mode; + ctx->u.des3.key_len = key_len; + + memcpy(ctx->u.des3.key, key, key_len); + sg_init_one(&ctx->u.des3.key_sg, ctx->u.des3.key, key_len); + + return 0; +} + +static int ccp_des3_crypt(struct ablkcipher_request *req, bool encrypt) +{ + struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm); + struct ccp_des3_req_ctx *rctx = ablkcipher_request_ctx(req); + struct scatterlist *iv_sg = NULL; + unsigned int iv_len = 0; + int ret; + + if (!ctx->u.des3.key_len) + return -EINVAL; + + if (((ctx->u.des3.mode == CCP_DES3_MODE_ECB) || + (ctx->u.des3.mode == CCP_DES3_MODE_CBC)) && + (req->nbytes & (DES3_EDE_BLOCK_SIZE - 1))) + return -EINVAL; + + if (ctx->u.des3.mode != CCP_DES3_MODE_ECB) { + if (!req->info) + return -EINVAL; + + memcpy(rctx->iv, req->info, DES3_EDE_BLOCK_SIZE); + iv_sg = &rctx->iv_sg; + iv_len = DES3_EDE_BLOCK_SIZE; + sg_init_one(iv_sg, rctx->iv, iv_len); + } + + memset(&rctx->cmd, 0, sizeof(rctx->cmd)); + INIT_LIST_HEAD(&rctx->cmd.entry); + rctx->cmd.engine = CCP_ENGINE_DES3; + rctx->cmd.u.des3.type = ctx->u.des3.type; + rctx->cmd.u.des3.mode = ctx->u.des3.mode; + rctx->cmd.u.des3.action = (encrypt) + ? CCP_DES3_ACTION_ENCRYPT + : CCP_DES3_ACTION_DECRYPT; + rctx->cmd.u.des3.key = &ctx->u.des3.key_sg; + rctx->cmd.u.des3.key_len = ctx->u.des3.key_len; + rctx->cmd.u.des3.iv = iv_sg; + rctx->cmd.u.des3.iv_len = iv_len; + rctx->cmd.u.des3.src = req->src; + rctx->cmd.u.des3.src_len = req->nbytes; + rctx->cmd.u.des3.dst = req->dst; + + ret = ccp_crypto_enqueue_request(&req->base, &rctx->cmd); + + return ret; +} + +static int ccp_des3_encrypt(struct ablkcipher_request *req) +{ + return ccp_des3_crypt(req, true); +} + +static int ccp_des3_decrypt(struct ablkcipher_request *req) +{ + return ccp_des3_crypt(req, false); +} + +static int ccp_des3_cra_init(struct crypto_tfm *tfm) +{ + struct ccp_ctx *ctx = crypto_tfm_ctx(tfm); + + ctx->complete = ccp_des3_complete; + ctx->u.des3.key_len = 0; + + tfm->crt_ablkcipher.reqsize = sizeof(struct ccp_des3_req_ctx); + + return 0; +} + +static void ccp_des3_cra_exit(struct crypto_tfm *tfm) +{ +} + +static struct crypto_alg ccp_des3_defaults = { + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, + .cra_blocksize = DES3_EDE_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct ccp_ctx), + .cra_priority = CCP_CRA_PRIORITY, + .cra_type = &crypto_ablkcipher_type, + .cra_init = ccp_des3_cra_init, + .cra_exit = ccp_des3_cra_exit, + .cra_module = THIS_MODULE, + .cra_ablkcipher = { + .setkey = ccp_des3_setkey, + .encrypt = ccp_des3_encrypt, + .decrypt = ccp_des3_decrypt, + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + }, +}; + +struct ccp_des3_def { + enum ccp_des3_mode mode; + unsigned int version; + const char *name; + const char *driver_name; + unsigned int blocksize; + unsigned int ivsize; + struct crypto_alg *alg_defaults; +}; + +static struct ccp_des3_def des3_algs[] = { + { + .mode = CCP_DES3_MODE_ECB, + .version = CCP_VERSION(5, 0), + .name = "ecb(des3_ede)", + .driver_name = "ecb-des3-ccp", + .blocksize = DES3_EDE_BLOCK_SIZE, + .ivsize = 0, + .alg_defaults = &ccp_des3_defaults, + }, + { + .mode = CCP_DES3_MODE_CBC, + .version = CCP_VERSION(5, 0), + .name = "cbc(des3_ede)", + .driver_name = "cbc-des3-ccp", + .blocksize = DES3_EDE_BLOCK_SIZE, + .ivsize = DES3_EDE_BLOCK_SIZE, + .alg_defaults = &ccp_des3_defaults, + }, +}; + +static int ccp_register_des3_alg(struct list_head *head, + const struct ccp_des3_def *def) +{ + struct ccp_crypto_ablkcipher_alg *ccp_alg; + struct crypto_alg *alg; + int ret; + + ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + if (!ccp_alg) + return -ENOMEM; + + INIT_LIST_HEAD(&ccp_alg->entry); + + ccp_alg->mode = def->mode; + + /* Copy the defaults and override as necessary */ + alg = &ccp_alg->alg; + *alg = *def->alg_defaults; + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + def->driver_name); + alg->cra_blocksize = def->blocksize; + alg->cra_ablkcipher.ivsize = def->ivsize; + + ret = crypto_register_alg(alg); + if (ret) { + pr_err("%s ablkcipher algorithm registration error (%d)\n", + alg->cra_name, ret); + kfree(ccp_alg); + return ret; + } + + list_add(&ccp_alg->entry, head); + + return 0; +} + +int ccp_register_des3_algs(struct list_head *head) +{ + int i, ret; + unsigned int ccpversion = ccp_version(); + + for (i = 0; i < ARRAY_SIZE(des3_algs); i++) { + if (des3_algs[i].version > ccpversion) + continue; + ret = ccp_register_des3_alg(head, &des3_algs[i]); + if (ret) + return ret; + } + + return 0; +} diff --git a/drivers/crypto/ccp/ccp-crypto-main.c b/drivers/crypto/ccp/ccp-crypto-main.c index e0380e5..3f1e36d 100644 --- a/drivers/crypto/ccp/ccp-crypto-main.c +++ b/drivers/crypto/ccp/ccp-crypto-main.c @@ -33,6 +33,10 @@ module_param(sha_disable, uint, 0444); MODULE_PARM_DESC(sha_disable, "Disable use of SHA - any non-zero value"); +static unsigned int des3_disable; +module_param(des3_disable, uint, 0444); +MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value"); + /* List heads for the supported algorithms */ static LIST_HEAD(hash_algs); static LIST_HEAD(cipher_algs); @@ -337,6 +341,12 @@ static int ccp_register_algs(void) return ret; } + if (!des3_disable) { + ret = ccp_register_des3_algs(&cipher_algs); + if (ret) + return ret; + } + if (!sha_disable) { ret = ccp_register_sha_algs(&hash_algs); if (ret) diff --git a/drivers/crypto/ccp/ccp-crypto.h b/drivers/crypto/ccp/ccp-crypto.h index 95cce27..8c8bd3f 100644 --- a/drivers/crypto/ccp/ccp-crypto.h +++ b/drivers/crypto/ccp/ccp-crypto.h @@ -23,6 +23,8 @@ #include #include +#define CCP_LOG_LEVEL KERN_INFO + #define CCP_CRA_PRIORITY 300 struct ccp_crypto_ablkcipher_alg { @@ -137,6 +139,24 @@ struct ccp_aes_cmac_exp_ctx { u8 buf[AES_BLOCK_SIZE]; }; +/***** 3DES related defines *****/ +struct ccp_des3_ctx { + enum ccp_engine engine; + enum ccp_des3_type type; + enum ccp_des3_mode mode; + + struct scatterlist key_sg; + unsigned int key_len; + u8 key[AES_MAX_KEY_SIZE]; +}; + +struct ccp_des3_req_ctx { + struct scatterlist iv_sg; + u8 iv[AES_BLOCK_SIZE]; + + struct ccp_cmd cmd; +}; + /* SHA-related defines * These values must be large enough to accommodate any variant */ @@ -201,6 +221,7 @@ struct ccp_ctx { union { struct ccp_aes_ctx aes; struct ccp_sha_ctx sha; + struct ccp_des3_ctx des3; } u; }; @@ -213,5 +234,6 @@ struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table, int ccp_register_aes_cmac_algs(struct list_head *head); int ccp_register_aes_xts_algs(struct list_head *head); int ccp_register_sha_algs(struct list_head *head); +int ccp_register_des3_algs(struct list_head *head); #endif diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 7bc0998..a3689a6 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c @@ -553,6 +553,7 @@ static irqreturn_t ccp_irq_handler(int irq, void *data) static const struct ccp_actions ccp3_actions = { .aes = ccp_perform_aes, .xts_aes = ccp_perform_xts_aes, + .des3 = NULL, .sha = ccp_perform_sha, .rsa = ccp_perform_rsa, .passthru = ccp_perform_passthru, diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index 41cc853..fc5666e 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c @@ -108,6 +108,12 @@ static void ccp_lsb_free(struct ccp_cmd_queue *cmd_q, unsigned int start, u16 type:2; } aes_xts; struct { + u16 size:7; + u16 encrypt:1; + u16 mode:5; + u16 type:2; + } des3; + struct { u16 rsvd1:10; u16 type:4; u16 rsvd2:1; @@ -139,6 +145,10 @@ static void ccp_lsb_free(struct ccp_cmd_queue *cmd_q, unsigned int start, #define CCP_AES_TYPE(p) ((p)->aes.type) #define CCP_XTS_SIZE(p) ((p)->aes_xts.size) #define CCP_XTS_ENCRYPT(p) ((p)->aes_xts.encrypt) +#define CCP_DES3_SIZE(p) ((p)->des3.size) +#define CCP_DES3_ENCRYPT(p) ((p)->des3.encrypt) +#define CCP_DES3_MODE(p) ((p)->des3.mode) +#define CCP_DES3_TYPE(p) ((p)->des3.type) #define CCP_SHA_TYPE(p) ((p)->sha.type) #define CCP_RSA_SIZE(p) ((p)->rsa.size) #define CCP_PT_BYTESWAP(p) ((p)->pt.byteswap) @@ -388,6 +398,47 @@ static int ccp5_perform_sha(struct ccp_op *op) return ccp5_do_cmd(&desc, op->cmd_q); } +static int ccp5_perform_des3(struct ccp_op *op) +{ + struct ccp5_desc desc; + union ccp_function function; + u32 key_addr = op->sb_key * LSB_ITEM_SIZE; + + /* Zero out all the fields of the command desc */ + memset(&desc, 0, sizeof(struct ccp5_desc)); + + CCP5_CMD_ENGINE(&desc) = CCP_ENGINE_DES3; + + CCP5_CMD_SOC(&desc) = op->soc; + CCP5_CMD_IOC(&desc) = 1; + CCP5_CMD_INIT(&desc) = op->init; + CCP5_CMD_EOM(&desc) = op->eom; + CCP5_CMD_PROT(&desc) = 0; + + function.raw = 0; + CCP_DES3_ENCRYPT(&function) = op->u.des3.action; + CCP_DES3_MODE(&function) = op->u.des3.mode; + CCP_DES3_TYPE(&function) = op->u.des3.type; + CCP5_CMD_FUNCTION(&desc) = cpu_to_le32(function.raw); + + CCP5_CMD_LEN(&desc) = cpu_to_le32(op->src.u.dma.length); + + CCP5_CMD_SRC_LO(&desc) = cpu_to_le32(ccp_addr_lo(&op->src.u.dma)); + CCP5_CMD_SRC_HI(&desc) = cpu_to_le32(ccp_addr_hi(&op->src.u.dma)); + CCP5_CMD_SRC_MEM(&desc) = cpu_to_le32(CCP_MEMTYPE_SYSTEM); + + CCP5_CMD_DST_LO(&desc) = cpu_to_le32(ccp_addr_lo(&op->dst.u.dma)); + CCP5_CMD_DST_HI(&desc) = cpu_to_le32(ccp_addr_hi(&op->dst.u.dma)); + CCP5_CMD_DST_MEM(&desc) = cpu_to_le32(CCP_MEMTYPE_SYSTEM); + + CCP5_CMD_KEY_LO(&desc) = cpu_to_le32(lower_32_bits(key_addr)); + CCP5_CMD_KEY_HI(&desc) = 0; + CCP5_CMD_KEY_MEM(&desc) = cpu_to_le32(CCP_MEMTYPE_SB); + CCP5_CMD_LSB_ID(&desc) = cpu_to_le32(op->sb_ctx); + + return ccp5_do_cmd(&desc, op->cmd_q); +} + static int ccp5_perform_rsa(struct ccp_op *op) { struct ccp5_desc desc; @@ -435,6 +486,7 @@ static int ccp5_perform_passthru(struct ccp_op *op) struct ccp_dma_info *saddr = &op->src.u.dma; struct ccp_dma_info *daddr = &op->dst.u.dma; + memset(&desc, 0, Q_DESC_SIZE); CCP5_CMD_ENGINE(&desc) = CCP_ENGINE_PASSTHRU; @@ -729,6 +781,7 @@ static int ccp5_init(struct ccp_device *ccp) dev_dbg(dev, "queue #%u available\n", i); } + if (ccp->cmd_q_count == 0) { dev_notice(dev, "no command queues available\n"); ret = -EIO; @@ -994,6 +1047,7 @@ static void ccp5other_config(struct ccp_device *ccp) .aes = ccp5_perform_aes, .xts_aes = ccp5_perform_xts_aes, .sha = ccp5_perform_sha, + .des3 = ccp5_perform_des3, .rsa = ccp5_perform_rsa, .passthru = ccp5_perform_passthru, .ecc = ccp5_perform_ecc, diff --git a/drivers/crypto/ccp/ccp-dev.h b/drivers/crypto/ccp/ccp-dev.h index 2b5c01f..754e9c2 100644 --- a/drivers/crypto/ccp/ccp-dev.h +++ b/drivers/crypto/ccp/ccp-dev.h @@ -190,6 +190,9 @@ #define CCP_XTS_AES_KEY_SB_COUNT 1 #define CCP_XTS_AES_CTX_SB_COUNT 1 +#define CCP_DES3_KEY_SB_COUNT 1 +#define CCP_DES3_CTX_SB_COUNT 1 + #define CCP_SHA_SB_COUNT 1 #define CCP_RSA_MAX_WIDTH 4096 @@ -475,6 +478,12 @@ struct ccp_xts_aes_op { enum ccp_xts_aes_unit_size unit_size; }; +struct ccp_des3_op { + enum ccp_des3_type type; + enum ccp_des3_mode mode; + enum ccp_des3_action action; +}; + struct ccp_sha_op { enum ccp_sha_type type; u64 msg_bits; @@ -512,6 +521,7 @@ struct ccp_op { union { struct ccp_aes_op aes; struct ccp_xts_aes_op xts; + struct ccp_des3_op des3; struct ccp_sha_op sha; struct ccp_rsa_op rsa; struct ccp_passthru_op passthru; @@ -620,13 +630,13 @@ struct ccp5_desc { struct ccp_actions { int (*aes)(struct ccp_op *); int (*xts_aes)(struct ccp_op *); + int (*des3)(struct ccp_op *); int (*sha)(struct ccp_op *); int (*rsa)(struct ccp_op *); int (*passthru)(struct ccp_op *); int (*ecc)(struct ccp_op *); u32 (*sballoc)(struct ccp_cmd_queue *, unsigned int); - void (*sbfree)(struct ccp_cmd_queue *, unsigned int, - unsigned int); + void (*sbfree)(struct ccp_cmd_queue *, unsigned int, unsigned int); unsigned int (*get_free_slots)(struct ccp_cmd_queue *); int (*init)(struct ccp_device *); void (*destroy)(struct ccp_device *); diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c index 0d82080..0de961a 100644 --- a/drivers/crypto/ccp/ccp-ops.c +++ b/drivers/crypto/ccp/ccp-ops.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "ccp-dev.h" @@ -939,6 +940,200 @@ static int ccp_run_xts_aes_cmd(struct ccp_cmd_queue *cmd_q, return ret; } +static int ccp_run_des3_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) +{ + struct ccp_des3_engine *des3 = &cmd->u.des3; + + struct ccp_dm_workarea key, ctx; + struct ccp_data src, dst; + struct ccp_op op; + unsigned int dm_offset; + unsigned int len_singlekey; + bool in_place = false; + int ret; + + /* Error checks */ + if (!cmd_q->ccp->vdata->perform->des3) + return -EINVAL; + + if (des3->key_len != DES3_EDE_KEY_SIZE) + return -EINVAL; + + if (((des3->mode == CCP_DES3_MODE_ECB) || + (des3->mode == CCP_DES3_MODE_CBC)) && + (des3->src_len & (DES3_EDE_BLOCK_SIZE - 1))) + return -EINVAL; + + if (!des3->key || !des3->src || !des3->dst) + return -EINVAL; + + if (des3->mode != CCP_DES3_MODE_ECB) { + if (des3->iv_len != DES3_EDE_BLOCK_SIZE) + return -EINVAL; + + if (!des3->iv) + return -EINVAL; + } + + ret = -EIO; + /* Zero out all the fields of the command desc */ + memset(&op, 0, sizeof(op)); + + /* Set up the Function field */ + op.cmd_q = cmd_q; + op.jobid = CCP_NEW_JOBID(cmd_q->ccp); + op.sb_key = cmd_q->sb_key; + + op.init = (des3->mode == CCP_DES3_MODE_ECB) ? 0 : 1; + op.u.des3.type = des3->type; + op.u.des3.mode = des3->mode; + op.u.des3.action = des3->action; + + /* + * All supported key sizes fit in a single (32-byte) KSB entry and + * (like AES) must be in little endian format. Use the 256-bit byte + * swap passthru option to convert from big endian to little endian. + */ + ret = ccp_init_dm_workarea(&key, cmd_q, + CCP_DES3_KEY_SB_COUNT * CCP_SB_BYTES, + DMA_TO_DEVICE); + if (ret) + return ret; + + /* + * The contents of the key triplet are in the reverse order of what + * is required by the engine. Copy the 3 pieces individually to put + * them where they belong. + */ + dm_offset = CCP_SB_BYTES - des3->key_len; /* Basic offset */ + + len_singlekey = des3->key_len / 3; + ccp_set_dm_area(&key, dm_offset + 2 * len_singlekey, + des3->key, 0, len_singlekey); + ccp_set_dm_area(&key, dm_offset + len_singlekey, + des3->key, len_singlekey, len_singlekey); + ccp_set_dm_area(&key, dm_offset, + des3->key, 2 * len_singlekey, len_singlekey); + + /* Copy the key to the SB */ + ret = ccp_copy_to_sb(cmd_q, &key, op.jobid, op.sb_key, + CCP_PASSTHRU_BYTESWAP_256BIT); + if (ret) { + cmd->engine_error = cmd_q->cmd_error; + goto e_key; + } + + /* + * The DES3 context fits in a single (32-byte) KSB entry and + * must be in little endian format. Use the 256-bit byte swap + * passthru option to convert from big endian to little endian. + */ + if (des3->mode != CCP_DES3_MODE_ECB) { + u32 load_mode; + + op.sb_ctx = cmd_q->sb_ctx; + + ret = ccp_init_dm_workarea(&ctx, cmd_q, + CCP_DES3_CTX_SB_COUNT * CCP_SB_BYTES, + DMA_BIDIRECTIONAL); + if (ret) + goto e_key; + + /* Load the context into the LSB */ + dm_offset = CCP_SB_BYTES - des3->iv_len; + ccp_set_dm_area(&ctx, dm_offset, des3->iv, 0, des3->iv_len); + + if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) + load_mode = CCP_PASSTHRU_BYTESWAP_NOOP; + else + load_mode = CCP_PASSTHRU_BYTESWAP_256BIT; + ret = ccp_copy_to_sb(cmd_q, &ctx, op.jobid, op.sb_ctx, + load_mode); + if (ret) { + cmd->engine_error = cmd_q->cmd_error; + goto e_ctx; + } + } + + /* + * Prepare the input and output data workareas. For in-place + * operations we need to set the dma direction to BIDIRECTIONAL + * and copy the src workarea to the dst workarea. + */ + if (sg_virt(des3->src) == sg_virt(des3->dst)) + in_place = true; + + ret = ccp_init_data(&src, cmd_q, des3->src, des3->src_len, + DES3_EDE_BLOCK_SIZE, + in_place ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE); + if (ret) + goto e_ctx; + + if (in_place) + dst = src; + else { + ret = ccp_init_data(&dst, cmd_q, des3->dst, des3->src_len, + DES3_EDE_BLOCK_SIZE, DMA_FROM_DEVICE); + if (ret) + goto e_src; + } + + /* Send data to the CCP DES3 engine */ + while (src.sg_wa.bytes_left) { + ccp_prepare_data(&src, &dst, &op, DES3_EDE_BLOCK_SIZE, true); + if (!src.sg_wa.bytes_left) { + op.eom = 1; + + /* Since we don't retrieve the context in ECB mode + * we have to wait for the operation to complete + * on the last piece of data + */ + op.soc = 0; + } + + ret = cmd_q->ccp->vdata->perform->des3(&op); + if (ret) { + cmd->engine_error = cmd_q->cmd_error; + goto e_dst; + } + + ccp_process_data(&src, &dst, &op); + } + + if (des3->mode != CCP_DES3_MODE_ECB) { + /* Retrieve the context and make BE */ + ret = ccp_copy_from_sb(cmd_q, &ctx, op.jobid, op.sb_ctx, + CCP_PASSTHRU_BYTESWAP_256BIT); + if (ret) { + cmd->engine_error = cmd_q->cmd_error; + goto e_dst; + } + + /* ...but we only need the last DES3_EDE_BLOCK_SIZE bytes */ + if (cmd_q->ccp->vdata->version == CCP_VERSION(3, 0)) + dm_offset = CCP_SB_BYTES - des3->iv_len; + else + dm_offset = 0; + ccp_get_dm_area(&ctx, dm_offset, des3->iv, 0, + DES3_EDE_BLOCK_SIZE); + } +e_dst: + if (!in_place) + ccp_free_data(&dst, cmd_q); + +e_src: + ccp_free_data(&src, cmd_q); + +e_ctx: + if (des3->mode != CCP_DES3_MODE_ECB) + ccp_dm_free(&ctx); + +e_key: + ccp_dm_free(&key); + + return ret; +} + static int ccp_run_sha_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) { struct ccp_sha_engine *sha = &cmd->u.sha; @@ -1903,6 +2098,9 @@ int ccp_run_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) case CCP_ENGINE_XTS_AES_128: ret = ccp_run_xts_aes_cmd(cmd_q, cmd); break; + case CCP_ENGINE_DES3: + ret = ccp_run_des3_cmd(cmd_q, cmd); + break; case CCP_ENGINE_SHA: ret = ccp_run_sha_cmd(cmd_q, cmd); break; diff --git a/include/linux/ccp.h b/include/linux/ccp.h index 90a1fbe..fa02617 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h @@ -292,6 +292,60 @@ struct ccp_sha_engine { * final sha cmd */ }; +/***** 3DES engine *****/ +enum ccp_des3_mode { + CCP_DES3_MODE_ECB = 0, + CCP_DES3_MODE_CBC, + CCP_DES3_MODE_CFB, + CCP_DES3_MODE__LAST, +}; + +enum ccp_des3_type { + CCP_DES3_TYPE_168 = 1, + CCP_DES3_TYPE__LAST, + }; + +enum ccp_des3_action { + CCP_DES3_ACTION_DECRYPT = 0, + CCP_DES3_ACTION_ENCRYPT, + CCP_DES3_ACTION__LAST, +}; + +/** + * struct ccp_des3_engine - CCP SHA operation + * @type: Type of 3DES operation + * @mode: cipher mode + * @action: 3DES operation (decrypt/encrypt) + * @key: key to be used for this 3DES operation + * @key_len: length of key (in bytes) + * @iv: IV to be used for this AES operation + * @iv_len: length in bytes of iv + * @src: input data to be used for this operation + * @src_len: length of input data used for this operation (in bytes) + * @dst: output data produced by this operation + * + * Variables required to be set when calling ccp_enqueue_cmd(): + * - type, mode, action, key, key_len, src, dst, src_len + * - iv, iv_len for any mode other than ECB + * + * The iv variable is used as both input and output. On completion of the + * 3DES operation the new IV overwrites the old IV. + */ +struct ccp_des3_engine { + enum ccp_des3_type type; + enum ccp_des3_mode mode; + enum ccp_des3_action action; + + struct scatterlist *key; + u32 key_len; /* In bytes */ + + struct scatterlist *iv; + u32 iv_len; /* In bytes */ + + struct scatterlist *src, *dst; + u64 src_len; /* In bytes */ +}; + /***** RSA engine *****/ /** * struct ccp_rsa_engine - CCP RSA operation @@ -541,7 +595,7 @@ struct ccp_ecc_engine { enum ccp_engine { CCP_ENGINE_AES = 0, CCP_ENGINE_XTS_AES_128, - CCP_ENGINE_RSVD1, + CCP_ENGINE_DES3, CCP_ENGINE_SHA, CCP_ENGINE_RSA, CCP_ENGINE_PASSTHRU, @@ -589,6 +643,7 @@ struct ccp_cmd { union { struct ccp_aes_engine aes; struct ccp_xts_aes_engine xts; + struct ccp_des3_engine des3; struct ccp_sha_engine sha; struct ccp_rsa_engine rsa; struct ccp_passthru_engine passthru;