From patchwork Fri Nov 4 16:05:01 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gary R Hook X-Patchwork-Id: 9412779 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 8B3C66022E for ; Fri, 4 Nov 2016 16:05:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7A96D2B189 for ; Fri, 4 Nov 2016 16:05:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F61F2B1BC; Fri, 4 Nov 2016 16:05:19 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 E27432B189 for ; Fri, 4 Nov 2016 16:05:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935059AbcKDQFR (ORCPT ); Fri, 4 Nov 2016 12:05:17 -0400 Received: from mail-by2nam01on0072.outbound.protection.outlook.com ([104.47.34.72]:21482 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932299AbcKDQFP (ORCPT ); Fri, 4 Nov 2016 12:05:15 -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=YdxIRbW/7xk3tA/tL9Kc5+MHhZOFIOVYEk+1w6JRNBQ=; b=i4gATwoxpGh9iLzRm6EFyAT0Ai+xgKR12GDFmF8+7aFLjOfRfPStNWb5cYcTYRmUYX23rTys0PkOU7DhXA3v9ApBhos418tlcJW8nlx22JoGoNizrnGUE3I9rIgSIoxQ/KeBOuSyT5pOGBOdgRGwxf4a6tT/jqAA8H9sesNDnhg= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Gary.Hook@amd.com; Received: from [10.236.19.42] (165.204.77.1) by BN6PR12MB1394.namprd12.prod.outlook.com (10.168.228.140) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.693.12; Fri, 4 Nov 2016 16:05:12 +0000 Subject: [PATCH V2 9/9] crypto: ccp - Enable 3DES function on v5 CCPs From: Gary R Hook To: CC: , , Date: Fri, 4 Nov 2016 11:05:01 -0500 Message-ID: <20161104160500.18155.89154.stgit@taos> In-Reply-To: <20161104160140.18155.75618.stgit@taos> References: <20161104160140.18155.75618.stgit@taos> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: DM5PR18CA0041.namprd18.prod.outlook.com (10.173.208.27) To BN6PR12MB1394.namprd12.prod.outlook.com (10.168.228.140) X-MS-Office365-Filtering-Correlation-Id: e96dc118-b3d9-476d-bf8c-08d404cc5bb3 X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1394; 2:pH957x/2FAe+k2B70BEHShDYUfI1E2RdKiim99Avk1AjMjpZKRdGpsR1hPJj3fpEbAeOYK7Di1XvyS1dnpONPJ55XjQdcHSW6Yd+MmA8uVyMeddlRv+mQDyO3YBM1X/GaSTF7P3J8+u/8YzAQJZ8uOw9rDiXWb4mQNJhbK3SYyhomK4D82Shuub0wTbzPSR1g3I6I/ewlZaguHKfVf85cQ==; 3:6R7EX1zYsvVkBktISU4R0Qm/M4Fi+oEa55z+VMEbKK5SdUk1gujmMePtroSYDWtuLDjYX8Y9JqAU0hZNQuQOre8mjCi4hsEB/gg3GW1qa7dYL0z+5LPZAOZsw0Ajuc1t7DS1LpTE53jnZHoHFLJqwQ==; 25:CI2gBVMW26sabpIN0aecIsIgpJ0VXDoQFikNJtDcyP3oe5cx1G5/hR5gB/Q9+qD8OpA09zcxddOdfXP7QsZVjfXwL7AscQBk+BoTllU/0aqV3FDxqWkNxr/5b9sXjvR5su3YEoYJwkJ2jpnR2ER0MM66zt7Vk+emq6yyBG5LZHaf6Dq1ey9V4z5pMUW8U4ZIqC01/3YogPdwqs8+DRBrf60ODgPSnoLC5ujQRWQVtkHRSW86hIZdIWb5DCsGzSYdP+JKDVBCEcDsX/GwrJFumHJEo7C7gSiNqNSGMlZTvqMVDHdzno1U+iur/zlgDY3ZlAWLTCmmqydTnjlxSz746OULwxj5YikpBILbOX1O+4+OtHmzSZGKBVdGHXdipIePv9z142En84FjcFzGujLUw/NCg00CzaG9sofr/RMGV/ydWJJl34k/nTzLXm41aVFH X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN6PR12MB1394; X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1394; 31:SdL7be+nmUtIn4MqmBnaBD3PPuSt0A6DWc+XcCxMzo6eX/zPcLP18k89gChlZuhtmZ3Cf1Fx/tURDEwpc1PFJKoKvjUuRdKaIYRSMtNavOrzzbqZfy372OMuifGklMQWudd0eGuTkMpCQ5GK/NkvddJZT+h0Q6A+yCIcB/kw/n7okdKQaljTN2v++t4SrbRtQF2dC87USJHdtn40AxDc78EyhZQ8ivmuR5AJoto42x04JJFvbEcLN4St6n/aon5WGLRxiWccxy7IAZyKyvuboA==; 20:sKeNibCNeH9PEDeNj3b8lbz6kJ98F/tZ8NnoDcFtaccm4r6lxm1VH4QwIQiVPPqSWYkBMdnZPIFYznYlo46coHRCl4Y5CkR7EVaiBVGIgrud52Vn3J4Yesz07u5wBRD8XJM8JijReO2pMxGNeeuunYDm5a7rOzMX5G7F/JTgHDMNFE3W2aufipLv72KpJ07QIHMQ5v3aDQTGJNlrJk4yfdnld6OsvkyKbq8tS0fvRaGM+XDP9AyKDxmkfwPpjKYpaH4pP4hI6Vej1GHszHC7ydLCeIBVajZCkF7K4ZoBBArCqZeYtcN4nNRzX+vjR0mO5IeAZY0YswA1ed16Aj8jqOhX6vSeizkcIffe/yfAGH4PrBo9S9oLxrC2B1aX3D0+Hzon2A2F1BWeEuc9CWhJtAhxS6w/QU+4pQLoDeh3oSgNIgKd37yTOFVZxK2Q1jDzuZDqMfX9J57kMwGRNXDYSolSL9iQasb2qeEJurOgoKMib7bjFc1RhB7n2XR8udYA X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026); SRVR:BN6PR12MB1394; BCL:0; PCL:0; RULEID:; SRVR:BN6PR12MB1394; X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1394; 4:iF+1P2AhGQhH2xoCRg2Jr/2m8r7FgUYOIy0U1tw9fb8KALu3El65PuJddREFQg8TzygF319rrbORedBEdCMpkbJ6G4tkA8bKKcMMGfqaAB5+8bPrY55tIfUvGQg38VaZPj4FE3xRvk/J8lKjZo6C6022Y/l7WTFzFMyTGPoyXkLlWyWyAuwxDv89sLwAekSbaNBX/JpET5bJSuwiGRJKshpNQjwBPcFL+KO5+Mtq1MYboP6ZUP+i6L3NtQEIqo+q1+xBbaaOG1zWsvlI0OaMGUj9c7JULz4nmlFpD3+GwzD5LSRLYCK1Y9OWdQXUssNhmYmQ77IxuJ5D3A/iw7HzyliQi1PhbmeoXj7hIiNvuvmRCF+WpR7Swi/NEW4k44mxt28DsDm7Lw5uz+V46UY0JHUxk338WMfytbQ2ZBBik0wflUN9MgnWGkUccskDN7W64PY1oFemNrVfXaDKEn1STA== X-Forefront-PRVS: 01165471DB X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(979002)(6049001)(6009001)(7916002)(189002)(199003)(86362001)(77096005)(47776003)(66066001)(50466002)(19580405001)(19580395003)(9686002)(4326007)(189998001)(83506001)(8676002)(6666003)(92566002)(2906002)(103116003)(81166006)(81156014)(6916009)(2950100002)(68736007)(42186005)(3846002)(586003)(54356999)(33646002)(105586002)(4001350100001)(97746001)(305945005)(230700001)(33716001)(50986999)(23676002)(7736002)(110136003)(97736004)(7846002)(2351001)(106356001)(229853001)(101416001)(6116002)(5660300001)(76176999)(1076002)(2004002)(969003)(989001)(999001)(1009001)(1019001); DIR:OUT; SFP:1101; SCL:1; SRVR:BN6PR12MB1394; H:[10.236.19.42]; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtCTjZQUjEyTUIxMzk0OzIzOklqaWJIdHUyTzg3Vnl3KzhPWGFmY0ZBZFFD?= =?utf-8?B?NkNSQTdHbHVpRmhNVXJRdGpGekordmNubUdXRkVjd3NWZHpuNEN2RDlsVnFQ?= =?utf-8?B?bzFReXhNNkk5MjVyV2JpL2MrUUdNZjlIY1lta3NHODlrK0tCQ1NQU3hZcEdE?= =?utf-8?B?cjMxVXAxQ3ZRaEpKcEorT0xjU0YwVXVGdWNZNlY0RnJISndQb3gzcTlGTFZq?= =?utf-8?B?ZTZWVy9vVkRuays3N1ZXcUpzdTQ4MGorczBqdFArQWFMRklGQXlEaDVyNy9K?= =?utf-8?B?dXh3NEY3cksrS1hyck5ZM3lacU82dyt2RlhVUENHU0lzZkk3dFZ4SG5QTDI4?= =?utf-8?B?UjVjSStCdW9pMmVDS2RVeUxBY1phVWZqVzIzbHlwRFQwOTVrWTRDZkRiNDMz?= =?utf-8?B?bXpLWklQZVFaQmFTSW1mTVFRa3JtRXh1SXFBdElyWnA3c2RQbnJVbDI5UDhT?= =?utf-8?B?NEF4N3c0NjQyckNxdUZMbGZYcndxcmprTjRJL1dKN0ltZ1UzNlF3Sm8zcG12?= =?utf-8?B?Zkloc1FIMGttNU5JRXZWMDUxekk0dlp6ZVA1UVhrRW1XQStqM0RFYTZ0WWlX?= =?utf-8?B?M0drakVjelMxam9pMW1zU3gzVVpHUFUvSjVGNndtUldXVWdpcVcxY0Nsdjda?= =?utf-8?B?SDExQzNFOHBUbmxSNXFRTWJ3czZHakY1aUR5dGFlZkRzY3RXamRwZDhUbDRS?= =?utf-8?B?U2FhTHk4MW1hRmdra0c4QXZkMkl5aFZSMHVNVEVWVjJkNkgxVTdhUC9jSzFk?= =?utf-8?B?aHRyS2M3NndhN3EyN1BrcUlqQy81RDdxNE1zejJjR1QvTStHbVhZTzBHUndH?= =?utf-8?B?ZjNhZ1ZNT1d3ajkyWDFtUDRmQmdNR3EvbUxHeHVpNTlLa3FMaldOTTBxZTlu?= =?utf-8?B?bUltOHNLUFhvbHJ5VGpVdUNwNU42S2cwditQVEJWeHVMVC9IV0FQczFteWQz?= =?utf-8?B?Nks4djMwUU9kVTl3aXpCR2dmWEVzOTIycndOcm5uL2ZrSUFwWFdFR2EzVHdo?= =?utf-8?B?ZkRXakd2UlJUdlJnQkdEeDRyL2hWQmJKemYxM2hMQTFCNUVWWmdNNDJ1ZGJ5?= =?utf-8?B?MHY1L0cyNUY4NnRETlE2dXVNZFgxUXFFYXpZeFU3ZWpqaTNyRTVrNTllbkF4?= =?utf-8?B?VGVqdXR2NExLTWFOWjVndWo0RkZUSFlOUnhZWk1TM3BOSTRtU1p4WDM1Rmxv?= =?utf-8?B?MDBmbjN3cGNZU2h1R3NKVDlHZ1puYUtNSXpKQVdVZmoyOWFtYUJjeGNuaEln?= =?utf-8?B?N21uVnVVLzR5NW8waUROb2Fvd1JWVklkR2x4bVIyd0xoTFpCWFNBdFFjTjQw?= =?utf-8?B?UEQvb1REVXNrTDhxWFRwRnJCeXI4em5SRWNlbWxwT2VkbzNNY2FkbHE1cllO?= =?utf-8?B?ZWJiZDRLTEVDZHJZMnMwZHhSSmc1ZmNZQUtqZjRMRkkxSFkydHZRZjEydHdK?= =?utf-8?B?NXF6V1lXbVY5dTd6RFlwNjh3VXY0dExSNzd0enpzSUdjT1IyU0VVY3ovZVFD?= =?utf-8?B?a2E0cU5ldzFTeDAyTzY5WjZCWHFKK3piWEMxZ0FEaTB0N1RoMk9YMXkwQk5V?= =?utf-8?B?dlJGM1NNSWJzaU1Rblp5eFkwQmVpUjB2akZFajRlUXBMZG1UZDFuUU1hNm9v?= =?utf-8?B?RHVnK25EMG9aWHVBdG1vV2ZPSnl3dkpSNkNFWW51eFJ1MHFHQi9IZktsZytO?= =?utf-8?B?VkR1NndkRkFPQk1JaWp3ckZUdUxFMmMvNm5BS1Q4WkJoV1ljSG9wemJxN1lQ?= =?utf-8?B?MXhtQTN0a2VLVDcvYTlHclVLbWJLdzFwbHo2eXJVc1lWS3VNRlRRQ2hydXht?= =?utf-8?B?Nkg4c01Hd0k1VlhaR3VZV1EvQWJESjRLNE4rWER5OEFmVTNVa1c4Vk5jYnla?= =?utf-8?Q?2+5eHt2T3zQ0lfIVAIPb+Rtb7qXOniZ7?= X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1394; 6:O0A8i0YU1eeHme0iCHrdxAITlDEa4Tbv8gcU5z1bpqEsiYaJIdxY0519EcCX41Z9eoX8VU2VnhHeznXS6cR6qAPTj4jSeIIKq7bRLFschcnt7q+eCeYJwfMqtSCoq02bh5uD50UO3I98tHVfdha0BXpjUxHVl8WjEIAr7r3Bd0/WcKlO9EazyA8GlCXAum8q0O2biDzOUOJwKsTREAKlIEufq3nVlFcak0RTNqOP1G6RfbGjrMLSbtbv4exhEqDg7HQNwWlPgsPYCUqhP2t+NlO9UoxMs8XjB+IlE+pZdMf1dYW+3wasxABnWra4lfJK/vBaWK5WcSE7omvQILKs4FAfCcWaQ2x6xP8nG8DapvU=; 5:h9fPJvLilLBqEnZxkFKzn5iDVaqYTbtPtJBMo7jPv9uoStxBn0dsb7ziFT10Gcl1wq90nhBJyG+doG1P4IzJaufFXJUAUDNRnUPgYOYS6NPmLEGHG9oJ5r5SbomtC9bGKQwiKFdf0VWTReqq1oNrYAulq8vd2G9hN35zhWF4d6w=; 24:ZoAojkJoV7f3XG+F6sNzyxy5RunBZqjXJ4NKrC+PJn+dy1BlxcJRKuY9inpPetaaNJRnmoSco7jDEQta5hvf2TpvR6bRIHEcose+12GJurY= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1394; 7:sCkUi1/mPN/5goHMLpjK6jC5fdQP3KQEd6tBHiqN3pCAGA4/oocFqa1cvgugd7gtsJ3ztMvhuUOV+ic95h4U2aA9XSD4OxjiZHMP3RsOUqcRKIQHQY6SmkA3Bs5fxAnmOHTXt0FKYyYA0Q+jtkWso4w72LrAJU9tthLFMEYByKXtNgcJMpmpHvdYvCb6q81N6B5bYp99I8t+u8wkm2c+N8lkiYka+7jP/lH7ZR54ITnmF9HvQPGCO9Zo4/DFghTshFeKXBVKJZRWpMXD7O2jb+tQi3s/T2k0oxPJOSc7Ac3A0X5dUepdJx+PBGOmKQPObyblyfFyG0inwotD3kRvwkfHA/Xjn2b/R2cOlJ/cpHY=; 20:NNx0pWlWcr7P6TPlWZnTia5I4e/BfnK8qURrHcgon6VOCKQ62LGyCFVws+Px1jiGlFzYeEqcC8KOzciqf15EODVvzh1CpNbPF/s4Wc8/OuRBNY3squEPr/CtsOF2BlB26lRqvz9lgaqH5RqAFQw6Yl6OHgQyK+XHOLn8QQaHsr6ZmZdWy5zwZ3UHxah0Nodv9yHjNaR1k4oZ3lunbfr0hY+RuFAaSGoyP8iu+q5qFvETOR2DzDLmodTjTXIATSgA X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Nov 2016 16:05:12.0415 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR12MB1394 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 | 20 +++ 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, 606 insertions(+), 3 deletions(-) create mode 100644 drivers/crypto/ccp/ccp-crypto-des3.c -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile index fd77225..563594a 100644 --- a/drivers/crypto/ccp/Makefile +++ b/drivers/crypto/ccp/Makefile @@ -14,4 +14,5 @@ ccp-crypto-objs := ccp-crypto-main.o \ ccp-crypto-aes-xts.o \ ccp-crypto-rsa.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 e68012a..f492286 100644 --- a/drivers/crypto/ccp/ccp-crypto-main.c +++ b/drivers/crypto/ccp/ccp-crypto-main.c @@ -38,6 +38,10 @@ module_param(rsa_disable, uint, 0444); MODULE_PARM_DESC(rsa_disable, "Disable use of RSA - 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); @@ -348,6 +352,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 cc5044c..cce3c9d 100644 --- a/drivers/crypto/ccp/ccp-crypto.h +++ b/drivers/crypto/ccp/ccp-crypto.h @@ -158,6 +158,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 */ @@ -246,6 +264,7 @@ struct ccp_ctx { struct ccp_aes_ctx aes; struct ccp_rsa_ctx rsa; struct ccp_sha_ctx sha; + struct ccp_des3_ctx des3; } u; }; @@ -260,5 +279,6 @@ struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table, int ccp_register_aes_aeads(struct list_head *head); int ccp_register_sha_algs(struct list_head *head); int ccp_register_rsa_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 3a55628..6c8c58e 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 f386fca..811668f 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; @@ -998,6 +1051,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 1424f69..c25be6c 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 98f7983..bdf1147 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; @@ -2165,6 +2360,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 423561a..985fd03 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h @@ -300,6 +300,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 @@ -549,7 +603,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, @@ -597,6 +651,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;