From patchwork Thu Mar 2 21:27:03 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: 9601569 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 06247600CB for ; Thu, 2 Mar 2017 21:28:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E7D52285F7 for ; Thu, 2 Mar 2017 21:28:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCAA3285F8; Thu, 2 Mar 2017 21:28:07 +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 675D2285F9 for ; Thu, 2 Mar 2017 21:28:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751373AbdCBV14 (ORCPT ); Thu, 2 Mar 2017 16:27:56 -0500 Received: from mail-bl2nam02on0040.outbound.protection.outlook.com ([104.47.38.40]:16092 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751128AbdCBV1v (ORCPT ); Thu, 2 Mar 2017 16:27:51 -0500 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=8ig2p7LSemvAFwEuO+41nIo9JdZV8A/2nGsnJv/UoIQ=; b=iICHWYojdCmCJ8xpnQDXdSJ0Bk4AEDpIFgeERkaJgPCIQN1rej2KhNuFgur7AloisoIyyDUUi4Lb19u5qtTvK3wgdaW2blmK7HArJ8eoqxxsWVv/CNqW8mOzLTZSPCER3EZNe5mcPFn0iKag2+HmKHoTKDbLVS+TIgnzK0KWfOs= 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 DM5PR12MB1402.namprd12.prod.outlook.com (10.168.238.141) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.933.12; Thu, 2 Mar 2017 21:27:10 +0000 Subject: [PATCH V2 3/3] crypto: ccp - Enable 3DES function on v5 CCPs From: Gary R Hook To: CC: , , , Date: Thu, 2 Mar 2017 15:27:03 -0600 Message-ID: <20170302212703.30959.57908.stgit@taos> In-Reply-To: <20170302212331.30959.44149.stgit@taos> References: <20170302212331.30959.44149.stgit@taos> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SN1PR16CA0007.namprd16.prod.outlook.com (10.169.34.17) To DM5PR12MB1402.namprd12.prod.outlook.com (10.168.238.141) X-MS-Office365-Filtering-Correlation-Id: 7753089f-1c1e-4ee5-bb0c-08d461b2e31a X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:DM5PR12MB1402; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1402; 3:oQWMwsaZhsUppjVybVX+G5v/P98b6RM3RzJEUiV1H6qMRrLEqcvC26p+/wxAAfvdRF07hx6DZTw/mWGm8eIjToO8061sOuDYs+4qAmtEzMkXRlk7c4y2mG6YIUfCphHeDcL07+lcB1+eX3otVyb9BACMqat4+rZlRNiR1ywbqv5bAg25aZtHQzSmEkSHBbIJljuKSlXQJ+uG1fqhD9qB0x5q5hyv7meOH6OIR+jPjHbJ81Rz/Z1HE+omttYLyVjWqpILAmbt0ExyN6PKqTyypzxGaSn+CnJMO/qx7PD5gdY=; 25:J0m8nLdO1KZn5zu7uKdXtNoRlj2xURcsDob60LC1jiUZgfMS+i3kPvPbgAUoH07sgRiYMhnEkWzluLOw8pZCvbctqDNMsEdIJoYa47LfM+EhXYt6gztM0VK2wsNJI9rTlkCMPZ86oNkgqubT/3mxIZkkEqaLtw85BsWR/qRVryLWH5996BYWHbyZ4nH+haVukwX1Vn8u6FoJNZAGyGIe8D/zmjVkms9/Um4GNqHCJm9JtUIlbmKhPyeHR+kHNNikXstlLFilZ5XbQpgXAkY2Ws/NfnbFA2jK7r4bNR3SHiDi6uwexFTp8c4+mNqLHj2HQlBR5/mjGD7jOM0J9Fz8/X9yl/d0eg6lVp7O60VdYrSM+XnmFmIUonsCRbHpwOcVWVxTNxDZJX0MhPsSEUx9/GBxxC6cIM3hsBV2hAdXgnL0EHwLXnQvkmL3T2jQrKitSV/AioKAR1L5djdFGxBD6Q== X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1402; 31:HgHbgGU3WiIZqzlU92DxtUpLcuquw9wXePbaPq88vq8he593tYaNP/6IcyCHi70UBGQ7O2XvmpGaDlp97u1tDbf5ozF4zvpjil5G1rG65G3KOXGz4ARGph8id2MFmhZzR27/l2lRMX7+w1IiQtqU59anYNEm4PimkDwuji0HaTnRcNz0f9tahtuSVUdJQiEU3uIemvDCKVo0qGUdn01r37NTT1umEFZIOE/Uey0jCvcJHxFU0dqod1otqZzndVLh; 20:pb+wTP6BwcmHXEypBMpUoeJYLV1jTBd6W7PnACLnPsDX/R7QTopQf8Da/vXy1NV0geqpqwcfvG7fJY5s33LtDr7ufSFoJmSf2JcinvnHWW9J879HpssQDQ36uIa+AWuWaRn92HL0lZkd3o4PXYOEn/SgeGztJJ2PUSucQULvLSnTITpO6kHsGRKe3Jwb62oGdac9qFBgJRPwT8bkJXr1rJl3oy+RCNt0hR6+EPrmG8JTwCk99EaRirQko86/HApK4IjVrybThZCMJueS0Q3OBDr353DpQCbmIxBGIbHRnQGomtJdy/ywBoKlPJxnz0TXD44x39fS87sl5Pkfdy7wQJoF/TN1N3IqXcB+dhTahMbk4M4+olCTrcvdQVcW+RSAmAPYHhkbCG/TnrDv2pEdEKfFzDLeKugMx+gYKq5mc34H2ZmtgtnJCaH2W0xeJASKzbqzN+jvBQYld0a4ilOBQ2TMnvkCd9cunzKH+Z6Zm5NEWIxahHH1Nts3EYMesq2W 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)(8121501046)(5005006)(3002001)(10201501046)(6055026)(6041248)(20161123562025)(20161123558025)(20161123564025)(20161123560025)(20161123555025)(6072148); SRVR:DM5PR12MB1402; BCL:0; PCL:0; RULEID:; SRVR:DM5PR12MB1402; X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1402; 4:GrysU/lBI0/Hl1Z7X7cN3afCEej7wYVk6sTaDLxQJjac/4uIwo67s/uV8yZ29BdsuVWHdixA3PKgNP8O9rpBch6RjXXuT+ZqkqfEJLOrAiz1WoEH1IRbxIaWxiH9DNb8r/3Q2+ZjKuF6sFfO9oAAJh/B/CcS9ipTwsWvSFAe5jxA3X+CihATCIAG0uvBiL3hZNXrvMDiGiqF9fB1knxKJRKGrXbZO5nDb/1WvFWaGdaRZEqtM3sx1J8JKwYV/BffdlXDK9ucCqIgbbcou1gk9FgfkyBOkLJs81UnjOMmwUB0wYhFbi2/hl/PCqRKBt8MEf1Hyz8tTX6nI+MhLHtvM/l/iT8I3miCSvPIaecCk4hfYcWd24mXqkFwwLjWKXAH5pK8r1vMBop7jIRfTyhDDQeeqBz7B3Eyl2bkaKQFdKYCZMi84s3bwsP1XqBbVxzsO19lRRTXTj1zvS4tzl6N8/v90TGExkH2RRkH+oMFzJwGJANfM1OsJWDzGhNzuVfC43YXCKnuNudDjSXsc/jdIxhH0zNETCEGDMB/DrzTrVmtPyFwzx/LVDau344mqGZmJYGEzq2iUyLgWGua7TRBEd+335dPVN255uLSKulA5zKbHppY/Sh9PqnRvsCl816UabdUvpW2jCxqnIUkpLqvmc7tBzaRvMCL+tNiHtlkbpI= X-Forefront-PRVS: 023495660C X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6049001)(6009001)(7916002)(39850400002)(39410400002)(39840400002)(39860400002)(39450400003)(53936002)(110136004)(33716001)(7736002)(77096006)(6486002)(25786008)(90366009)(38730400002)(189998001)(305945005)(2950100002)(50986999)(6916009)(4326008)(76176999)(54356999)(33646002)(6666003)(5660300001)(9686003)(83506001)(54906002)(97746001)(6116002)(3846002)(230700001)(86362001)(50466002)(2906002)(4001350100001)(23676002)(42186005)(103116003)(47776003)(2351001)(1076002)(8676002)(81166006)(92566002)(66066001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR12MB1402; H:[10.236.19.42]; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtETTVQUjEyTUIxNDAyOzIzOlFJWGVTME5hV0pwa1JRNE53OHRsZWVUU1NU?= =?utf-8?B?TjdocEIzQkt5cWp6OTFIY0QrL1N1ZFpNNWtpWHhTQXFEK05YRkdLWEUrUG5n?= =?utf-8?B?RmJ0OElGMDZuM1dvRnRhWXBVUDBuNzhrekMwcVNzNlZIMzVWalA1VVVLVXNk?= =?utf-8?B?Qm95U2w5MWlNSGN2VzA2SnVoaWV0K05kQXJ1Vkp3emJlZkFlcm54ZkpwUi9K?= =?utf-8?B?WUJIOWRmdGk1cUdqaXo3b1o1SXdKM213NnFLNEFDRXRmaWtla084ZWpPZE9Y?= =?utf-8?B?NlJwdnREWHR0aGE0Y2pXRjYydnV0ZndrcjZtcVJFNVlNT3ZWcHRVdW1JcHJU?= =?utf-8?B?TEd1RVlwUlB5MXhyY2dLNFdSS2pST0lVaTc1Y1BvdXZKTGFORkp4QnJURWhT?= =?utf-8?B?akpDNlVSYjRjczJZQWlIbFRKSGVhTk5sWkpGV1hDNzBxS1V4Vi9ZcVZkRUNI?= =?utf-8?B?UVdOcjk0azZvcmdCdjZPVFhYeEoxNXYwR2xZdDIzNXdrajYzL0lRRHBWL0Rp?= =?utf-8?B?RDBHVmM3OHlTZ01JOFFnMGd0ZXRxaXNaWk5OSXFESTIzRVNLRlZiUVlpbEoy?= =?utf-8?B?c1MvNTUvT3dxQlprdFRIL1F0eEJQTzRGNzVMM0dKdDc5Tm82bHoxdSs4R3Fn?= =?utf-8?B?bzhrUjUzQXNqNTNZMUs0L1V6RTF4VktEbUoyblRmZ1VaUzZtVXJLRHVvZTI0?= =?utf-8?B?U3N1WUhEMmEzYkdDT1NDMFdtN3JCQ2RKVVhmMXN5NytLV3FOQWZIYWNNaHI3?= =?utf-8?B?LzdtekI2TDZLSmlvMEY4T3FxcVB2NHljOHhTRVNNdTdBNXRTZ2s4QTZzanJY?= =?utf-8?B?ME1KeHhVbUV5VVpXY2tqWmI0bzVVQzNQOXM5UmhHRXBQdExvUlZ4ZTh5Z0tD?= =?utf-8?B?UXNCWjZXdzRmN1RGdzJ3TDk2c1MyVjZoaU5iVkU3K0JKclZhaTg5M3pkZnZu?= =?utf-8?B?NHJHWmh3cXY2UGsvUE1PMDc4eC9KSHBvK1Y2YzFQR0NaOUZFaU1NMmtiVmRo?= =?utf-8?B?V1RnVk9KcVAzYWR6VEhYN1lpVFIrbnpkOGVVZEtzKzVKZzFmVTNPRkVoUTNv?= =?utf-8?B?RjR1RkhrMituQzNkUEwrdE9WRHg5Q1JQQllvNDdsL3hML2xYZGxBTWUrV1Mv?= =?utf-8?B?Q1BGUWRtOWlyNXA2MXJ0aFNhVExPSGk0clF1SkxEb1BMdWdBbjFPVWI1RWhw?= =?utf-8?B?Q2srb3MyMFJnZzVHTnBNeW14UUpDQ1B0L1Zsa2hrNHo1K3p1ckhiYjg4ZFpx?= =?utf-8?B?ZzVkTFRCNWZPOTU4dkZkYkxWUTNvYWVCVWtNNWZRRzJ5Yjg2MGZvQ1VBNUJK?= =?utf-8?B?RVB4UE8vb2xub1lGQzljNGY0VEwzeGsxS2lKY0RhOXQ3SlRoWXhvOGxORWty?= =?utf-8?B?R2svdmhsTi9kUTVoTU5RSnlTNktPejBKckFDMnNFNTd6WlI5S3hFVTNpanA4?= =?utf-8?B?anVhZ09FdmtRNVRZL1hPVWRXaXNYRUFXSEJGbFkyaGU5MXo1V1lYRG10cXF3?= =?utf-8?B?dHhZc1Y2WFdGNlliNXM5RnFraGtXKzJLVUd2M1FRRWdTcVdFZnBjd3ZyRjho?= =?utf-8?B?eXNJZHJTWW01R3dUcmU4OXEzZmJyZXdpRkYyNWc2R2lwQVozdFo3QVdSRnFF?= =?utf-8?B?RVhNYUVXb05MUVNoVzBHNXhleXV0SStpNEU4THhnRi9zTE5pbC9JSkRRPT0=?= X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1402; 6:1YDFf1F6ninMLYFa5VSf+Ya2o7PbDU7IJGf0zB8LXFuOgMFAQeEzbJmfYt5iWIW0Ro2z4TvFk+hzX03CJq8QchsDfmK7/2qfEDz9OlicTIzwqLaVeNkTwqp+Mo8pP8ATfvL1htjOY+oR4BhYWFMerhKWQgyNicg74Okm3AFfh4XhzsMFJQ4/0DafsG8UEY60t7VV1xXzB19i+WKCATOubWg0wZMMh4H3jv0d/soPI/EOqmgPtgUJl0hCg74scG5eBLI68FJBumfgtZ/d29tT1JPpZatuEkpa2MOHNHyb0HGt7YnKhybJgD6u3OOjJdvtekpHDjriHLZ0KvuPZJQ0BW+vMcg+vkYZwJKlKVMlvKsldadiHzTkY9WaYfNBIcEzqg0xkBOc0vhJxuDjrYGBCM+2E+Igkz2/wRNTQ3Kjg4w=; 5:mZkWTfoBQOaLvprh/j0CXstRoy5ha8kY2wPswsxsrLmgTh9t7yCaodsQplVG8euFiJHt2lzYeyGKk0tyWpngVmuQR+VWu7Zrged35Ci6rlrtLWwB938v+sPA0NosH2noO90A0a6Q5EXTeAYnnQZ03Q==; 24:2UMMT9T1DOE2HZ5e4H0psR/ey+7gkbsQ32YWG08b+BrfaueaGMW8AdO47kYsRKyepBYb9d/ALN8jEm5DumIk9J7r63RwXwkVYq0mNIPlKJI= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM5PR12MB1402; 7:qvlpv4fcRSaF+FiHqqyAw0Y93jrpNVJUiNkBde4OSxvK7OJfoc3PxRqhvIRMmRlu4e8ddf4W0bT9Gr4mSrdUTGzXp42DPxG8eblvlmrok9JPYq2VX4kbHKfCZQ5MgC3MMo4CgExnvKhX45aR9c+nVZ5Q4Lz23NDkWdvLhaW8vpd+ZaaA995oU+M0RKSbxA8Mb7F1R8dTE71355n788xlgXIlv6Bm7xmyMhcl1agQzZlJnJsreeRY+ORPQFEKUXZj5woQGu1LNvxuOUYpe99hgBtumHxkYDaFYmp7g/OzZq19WwNDUpR24Rb0XyAocSylUEmYnhDdNQy0oz+J9yyZZQ==; 20:ZwMiv5QNffyVTwDaE1rSA9F4qI1ANrPEEuxl84vIza0Q0G3zNEhTNSaSAk1iqMoIkFZubLvsA3WdNTk2VmITDLsZD1gaRXcYUvuK3X9mRXUrwaWCzGMzykQPnaUPtb1qGYE4lNfelpNPzQDraKlNgIsPPbiqX0pWtpFflCXELqPkySDf1nyJdMFfjokeHCr4l5DkdmHskBL70+KSTTTngM0tTVMOPdFzainDVSSLyjFJDLQ4cNiQMXreknYz2AXd X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Mar 2017 21:27:10.5132 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1402 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 9ca1722..60919a3 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -13,4 +13,5 @@ ccp-crypto-objs := ccp-crypto-main.o \ ccp-crypto-aes-cmac.o \ ccp-crypto-aes-xts.o \ ccp-crypto-aes-galois.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 a33b8d6..8dccbdd 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); @@ -342,6 +346,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 34da62d..dd5bf15 100644 --- a/drivers/crypto/ccp/ccp-crypto.h +++ b/drivers/crypto/ccp/ccp-crypto.h @@ -25,6 +25,8 @@ #include #include +#define CCP_LOG_LEVEL KERN_INFO + #define CCP_CRA_PRIORITY 300 struct ccp_crypto_ablkcipher_alg { @@ -150,6 +152,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 */ @@ -214,6 +234,7 @@ struct ccp_ctx { union { struct ccp_aes_ctx aes; struct ccp_sha_ctx sha; + struct ccp_des3_ctx des3; } u; }; @@ -227,5 +248,6 @@ struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table, int ccp_register_aes_xts_algs(struct list_head *head); int ccp_register_aes_aeads(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 d44a738..72a1777 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) @@ -391,6 +401,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; @@ -438,6 +489,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; @@ -732,6 +784,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; @@ -997,6 +1050,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 8f313e6..384a545 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 @@ -474,6 +477,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; @@ -511,6 +520,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; @@ -619,13 +629,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 83c8cf7..7ae7f14 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" @@ -1183,6 +1184,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; @@ -2147,6 +2342,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 6f78295..dbe8aa0 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h @@ -301,6 +301,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 @@ -550,7 +604,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, @@ -598,6 +652,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;