From patchwork Wed Feb 15 21:56:18 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: 9575173 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 8534560209 for ; Wed, 15 Feb 2017 21:56:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 751971FF27 for ; Wed, 15 Feb 2017 21:56:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 69A1528556; Wed, 15 Feb 2017 21:56:38 +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 EDB201FF27 for ; Wed, 15 Feb 2017 21:56:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751571AbdBOV4g (ORCPT ); Wed, 15 Feb 2017 16:56:36 -0500 Received: from mail-by2nam01on0052.outbound.protection.outlook.com ([104.47.34.52]:43520 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750719AbdBOV4f (ORCPT ); Wed, 15 Feb 2017 16:56:35 -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=F9K/R4PkDbdfHEEGkgFauXO1K3BohYPmRZayCYlJDzU=; b=iWn7qZpFWI8TTYWJ/y+adJhGZpLryHtvY+kgmL2hWqMaPGPIILUCG1V44JQiqg3xH8OT41tKI3sGvJWVcyvZ7jnA7Zq1kt7C+DUVoT04G4yaF6fINOBvDx35P+OhY2r7pHcL036b2UkpAxJ1zTQ5LSQ/yi5ZZcNrZPrQ7sl/W/E= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Gary.Hook@amd.com; Received: from [10.236.19.42] (165.204.77.1) by BN6PR12MB1395.namprd12.prod.outlook.com (10.168.228.141) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.888.16; Wed, 15 Feb 2017 21:56:30 +0000 Subject: [PATCH 3/3] crypto: ccp - Add 3DES function on v5 CCPs From: Gary R Hook To: CC: , , Date: Wed, 15 Feb 2017 15:56:18 -0600 Message-ID: <20170215215618.26536.71792.stgit@taos> In-Reply-To: <20170215214954.26536.76736.stgit@taos> References: <20170215214954.26536.76736.stgit@taos> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: CY1PR14CA0027.namprd14.prod.outlook.com (10.163.13.165) To BN6PR12MB1395.namprd12.prod.outlook.com (10.168.228.141) X-MS-Office365-Filtering-Correlation-Id: b8e0db05-779a-4897-529b-08d455ed8033 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:BN6PR12MB1395; X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1395; 3:zu/IasfBLY93vj3wEGHiHPaMGegRXvT0NiqeFZIpoFkXzYyPZx0cLP8lzTMaZH29cZEER/XjXgATF00hhl9nqmWQaiNRP1fMANgC88MKNe+VTITxzLI/G/zISf0NAlh+51AlF4a7UmatlJrJqZ08QH6Vwa+Ln719wxwKmNyaGkBrFm7XmGofnrbJ6I6jHWSBrh07yF5MO7BUW7A9iV95RwVo7mk0JTI0OjsiBwpyzfwiP0DfdKiUMj0P8XWUt/PMx4D89yXGr2Ln1tQgAetPD+ymJviWjPd+POiO2GFptoM=; 25:i1AvrFN0ATRwtMiDn4gVPEjQEGHI2rdMCa4gKB2xq6AcOgGWodJpDoirM7GKfwwuu+SQWoUXlfYn+ZFl89RiaX1yD+k6W2ixRxj+Ez9gCAqYeMfu9qj5Gi3LZpZX2tWVCQKTLnA2KSt3/aAYT6Jbt4uhtdRDGKEtUpWYViHLaLnRIMtffDg9ZeRKvyiOBamc09+itsJw6An+FPF1GWo5MzDjdX/6hgxKl5AORrAXU7NVdPkVR2rESlKTF3AM0e50f/OFZR6nCRMgzFStIe0usENmzzN5GDRCaDNFmT+BTlznCXNbzY0P9lIs1umbLyN+IcGHXEjiO3IyCr/Cdnzb/mw5G8LO61OyuB4J+6aY8EgTvbJ39Ol4uk4fYqsawZ6fR9rOxkf0JfgdeX60qULGdnbiTymFTzd+4lS3xsz8GGkzabRwlCAB0evRXuzvrQtPs5BHs7rrRjaSlCQBmVhhEA== X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1395; 31:SlmaHI7ne/ZSbrQhFWqJdVYnfHrAoq9ensb2egBf9XdXUKqei1BYdKRB24auZIP7wamwCAjQo6sOaPrz/PQ0VfJKFyO6rSAbfFXSRhwbT5KbujxlJCeeKTUp6h9PdU7tMymIVilVtmfYY03MpCfWEo7wx1BqTy+r6P+iYU/6akSH5XJyV9tnzxvXFNlzW8yQKlkqKrFNuGOIwGXNoj9TZorm65MwtKfkRXJsk0J7i7CmFbE8jkEo2pg5EUqXAupxQMwnEUXfsyu4/3XqK2B1zg==; 20:8RKxwkc+MpaMCCDkBIWtUiV0te9oV34qn2/F7ZzKNFWTgYcetNAqfFwIvhIqNXyQxvOUBip5hgaghmIm+vrtIcdza+gfNLEK/KkMUTdvU1kiltcb6OJmzmSgi/TKUmfRxrzuR2mP6Qq7cTJGtIEKZmC5b9i30XWUb2bFFIXOIq0G1uxz93EuoDjqDVXMDxYwopfU8Qe8ZBpnsNOgR3vpl7NL1vKRwRggR2KzQqPuE76mh4IiCXQ0YM5B0t4zpI7Yn/ficwRweccMbi7C5AMGlch8jTjD9rBjGgTR0aXzo7+2wabkbqpKav/P8ogO7DQW2ew78m6zC5AyagFLwCUIrRFQi82BzGz4la2q4bKQAp/qFsbKs/c9ZEOhN1oaFa17gX29pLTJDqx0f9QNX6zV6rvn7AUGcZZ08w1GymmxHtsK/bIxl/7koAHfrgMx76r/iLSslB6D5Ig0Jty2wVlLFeNOoxnOQSf9yETvgcFUUdjcYESTi1iMxl7a3lQuudiN 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)(3002001)(10201501046)(6055026)(6041248)(20161123555025)(20161123558025)(20161123560025)(20161123562025)(20161123564025)(6072148); SRVR:BN6PR12MB1395; BCL:0; PCL:0; RULEID:; SRVR:BN6PR12MB1395; X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1395; 4:BGbswpLsfRvoo6pEJFnbnkM5aKuTrxMVgPNcy5HPGWTXp2nHBA7pMwMqium+AMwU/x/AgA7X/W4v3jQjoo3gG5hsiElCLyNJwRsSxHGu2XG1Sh+kUurdlTvaz14YxrZIF17Veal5SMTGQ4cXiBT3wUXUaI3ynaLcph34mFcLEgt16e78UTri0QCN7btQd4MpC2tTXTrmfyp6Qc/7NPz4x4cX/jNuG+moRMoDPIZwqlbYHv8R4rtsSZHWIZhoVukpjBthC+/HFJc69xexZR9ofc6y6x0B/Sk1F/RvHHq/njHfQLabuV+YHQPlSNQbHBqiZ47jX9os4tkmA6eAmtW4/I1DAjYFXY2EHCdFeJQYgxR2jzjroXGJTiCuY8FJsTnr/T3nF5y5kfOdELZgRlwRjMcYkesJ0NZRRxSkLXU8zPBRH7T0giwapNSV9iH8xLuDXa8wofT2svFoIaM1yeS643t0ft7J3mTfQTfBq7d/CPsM8Z4uAm/8ycqnHyV7tLDG4VLRjulNh2oYHwHe73NUjN2s38cayf45+33JsTC7Ktnv6VZDoEq+dGs6ton/9vVhOW7/9TpC+C6Wse6RsqZ4OzZYZ0d6XcZeiZUmehUuSh91QnUrnJVEuLzLlvJehWhg3owOv0wbtyrb47m4Y/1kfl7sMptETWxSAtT6Om3grd8= X-Forefront-PRVS: 021975AE46 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(6049001)(7916002)(39840400002)(39410400002)(39450400003)(39860400002)(39850400002)(199003)(189002)(2906002)(53936002)(6666003)(83506001)(97736004)(86362001)(77096006)(6916009)(103116003)(2950100002)(97746001)(54906002)(38730400002)(81166006)(110136004)(9686003)(389900002)(81156014)(6486002)(2351001)(50466002)(8676002)(25786008)(33646002)(90366009)(33716001)(66066001)(5660300001)(106356001)(50986999)(47776003)(105586002)(230700001)(92566002)(1076002)(3846002)(189998001)(6116002)(42186005)(54356999)(76176999)(305945005)(23676002)(101416001)(4001350100001)(7736002)(68736007)(4326007)(2004002)(357404004); DIR:OUT; SFP:1101; SCL:1; SRVR:BN6PR12MB1395; H:[10.236.19.42]; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtCTjZQUjEyTUIxMzk1OzIzOjFOaU9WODR1bXVTMGNZdjRPRThSTGU3MGdP?= =?utf-8?B?bzFuMmhkQjJqMlVRbzZKRitBazdONm0xazRCbnNzOXlzL1NnK3k4WC85TCsv?= =?utf-8?B?dVBVUDFrUnRMbTVPemV4YVNESXhkTkFWWk45UGtxQnI3djFVSmQvOWtHZXpn?= =?utf-8?B?YXlyUDNSb21iRUtBdnEyV1MycVAyenFOU1FFY1FXYy91c2lDQUl2UmJBLzlD?= =?utf-8?B?a3crSEVyaSt6dklFZllWQ2RabjlXQXVsMmRkeHloYnAyckhQd0w0SGphdC8w?= =?utf-8?B?QU9LVjY2Sit5U2FSTDJmVVlTY21xbURQQVBnUFZRWHVONFp0SVBXeTZzTjUr?= =?utf-8?B?YVZMRTlocUxDU3hqa1JqNE90czJaaXVIVlIrTXBXYjFYcytGOFEwYWRyT0FG?= =?utf-8?B?ejA2eDVHVGMrRVhYU3FGM2s0blZaUi9IRXVXbVAxMU80UGo1eUZUVWF2T1hO?= =?utf-8?B?bHhmaUgvMjgvMStCb2xDT2p4RjNIVitaVnFveGZvUXlMVkJFZ0NXSS90cnQ3?= =?utf-8?B?cEkyYjl3Mi9aUlRZemI2ZlRDNFQyOEpYbVVybzRJSTNFSTd6Q1BhaVZ6WUtM?= =?utf-8?B?U0tBYmFta1RjOWd3K1lwR2ppcFI1ekdITHVBQ1gvQ1FHUlMyd2VaSmVPOTJo?= =?utf-8?B?dlhmeXp0MFE4TnY0Wkc5MnN6OXRLcG92YlU3WFdsUjlyQ3A4bmhuTjFmYnBl?= =?utf-8?B?bkl3NzFlTDkyR09HM3JrSkYwRUtBRDlTdkttUGpOaHc0blFUdWt4dld6Nmp1?= =?utf-8?B?dEFsZ244ZDZIdTlXVnI3TXI3SlNxRnlNdXVuRnFIeEFrYzFncWtGOHZpSDA4?= =?utf-8?B?ajM0MmVLaU0xWGtzUXdsdE1qcy82VUJ0em54Uld5cDdodVFSdGxPK05EWFhv?= =?utf-8?B?RHoxK202aEtMbHZCQ0NVY3F2L1M1QUlSNlRkdW5jSnliN0JvTmxWeUp4aVAv?= =?utf-8?B?TVJPWGJrbGVRejVhNEd5Nm9sUkExUGZJbUljVHNjOFNQZGxIZHZGdVdTdnUz?= =?utf-8?B?R3N1SzJjZStwV3cwS2lGY0RGS25ZRkpGNHROVUczYVFTVmkvM2FyN3dBdzRM?= =?utf-8?B?aWRpQ2Fid2VqQUlIRTAzMjluOHBtWDB5U1JTeGpDWm8vN1ZZeVp0bmNvNVRo?= =?utf-8?B?OEZNZE51TkJ5LzdlSFJlK2NjVGtNaGk5cHk2S1Y5UFY4Z2hrUSt6K3Zwc1Vl?= =?utf-8?B?VE5LV0kzRGlxQ1pPeXV0eGdtLzdva1ZJZkNDaWpnamU1SFFHV0NzcHhYQmRY?= =?utf-8?B?L0pJdERnVHJiQXNTUEQ4aXRDbUQwVHhVNXNXdTdUblRwTVJTSndNUzNwL0c1?= =?utf-8?B?dXZnOWdWUDhzVmNHWmRKdTNrZS9RZmhzYzBBUXBWbmI0MFNMY1A1MXR4a01p?= =?utf-8?B?ZWNON3B4NTM0c0V0dERQRnd6aUxwNG12V2oyeDRQTWhMNTVzbTR0WTNFK2Z1?= =?utf-8?B?Z0c2bDhMay9tYnVLNURYUWpva2hjQXo0U25NZWh1aFI4alJKV2h3bS9QZWJr?= =?utf-8?B?WFdhUmlMMk1rTGloUHNZa2FyUHpWSHpnWlZSa3lUTHJ2V2ZKOGdub25PYUxx?= =?utf-8?B?SGY0UExBVVJYMjE5WU9ZU1p4dE9HMC9TZzVrdWlDdjFUUHVET3dzWEVGSERO?= =?utf-8?B?K0xsM1U2NTFSb1lFcGlYWlRCMVhLemxjenpNNTZSZFlocmh6eEh2YUhCazZ4?= =?utf-8?B?VHlmZUNSbXhxRVVQZGw3YllLZ1U1UkpGQjMreDh1MjFjYlFobURLRlppaFlJ?= =?utf-8?B?NlBETC9wTUlmSmlsamtpaEhJdzJJRUVZVzNCaWs3TUhCTFJXSC8zbGs4dkxV?= =?utf-8?B?K1lIMnkyeEVRREoybmNZd04zMjE3ZUNHa053c0k0ZXFkS0lKRFE2NmdYQ1lh?= =?utf-8?B?c3JLZ0lLeHk3RktxU1dydmpwbE5XWXZHMm4rTHp1a2FTbWdvNDNpc25RRzBa?= =?utf-8?B?cFFtM3JhR3RoTXFkQ3hmWDhwb0w5amFYZm9LMnl2dFAwaUdnTWtBZnpDSHZM?= =?utf-8?Q?tAtf8K?= X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1395; 6:OBnVSpbRoyKMjn7xiZbdi5XqN6MlMxoEIoxb76cUkOOcG0olI0AS7KdPszFwGmrXaeudLRfxJHr+POwTKgg7NVtahyhmoOJEQRXL4f0cQpDTahkwD/QXB0Lc2sAV27gT+c3uV0rtpoXEJtHuWTbAyb31MNj9F7mlgr5oEgJ3UtAtgBxvRNO5CVlcc5GtDp1S/W9xX0Fm5o/hjBH75M7yXwcBAQcAv4bWIgxLNch7HNFa6os5te8kwRRFOw6NnmLc0foGnKFA02ft+/3PUdp/eIYZwdRoC0BtXyXCOFyTYEsH2LyrjL5LdSS0BwfeKga9p0MM8ellFwH5n6Fz6adzxVXQ8a6YOH6ZcYI0EjgeTh/2aydqRMtdIQV1+96lBGTCWuzn5V7hK4Bal6gdxq+KTZtV85XoTtPILLxpktqw9p0=; 5:SZMHAL2uK6eYiEJJy3l/3jwclAGuHd80ld7L6Q/Fe5CST2iWGpSc2I/gibuNnNrUqIiLFQsIpZsHr3dS5OHadOpD3D0LZYHZo7Cbt/qRKJRt8fYFGe4+3gGkJKHJFLIvwRH4IA20TvZ7pHGWvQvlwg==; 24:YpjO5Fs6s3pOVhrpD5bY4/YBDMKTIWrgG9aur8nIFnrkE1VCnMZOy75LviHtBryO8MKFPLgPaHmGjDmGfxlcNvHsL9EnAq7/rZbsmZJ1O+g= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN6PR12MB1395; 7:UPoUNJhaZN2m+PM/Qs6AojZwprsOt1NF9BTCOhUeH7y+7fHSqfRSsP+YpQ8ATeAnT3qrURJKkJMyn6o2LluuwAavPQhqCS+aRRdsekqSrPaSmDLmPk5Cs9OJIsvUpA8wXaDs9HlGEF1Ep3pSiBnlBVXKAQq0p+K79lJ8zFd8r/iu3Q1e6W0/uuuxFRHOkV5ZpvE/oz4j+/h3XFZSykLhIpf/dRCSYb4PMPxwznd6Glj6srzresSErcGsfvGSLWzl8WaKsswxwUhYM8klsFzwAKVHU7w+ijgFffblmnPPLNh9Ku1hfMzWzRb6p69GTYIaTVUOYSYms4Jv78ptXvaDxA==; 20:luuqTQI/jZGbTboL4e3PngR6qqbq44aD1IDIq3E6yS3+P5XkMqAToOTxlGBvJewy7tSeRI7oSlqPAk7+qyL82iKtJyTrZP5MWJCZt3zs+kAtKxTDGaZxPb9w2CFctcvxD5p1BrGXI43LH6GEdpQfJqvILiQYdY1T0B4/G3dFdEr27/DboqFLxjawCvcYt5EABXG94Yvxxe+tGlsaJ/loGW25GIK72G1iy45sM2EnZSyEdI9BaY2cNOJPQ5bwJuHm X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Feb 2017 21:56:30.6274 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR12MB1395 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 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 64e8cfa..228210c 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); @@ -343,6 +347,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 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 2a55610..fdbbb1a 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" @@ -1191,6 +1192,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->ccp_act->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->ccp_act->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; @@ -2155,6 +2350,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;