From patchwork Thu Aug 10 17:42:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Horia Geanta X-Patchwork-Id: 9894443 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 D150D60384 for ; Thu, 10 Aug 2017 17:49:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C005128B45 for ; Thu, 10 Aug 2017 17:49:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B46FC28B50; Thu, 10 Aug 2017 17:49:42 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2EAC728B45 for ; Thu, 10 Aug 2017 17:49:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=98jSEbWutZQezZxBg/7h0OckJ8XE6hVfV3P8Y7xkMWc=; b=l2hgPQUBFapXsb sOtaA708a0u/6ZvwpJYigKyTc0wtwB75e6HM1vG40luEJp4j4jcr+RXFWdZMk+FOmJZtJhBxKSlft GhInLFOnW1KBPU0EYe9BaUbWZpgeSYOWz9kUmusFsrh3y3RY+IDgtoV0MQY2ggs3ibJyB0l/Dtswu C2agQjt56vBs9EkPn3JPv3GOjkXmDJDRjLWIQP13/4b5INHsoMsJ4iQ3kAmL0Y+581GdXV1xqoRKm iw2MHBa8DtepgEmZt/4EwE+xyuvqKloGdayKqc+5xpabIMtzpDRecit8Ux4viAxThCDOjXxADyFxg iibphgZeWSsl05A48lBg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dfraU-0007bx-9e; Thu, 10 Aug 2017 17:49:38 +0000 Received: from mail-by2nam03on0061.outbound.protection.outlook.com ([104.47.42.61] helo=NAM03-BY2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dfrVL-00030S-Oe for linux-arm-kernel@lists.infradead.org; Thu, 10 Aug 2017 17:44:40 +0000 Received: from CY4PR03CA0002.namprd03.prod.outlook.com (10.168.162.12) by MWHPR03MB3327.namprd03.prod.outlook.com (10.174.249.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.1320.16; Thu, 10 Aug 2017 17:43:57 +0000 Received: from BY2FFO11FD034.protection.gbl (2a01:111:f400:7c0c::117) by CY4PR03CA0002.outlook.office365.com (2603:10b6:903:33::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.1341.17 via Frontend Transport; Thu, 10 Aug 2017 17:43:57 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; driverdev.osuosl.org; dkim=none (message not signed) header.d=none;driverdev.osuosl.org; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Received: from tx30smr01.am.freescale.net (192.88.168.50) by BY2FFO11FD034.mail.protection.outlook.com (10.1.14.219) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1304.16 via Frontend Transport; Thu, 10 Aug 2017 17:43:56 +0000 Received: from enigma.ea.freescale.net (enigma.ea.freescale.net [10.171.77.120]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id v7AHhN21012849; Thu, 10 Aug 2017 10:43:53 -0700 From: =?UTF-8?q?Horia=20Geant=C4=83?= To: Herbert Xu , Greg Kroah-Hartman , Stuart Yoder , Laurentiu Tudor , Ioana Radulescu , Catalin Marinas , Will Deacon Subject: [RFC PATCH 09/10] crypto: caam/qi2 - add ablkcipher algorithms Date: Thu, 10 Aug 2017 20:42:52 +0300 Message-ID: <20170810174253.20951-10-horia.geanta@nxp.com> X-Mailer: git-send-email 2.12.0.264.gd6db3f216544 In-Reply-To: <20170810174253.20951-1-horia.geanta@nxp.com> References: <20170810174253.20951-1-horia.geanta@nxp.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Matching-Connectors: 131468606370787413; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(336005)(39860400002)(39850400002)(39840400002)(39410400002)(39400400002)(39450400003)(39380400002)(2980300002)(1110001)(1109001)(339900001)(199003)(189002)(104016004)(8656003)(305945005)(53936002)(68736007)(356003)(2950100002)(39060400002)(38730400002)(54906002)(85426001)(498600001)(50986999)(626005)(4326008)(53946003)(76176999)(5660300001)(1076002)(2870700001)(7416002)(50226002)(86362001)(189998001)(106466001)(97736004)(8936002)(2906002)(36756003)(105606002)(8676002)(77096006)(50466002)(81166006)(23676002)(33646002)(47776003)(5820100001)(81156014)(5890100001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR03MB3327; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11FD034; 1:2Jm7/jQzqbRiHyu0pFMtw1/wnwK0JevHlExUal16V2ibXQwucCurPwu4Qq1MqezqC17Fk3Jhvb9jHfnahMHe4hu15VVq/94JuIr5h8AXwRiyJeu1yAT+MivwmDef0KE7B3KDNixxfkFM4pAuMI5lxgPhRrD43I5XUQNx6Bkwi67gT2gNghvy9UVR4UeANUAXsz7QyyVGfzIyPDxbuJenTd1THqpmB9LHXbNzLjXYgF4sHl1yReTn8wyYNd17gSVpXpn3iAtsIKEbQ5ZI+UXD70/5Sno1TQ9/lqEw4Zd/tqZtW6MsEm8MVStGKlLA3xnvAoqIZWx16BqgZhowIRW8DyfiHBGWE+3zhsWqbVRzf1Eb2hQ7IdYm2dIK3Dl77fTr0QTM0WYL4u4IT21xfxX09ltnGRaluLTmzKlihm0ijw+7l7ZEiNhsyw2cIl5RQewb18wcosTsby/TBe8mXTYnlgDZF6oVxX8j9asNJnmPhxejf3b3puOwQ5d2RibpS9On/ZHe7UPJwd6h7FxQFnsFEUEhCBe0W2Q6X9Lwc+Uyw0/aE+gxVmXAtx4E/3LKzw3khhGu8I81nSHXudHEBA6m5ZcIlpbclPyVfhK4s6SFjPwkcvKdllnehonBz+6pWPUxvYZarQukMTK4KYxfbnbAVyWVwTrfP3em8yZLlEQP3EidYq9+ndpOwbXFhjy3iB17OyrXEVYGVaeIRJYis8AU8LJWB+rFKRfk9aW8KpAvfy5M0tYbvmTYHQwtbiawW2U2V9x+JnPgg/EClFMJ+lUP+ZPZBf5XsOGX1fTCk+HuM//71zCgoEdeVNY+QWb/LQ819HrtOnsun6OK0+Lhdd442S8t8p1WCavvnXYevDoR2rHMjk9or9E055lPJMJ+0+1N X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: bd2c528d-cb64-4b83-43ec-08d4e017603a X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(300000503095)(300135400095)(2017052603031)(201703131430075)(201703131517081)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:MWHPR03MB3327; X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB3327; 3:XxA9UdWN6bApRMo+NNb8GEx53PUVThc91Xc0vw0fiQHSUJJ+dzb7wO6BAhqwS4heUSDR4mgILSGeOVd/VlwLbiwUl5bwwYVbCKzqFd7U27FPQQHaHAofBX714lHk5Qbw+6PMSccvbd2ASgpgMRQBZuHt7sD9JWYAb4yKHV7LyRCYiRWfL+mE8O8+JBRnHR2IlAldcJKQLVX5QDdGVBXTPqwo0BUelUwDiEdcRIrnZEG/XLCQ7ueKTCSx7IyY4BTwNOuTWHOIiUT/9qvpAuOoo0crKUFmdPitqHR0I+7I7lUn8BzbrHnnjKRfnREwk2591pjlIBcoGWjGN3S+sVUYjkwlzE0G9ozqRwaxlw4zTaw=; 25:E8NN2x3f4xB/0sgvWn1zdjmcjwTqytLKqaSx3uqxnD/UA0vQoxYYIcye2/31BxDqlhMh5xYGL3gjQqb5I07Z/Pa6FyxkO58SuWdNI/DsiB5/rF6qclDxZHJ/HnOZI/voHMjA1P4nvxFHDRwpQidoXOTPkWAg+/XqLUth3P2sBaCUTsqSvDtKf4ADZtFUPJs9IC8qUjgu6VXGF8T9raY4vpuXLyHDu3RT7FizyPQTHfOoUR3QIHzrz3Rj8p5bkWpf3+05Yf7q3x5Xw4x8JXoAEiwW6Q7KbbGzRup1I3EZOc3v98ucjlhvXOYRszh/BNMNPlQ/YkikeyaNx7DB0cK5dw== X-MS-TrafficTypeDiagnostic: MWHPR03MB3327: X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB3327; 31:5eLPZPENyspW0Smi/tsatSRbPUI8tWuXTlJvHVOCEWoUveHuC0OoIfXCE4+hC938dG4hXSI9jvJbFoNQpZ1n1scQRG6gAGm0qVgYSZUKWmk4HpQZ3Y2enVb4gs2+w2sHnPtKKtQwuzFJnVtR+lI4O5kVek5Gerlnc2yX+0E+QCcQ23XCvb2gr08rMiQGrH0GYFYNSxF/PUx8HUeoTw7+3t1fKozlIqyK3PWlY+K089c=; 4:FKBGbz4JhMwOd0qi1gmJjb3DCkS2SJ4FmemlewbngO/WOxK71Y+Fmig4Od51+11Z64ZFwHhY3A3d5P4lRQOVW1T5mYfN+FfIvwLHzDgL8zICmJLqTgF+MBDEAG8qxzKc32ix+L9IA2iCv2/C0qXjMVdlEO3o+kWh7waEmPxmFVFkBJxWc4W2rmI330r3aCMyR/z47Mgc0kMNpNCpxsdQaAsW0TCQaX/CdBb7iwld+jXr+DLAVlkvo/TXfetiDKxb161dA9+jgWid/Y7OdzAAxcwv2lEeRHugW4QwT7Fs1iE= X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6095135)(601004)(2401047)(13016025)(13018025)(8121501046)(5005006)(3002001)(93006095)(93001095)(100000703101)(100105400095)(10201501046)(6055026)(6096035)(20161123556025)(20161123559100)(20161123561025)(201703131430075)(201703131448075)(201703131433075)(201703161259150)(201703151042153)(20161123563025)(20161123565025)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:MWHPR03MB3327; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(400006)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:MWHPR03MB3327; X-Forefront-PRVS: 03950F25EC X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjAzTUIzMzI3OzIzOjNUOUZRVWZXZ2tDUDlxVHBVQkJqSUlwUFJy?= =?utf-8?B?OTB5VVQ3a3oxK1k4NndOZkNMdWd1QmVRMkRYeXhtSW9velRob0VVRzM0N0FV?= =?utf-8?B?NlZCd3lIZVorUzB6elRlMmlBT1B2c0U1eENlSEVLMkYrZzRSTDJpakNMNzQ3?= =?utf-8?B?TzRjRFFnZU1FVzBuclBTZHcwbEl6RzYxOW5uOEoySjFGWFZTbCtnOHhyYlFR?= =?utf-8?B?NCtmajhSMW93N3llOVkzRm5BcG5LcThqbFI5R0dlMERqa3JNY2tUdDVoKy9U?= =?utf-8?B?SXlKTlVpS0p2Y29ZWExQbVpNTkJuNGRKclp0K0FMNHdvZGtWTmpVcXlxZ0E1?= =?utf-8?B?UldLMC9CeDFiYnJoYTZqVlpQZmVFUGpJb2dxVllqUVVLcVNUakdDMEMzaGNI?= =?utf-8?B?cU1kRUNNSWR4VHUvbVJZTy9vN1kzUDk2RjNKdC9NMEdIQmx5UXBzRTJQMGRV?= =?utf-8?B?bHdaYWsrOStvNk9JVUJrK3dyanFYemdObW5rV3k3RFFJTlp6TTgxSjB5Vkor?= =?utf-8?B?TWNFcnNIZHp3MjR1VzRwelFCYVBPSXJFZnNTRXBJaEtNL2V2L1dYb1Qzc0tB?= =?utf-8?B?eWhmM1lYVHBrNHlBUFJLMjhXNERmQTkwOTFDZzB6cFFDOE5IZyt1dGN4Y0cx?= =?utf-8?B?ZW83emF2TDNBTm1nV0tKRGR6YytQYnhsUFMvcDQ2anBpZ09CMm9iKzNDV0JE?= =?utf-8?B?VGxIWm5vQUd2dGZ2MnhvaFMrVWJ0WHdBQ2tVZERTVjBrN0krV0dzM3ZpWTRn?= =?utf-8?B?YlQ3bXBXdVJWTi82OEs1MVFNYkZmNVc1YmZGK3ByL21Vd1R5b0VyN1FzajB4?= =?utf-8?B?UUtTYTlBQnhRMmdxWllHbTVTUWZHQTc5TENLejkwVnBCS0dMK1JUcVdUUFdX?= =?utf-8?B?VThzVDZQUll4MzJCY2NnL04rcXNXMzdkcndRbGZKNWZlbVg3dklUUUZqaHBC?= =?utf-8?B?UE5WbnhUbXQ3dEt3TGxmWW1QTTVBSW9ic3o5YTlBSlNRTytoeFFWMnI4TkJY?= =?utf-8?B?c2FwdmdkeXBCVWR3MFRoWHd0OWJlVWlPMVArMFhmc1l0cS9pc3BRMmNXbmU4?= =?utf-8?B?aFhCMGRrMkErMEJrSXgrNXczS0pyWjJyZEZrZnNHek95M0E5V3FQSFBHWDVD?= =?utf-8?B?Y1J2b2RKU2N5YUMwL0xZUVFFTjIwY29UQm80VGp2T2NOcnNXU0k0OEM4Z1V5?= =?utf-8?B?OTRLdys1ZExQZ2RoWVU0NU9qZDBJblkydjVUNDFTMkR1N2ZUa2h5bEg2YTNI?= =?utf-8?B?cmpRL011L0F2ZE5VRmFJSWtmMkd6ZEp4SWIvcTdOd1c0UTNIdmNhMFMzMEI4?= =?utf-8?B?dkc1aS9XcDF2ZHNUMkllZ1J0QXJlUTVQRngxUHFKaDdKVWpvQWtlTmREMWRX?= =?utf-8?B?bmRzbFdidFJBSWU4dlpIZmZkazFaYk9hdmd5L0dsSzNXWENUcnhreWNVd3hX?= =?utf-8?B?eEJDbHVwNjJ0WHYwUlpQQ0xHTlJvRGJNUmdvR3lhZHZxUXBvWEE3aUx5aFdt?= =?utf-8?B?YVBEVldGT1FKUHZFbG5PNUtUZENzVEROajYzKzNBbnkwdEpZV05pcVA4Y2o3?= =?utf-8?B?VHRPUWRPVHArTDJHSzlLQllWR0IzR1RHYXNieFk4NjFvSnZocnNyWHU0aTds?= =?utf-8?B?V0hlN0g4TG1JV3lxK2NUVUNWd2lUKzljeHd2ZWY4Y2k2eWlTOFBFb0MwSmlZ?= =?utf-8?B?dzFiY2oyQ1VOZzF3TFVrQlBIUWtCZHE4Yjg2cEpzOUtKQ2YyWENLaTc3RG1E?= =?utf-8?B?dkk3NHFENVRPVjBETlp2WmE5YjlNdVI3NElXOUJDeFJrcGYrdFlWcnNFU2Nv?= =?utf-8?B?SWg5UGpDaTdlbElrYzM3cjYvSzgyOFYybjIxam94MVZpNHBwNXltT0xSR25r?= =?utf-8?Q?jpX0JV+mTtY=3D?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB3327; 6:7CyH7eqmGxVGeNnQfs4b4VpVt2HqVkVXCPYRQOk8u6lzMM2t5q6yJtBdoCiieriYkGY9QH3SXo0Yp2Og00aAiWqojAvJfQa3B2UFoqdD50N+TmM/tfS+Gh2IabLZGPwLVZAOEW55OGfe3NjFhrwYeEx6A0SMmawWC720fgQ88vwIEH866rFxtMp//bg7o48AJn1Onc1aFvaEk3znW6fBTRR+59eAuxt36Iy5dBwbd7oDJIhQGioPCCoyrC6pi5o7O1HO4ydLi8HeyHQJhz6HYSUzBKuos+hGg1FCd3Kq+aTh0oYdYwbw82SXMTw9B5A4eTLv1yRsXpjCuNAHWdVUOQ==; 5:LXRfibQ4t56yFY8lw+t7pva7Tjv8IFhDaJfIA0vSwCIszPz6B1ZIC8d8OFeETl511i/bw0whmVRqCwaWL0B/6LhMDmF4VoCAc/iROnyF4ouhhdWOXVJa4qCgumW/6BO9oF8oA4tWzdjru/zQ1uGa6A==; 24:mWc80iRJQYuUdPwyeMltujsbYJdSsbbjQgC5q5YLFM5+KWJX/m0+Q7iqoTqNPOsA4lZTi0z8P9cWzD+RtzJLNVKnD1cq9QDLB1yGTRDkmwc=; 7:8OJOuW2w+lRJWLNjyOIFmkcT2HxKKqkevVz8urXPnATe6sRgPD7JdQ83JVECQKu7BlVaRsie7XLqwpSU6ntPioNuDd60v9oBML9hoGaBuqXJaRbAJRMD2YNFwKxozwCSOIZvoZDJM980lDCMXYHCAw5xVc4aUZHF/Gziz7/XBUYuCMqgSx6AsvaQfOQ6hUjRaaoYYvsxFyZy8OH6IzgNgF68TRcll+Ff+sl532+7PVo= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Aug 2017 17:43:56.5795 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR03MB3327 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170810_104420_076845_1A851B41 X-CRM114-Status: GOOD ( 18.12 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devel@driverdev.osuosl.org, Roy Pledge , Dan Douglass , Radu Alexe , linux-crypto@vger.kernel.org, "David S . Miller" , linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add support to submit the following ablkcipher algorithms via the DPSECI backend: cbc({aes,des,des3_ede}) ctr(aes), rfc3686(ctr(aes)) xts(aes) Signed-off-by: Horia Geantă --- drivers/crypto/caam/Kconfig | 1 + drivers/crypto/caam/caamalg_qi2.c | 816 ++++++++++++++++++++++++++++++++++++++ drivers/crypto/caam/caamalg_qi2.h | 23 +- 3 files changed, 839 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index e45d39d9007e..eb202e59c4fa 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -159,6 +159,7 @@ config CRYPTO_DEV_FSL_DPAA2_CAAM tristate "QorIQ DPAA2 CAAM (DPSECI) driver" depends on FSL_MC_DPIO select CRYPTO_DEV_FSL_CAAM_COMMON + select CRYPTO_BLKCIPHER select CRYPTO_AUTHENC select CRYPTO_AEAD ---help--- diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c index 9dc5e1184e80..f32c518bc680 100644 --- a/drivers/crypto/caam/caamalg_qi2.c +++ b/drivers/crypto/caam/caamalg_qi2.c @@ -1047,6 +1047,457 @@ static int rfc4543_setkey(struct crypto_aead *aead, return ret; } +static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, + const u8 *key, unsigned int keylen) +{ + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher); + const char *alg_name = crypto_tfm_alg_name(tfm); + struct device *dev = ctx->dev; + struct caam_flc *flc; + unsigned int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + u32 *desc; + u32 ctx1_iv_off = 0; + const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == + OP_ALG_AAI_CTR_MOD128); + const bool is_rfc3686 = (ctr_mode && strstr(alg_name, "rfc3686")); + + memcpy(ctx->key, key, keylen); +#ifdef DEBUG + print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); +#endif + /* + * AES-CTR needs to load IV in CONTEXT1 reg + * at an offset of 128bits (16bytes) + * CONTEXT1[255:128] = IV + */ + if (ctr_mode) + ctx1_iv_off = 16; + + /* + * RFC3686 specific: + * | CONTEXT1[255:128] = {NONCE, IV, COUNTER} + * | *key = {KEY, NONCE} + */ + if (is_rfc3686) { + ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE; + keylen -= CTR_RFC3686_NONCE_SIZE; + } + + ctx->key_dma = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE); + if (dma_mapping_error(dev, ctx->key_dma)) { + dev_err(dev, "unable to map key i/o memory\n"); + return -ENOMEM; + } + ctx->cdata.keylen = keylen; + ctx->cdata.key_virt = ctx->key; + ctx->cdata.key_inline = true; + + /* ablkcipher_encrypt shared descriptor */ + flc = &ctx->flc[ENCRYPT]; + desc = flc->sh_desc; + + cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize, + is_rfc3686, ctx1_iv_off); + + flc->flc[1] = desc_len(desc); /* SDL */ + flc->flc_dma = dma_map_single(dev, flc, sizeof(flc->flc) + + desc_bytes(desc), DMA_TO_DEVICE); + if (dma_mapping_error(dev, flc->flc_dma)) { + dev_err(dev, "unable to map shared descriptor\n"); + return -ENOMEM; + } + + /* ablkcipher_decrypt shared descriptor */ + flc = &ctx->flc[DECRYPT]; + desc = flc->sh_desc; + + cnstr_shdsc_ablkcipher_decap(desc, &ctx->cdata, ivsize, + is_rfc3686, ctx1_iv_off); + + flc->flc[1] = desc_len(desc); /* SDL */ + flc->flc_dma = dma_map_single(dev, flc, sizeof(flc->flc) + + desc_bytes(desc), DMA_TO_DEVICE); + if (dma_mapping_error(dev, flc->flc_dma)) { + dev_err(dev, "unable to map shared descriptor\n"); + return -ENOMEM; + } + + /* ablkcipher_givencrypt shared descriptor */ + flc = &ctx->flc[GIVENCRYPT]; + desc = flc->sh_desc; + + cnstr_shdsc_ablkcipher_givencap(desc, &ctx->cdata, + ivsize, is_rfc3686, ctx1_iv_off); + + flc->flc[1] = desc_len(desc); /* SDL */ + flc->flc_dma = dma_map_single(dev, flc, sizeof(flc->flc) + + desc_bytes(desc), DMA_TO_DEVICE); + if (dma_mapping_error(dev, flc->flc_dma)) { + dev_err(dev, "unable to map shared descriptor\n"); + return -ENOMEM; + } + + return 0; +} + +static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, + const u8 *key, unsigned int keylen) +{ + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct device *dev = ctx->dev; + struct caam_flc *flc; + u32 *desc; + + if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) { + dev_err(dev, "key size mismatch\n"); + crypto_ablkcipher_set_flags(ablkcipher, + CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + memcpy(ctx->key, key, keylen); + ctx->key_dma = dma_map_single(dev, ctx->key, keylen, DMA_TO_DEVICE); + if (dma_mapping_error(dev, ctx->key_dma)) { + dev_err(dev, "unable to map key i/o memory\n"); + return -ENOMEM; + } + ctx->cdata.keylen = keylen; + ctx->cdata.key_virt = ctx->key; + ctx->cdata.key_inline = true; + + /* xts_ablkcipher_encrypt shared descriptor */ + flc = &ctx->flc[ENCRYPT]; + desc = flc->sh_desc; + cnstr_shdsc_xts_ablkcipher_encap(desc, &ctx->cdata); + + flc->flc[1] = desc_len(desc); /* SDL */ + flc->flc_dma = dma_map_single(dev, flc, sizeof(flc->flc) + + desc_bytes(desc), DMA_TO_DEVICE); + if (dma_mapping_error(dev, flc->flc_dma)) { + dev_err(dev, "unable to map shared descriptor\n"); + return -ENOMEM; + } + + /* xts_ablkcipher_decrypt shared descriptor */ + flc = &ctx->flc[DECRYPT]; + desc = flc->sh_desc; + + cnstr_shdsc_xts_ablkcipher_decap(desc, &ctx->cdata); + + flc->flc[1] = desc_len(desc); /* SDL */ + flc->flc_dma = dma_map_single(dev, flc, sizeof(flc->flc) + + desc_bytes(desc), DMA_TO_DEVICE); + if (dma_mapping_error(dev, flc->flc_dma)) { + dev_err(dev, "unable to map shared descriptor\n"); + return -ENOMEM; + } + + return 0; +} + +static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request + *req, bool encrypt) +{ + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + struct caam_request *req_ctx = ablkcipher_request_ctx(req); + struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; + struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct device *dev = ctx->dev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? + GFP_KERNEL : GFP_ATOMIC; + int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; + struct ablkcipher_edesc *edesc; + dma_addr_t iv_dma; + bool in_contig; + int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + int dst_sg_idx, qm_sg_ents; + struct dpaa2_sg_entry *sg_table; + enum optype op_type = encrypt ? ENCRYPT : DECRYPT; + + src_nents = sg_nents_for_len(req->src, req->nbytes); + if (unlikely(src_nents < 0)) { + dev_err(dev, "Insufficient bytes (%d) in src S/G\n", + req->nbytes); + return ERR_PTR(src_nents); + } + + if (unlikely(req->dst != req->src)) { + dst_nents = sg_nents_for_len(req->dst, req->nbytes); + if (unlikely(dst_nents < 0)) { + dev_err(dev, "Insufficient bytes (%d) in dst S/G\n", + req->nbytes); + return ERR_PTR(dst_nents); + } + + mapped_src_nents = dma_map_sg(dev, req->src, src_nents, + DMA_TO_DEVICE); + if (unlikely(!mapped_src_nents)) { + dev_err(dev, "unable to map source\n"); + return ERR_PTR(-ENOMEM); + } + + mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents, + DMA_FROM_DEVICE); + if (unlikely(!mapped_dst_nents)) { + dev_err(dev, "unable to map destination\n"); + dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE); + return ERR_PTR(-ENOMEM); + } + } else { + mapped_src_nents = dma_map_sg(dev, req->src, src_nents, + DMA_BIDIRECTIONAL); + if (unlikely(!mapped_src_nents)) { + dev_err(dev, "unable to map source\n"); + return ERR_PTR(-ENOMEM); + } + } + + iv_dma = dma_map_single(dev, req->info, ivsize, DMA_TO_DEVICE); + if (dma_mapping_error(dev, iv_dma)) { + dev_err(dev, "unable to map IV\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0, + 0, 0, 0, 0); + return ERR_PTR(-ENOMEM); + } + + if (mapped_src_nents == 1 && + iv_dma + ivsize == sg_dma_address(req->src)) { + in_contig = true; + qm_sg_ents = 0; + } else { + in_contig = false; + qm_sg_ents = 1 + mapped_src_nents; + } + dst_sg_idx = qm_sg_ents; + + qm_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0; + if (unlikely(qm_sg_ents > CAAM_QI_MAX_ABLKCIPHER_SG)) { + dev_err(dev, "Insufficient S/G entries: %d > %lu\n", + qm_sg_ents, CAAM_QI_MAX_ABLKCIPHER_SG); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, + iv_dma, ivsize, op_type, 0, 0); + return ERR_PTR(-ENOMEM); + } + + /* allocate space for base edesc and link tables */ + edesc = qi_cache_alloc(GFP_DMA | flags); + if (unlikely(!edesc)) { + dev_err(dev, "could not allocate extended descriptor\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, + iv_dma, ivsize, op_type, 0, 0); + return ERR_PTR(-ENOMEM); + } + + edesc->src_nents = src_nents; + edesc->dst_nents = dst_nents; + edesc->iv_dma = iv_dma; + sg_table = &edesc->sgt[0]; + edesc->qm_sg_bytes = qm_sg_ents * sizeof(*sg_table); + + if (!in_contig) { + dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0); + sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + 1, 0); + } + + if (mapped_dst_nents > 1) + sg_to_qm_sg_last(req->dst, mapped_dst_nents, sg_table + + dst_sg_idx, 0); + + edesc->qm_sg_dma = dma_map_single(dev, sg_table, edesc->qm_sg_bytes, + DMA_TO_DEVICE); + if (dma_mapping_error(dev, edesc->qm_sg_dma)) { + dev_err(dev, "unable to map S/G table\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, + iv_dma, ivsize, op_type, 0, 0); + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } + + memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); + dpaa2_fl_set_final(in_fle, true); + dpaa2_fl_set_len(in_fle, req->nbytes + ivsize); + dpaa2_fl_set_len(out_fle, req->nbytes); + + if (!in_contig) { + dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); + dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); + } else { + dpaa2_fl_set_format(in_fle, dpaa2_fl_single); + dpaa2_fl_set_addr(in_fle, iv_dma); + } + + if (req->src == req->dst) { + if (!in_contig) { + dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); + dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma + + sizeof(*sg_table)); + } else { + dpaa2_fl_set_format(out_fle, dpaa2_fl_single); + dpaa2_fl_set_addr(out_fle, sg_dma_address(req->src)); + } + } else if (mapped_dst_nents > 1) { + dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); + dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma + dst_sg_idx * + sizeof(*sg_table)); + } else { + dpaa2_fl_set_format(out_fle, dpaa2_fl_single); + dpaa2_fl_set_addr(out_fle, sg_dma_address(req->dst)); + } + + return edesc; +} + +static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc( + struct skcipher_givcrypt_request *greq) +{ + struct ablkcipher_request *req = &greq->creq; + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + struct caam_request *req_ctx = ablkcipher_request_ctx(req); + struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; + struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct device *dev = ctx->dev; + gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP)) ? + GFP_KERNEL : GFP_ATOMIC; + int src_nents, mapped_src_nents, dst_nents, mapped_dst_nents; + struct ablkcipher_edesc *edesc; + dma_addr_t iv_dma; + bool out_contig; + int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + struct dpaa2_sg_entry *sg_table; + int dst_sg_idx, qm_sg_ents; + + src_nents = sg_nents_for_len(req->src, req->nbytes); + if (unlikely(src_nents < 0)) { + dev_err(dev, "Insufficient bytes (%d) in src S/G\n", + req->nbytes); + return ERR_PTR(src_nents); + } + + if (unlikely(req->dst != req->src)) { + dst_nents = sg_nents_for_len(req->dst, req->nbytes); + if (unlikely(dst_nents < 0)) { + dev_err(dev, "Insufficient bytes (%d) in dst S/G\n", + req->nbytes); + return ERR_PTR(dst_nents); + } + + mapped_src_nents = dma_map_sg(dev, req->src, src_nents, + DMA_TO_DEVICE); + if (unlikely(!mapped_src_nents)) { + dev_err(dev, "unable to map source\n"); + return ERR_PTR(-ENOMEM); + } + + mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents, + DMA_FROM_DEVICE); + if (unlikely(!mapped_dst_nents)) { + dev_err(dev, "unable to map destination\n"); + dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE); + return ERR_PTR(-ENOMEM); + } + } else { + mapped_src_nents = dma_map_sg(dev, req->src, src_nents, + DMA_BIDIRECTIONAL); + if (unlikely(!mapped_src_nents)) { + dev_err(dev, "unable to map source\n"); + return ERR_PTR(-ENOMEM); + } + + dst_nents = src_nents; + mapped_dst_nents = src_nents; + } + + iv_dma = dma_map_single(dev, greq->giv, ivsize, DMA_FROM_DEVICE); + if (dma_mapping_error(dev, iv_dma)) { + dev_err(dev, "unable to map IV\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0, + 0, 0, 0, 0); + return ERR_PTR(-ENOMEM); + } + + qm_sg_ents = mapped_src_nents > 1 ? mapped_src_nents : 0; + dst_sg_idx = qm_sg_ents; + if (mapped_dst_nents == 1 && + iv_dma + ivsize == sg_dma_address(req->dst)) { + out_contig = true; + } else { + out_contig = false; + qm_sg_ents += 1 + mapped_dst_nents; + } + + if (unlikely(qm_sg_ents > CAAM_QI_MAX_ABLKCIPHER_SG)) { + dev_err(dev, "Insufficient S/G entries: %d > %lu\n", + qm_sg_ents, CAAM_QI_MAX_ABLKCIPHER_SG); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, + iv_dma, ivsize, GIVENCRYPT, 0, 0); + return ERR_PTR(-ENOMEM); + } + + /* allocate space for base edesc and link tables */ + edesc = qi_cache_alloc(GFP_DMA | flags); + if (!edesc) { + dev_err(dev, "could not allocate extended descriptor\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, + iv_dma, ivsize, GIVENCRYPT, 0, 0); + return ERR_PTR(-ENOMEM); + } + + edesc->src_nents = src_nents; + edesc->dst_nents = dst_nents; + edesc->iv_dma = iv_dma; + sg_table = &edesc->sgt[0]; + edesc->qm_sg_bytes = qm_sg_ents * sizeof(*sg_table); + + if (mapped_src_nents > 1) + sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table, 0); + + if (!out_contig) { + dma_to_qm_sg_one(sg_table + dst_sg_idx, iv_dma, ivsize, 0); + sg_to_qm_sg_last(req->dst, mapped_dst_nents, sg_table + + dst_sg_idx + 1, 0); + } + + edesc->qm_sg_dma = dma_map_single(dev, sg_table, edesc->qm_sg_bytes, + DMA_TO_DEVICE); + if (dma_mapping_error(dev, edesc->qm_sg_dma)) { + dev_err(dev, "unable to map S/G table\n"); + caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, + iv_dma, ivsize, GIVENCRYPT, 0, 0); + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } + + memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); + dpaa2_fl_set_final(in_fle, true); + dpaa2_fl_set_len(in_fle, req->nbytes); + dpaa2_fl_set_len(out_fle, ivsize + req->nbytes); + + if (mapped_src_nents > 1) { + dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); + dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); + } else { + dpaa2_fl_set_format(in_fle, dpaa2_fl_single); + dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src)); + } + + if (!out_contig) { + dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); + dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma + dst_sg_idx * + sizeof(*sg_table)); + } else { + dpaa2_fl_set_format(out_fle, dpaa2_fl_single); + dpaa2_fl_set_addr(out_fle, sg_dma_address(req->dst)); + } + + return edesc; +} + static void aead_unmap(struct device *dev, struct aead_edesc *edesc, struct aead_request *req) { @@ -1060,6 +1511,19 @@ static void aead_unmap(struct device *dev, struct aead_edesc *edesc, dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); } +static void ablkcipher_unmap(struct device *dev, + struct ablkcipher_edesc *edesc, + struct ablkcipher_request *req) +{ + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + struct caam_request *caam_req = ablkcipher_request_ctx(req); + + caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, + edesc->iv_dma, ivsize, caam_req->op_type, + edesc->qm_sg_dma, edesc->qm_sg_bytes); +} + static void aead_encrypt_done(void *cbk_ctx, u32 status) { struct crypto_async_request *areq = cbk_ctx; @@ -1189,6 +1653,133 @@ static int ipsec_gcm_decrypt(struct aead_request *req) return aead_decrypt(req); } +static void ablkcipher_done(void *cbk_ctx, u32 status) +{ + struct crypto_async_request *areq = cbk_ctx; + struct ablkcipher_request *req = ablkcipher_request_cast(areq); + struct caam_request *req_ctx = to_caam_req(areq); + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct ablkcipher_edesc *edesc = req_ctx->edesc; + int ecode = 0; + int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + +#ifdef DEBUG + dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); +#endif + + if (unlikely(status)) { + caam_qi2_strstatus(ctx->dev, status); + ecode = -EIO; + } + +#ifdef DEBUG + print_hex_dump(KERN_ERR, "dstiv @" __stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, req->info, + edesc->src_nents > 1 ? 100 : ivsize, 1); + caam_dump_sg(KERN_ERR, "dst @" __stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, req->dst, + edesc->dst_nents > 1 ? 100 : req->nbytes, 1); +#endif + + ablkcipher_unmap(ctx->dev, edesc, req); + qi_cache_free(edesc); + + /* + * The crypto API expects us to set the IV (req->info) to the last + * ciphertext block. This is used e.g. by the CTS mode. + */ + scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize, + ivsize, 0); + + ablkcipher_request_complete(req, ecode); +} + +static int ablkcipher_encrypt(struct ablkcipher_request *req) +{ + struct ablkcipher_edesc *edesc; + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct caam_request *caam_req = ablkcipher_request_ctx(req); + int ret; + + /* allocate extended descriptor */ + edesc = ablkcipher_edesc_alloc(req, true); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + caam_req->flc = &ctx->flc[ENCRYPT]; + caam_req->op_type = ENCRYPT; + caam_req->cbk = ablkcipher_done; + caam_req->ctx = &req->base; + caam_req->edesc = edesc; + ret = dpaa2_caam_enqueue(ctx->dev, caam_req); + if (ret != -EINPROGRESS && + !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { + ablkcipher_unmap(ctx->dev, edesc, req); + qi_cache_free(edesc); + } + + return ret; +} + +static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *greq) +{ + struct ablkcipher_request *req = &greq->creq; + struct ablkcipher_edesc *edesc; + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct caam_request *caam_req = ablkcipher_request_ctx(req); + int ret; + + /* allocate extended descriptor */ + edesc = ablkcipher_giv_edesc_alloc(greq); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + caam_req->flc = &ctx->flc[GIVENCRYPT]; + caam_req->op_type = GIVENCRYPT; + caam_req->cbk = ablkcipher_done; + caam_req->ctx = &req->base; + caam_req->edesc = edesc; + ret = dpaa2_caam_enqueue(ctx->dev, caam_req); + if (ret != -EINPROGRESS && + !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { + ablkcipher_unmap(ctx->dev, edesc, req); + qi_cache_free(edesc); + } + + return ret; +} + +static int ablkcipher_decrypt(struct ablkcipher_request *req) +{ + struct ablkcipher_edesc *edesc; + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); + struct caam_request *caam_req = ablkcipher_request_ctx(req); + int ret; + + /* allocate extended descriptor */ + edesc = ablkcipher_edesc_alloc(req, false); + if (IS_ERR(edesc)) + return PTR_ERR(edesc); + + caam_req->flc = &ctx->flc[DECRYPT]; + caam_req->op_type = DECRYPT; + caam_req->cbk = ablkcipher_done; + caam_req->ctx = &req->base; + caam_req->edesc = edesc; + ret = dpaa2_caam_enqueue(ctx->dev, caam_req); + if (ret != -EINPROGRESS && + !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { + ablkcipher_unmap(ctx->dev, edesc, req); + qi_cache_free(edesc); + } + + return ret; +} + struct caam_crypto_alg { struct list_head entry; struct crypto_alg crypto_alg; @@ -1213,6 +1804,15 @@ static int caam_cra_init(struct crypto_tfm *tfm) return 0; } +static int caam_cra_init_ablkcipher(struct crypto_tfm *tfm) +{ + struct ablkcipher_tfm *ablkcipher_tfm = + crypto_ablkcipher_crt(__crypto_ablkcipher_cast(tfm)); + + ablkcipher_tfm->reqsize = sizeof(struct caam_request); + return caam_cra_init(tfm); +} + static int caam_cra_init_aead(struct crypto_aead *tfm) { crypto_aead_set_reqsize(tfm, sizeof(struct caam_request)); @@ -1239,11 +1839,135 @@ static void caam_exit_common(struct crypto_tfm *tfm) DMA_TO_DEVICE); } +static void caam_cra_exit(struct crypto_tfm *tfm) +{ + caam_exit_common(crypto_tfm_ctx(tfm)); +} + static void caam_cra_exit_aead(struct crypto_aead *tfm) { caam_exit_common(crypto_aead_ctx(tfm)); } +#define template_ablkcipher template_u.ablkcipher +struct caam_alg_template { + char name[CRYPTO_MAX_ALG_NAME]; + char driver_name[CRYPTO_MAX_ALG_NAME]; + unsigned int blocksize; + u32 type; + union { + struct ablkcipher_alg ablkcipher; + } template_u; + u32 class1_alg_type; + u32 class2_alg_type; +}; + +static struct caam_alg_template driver_algs[] = { + /* ablkcipher descriptor */ + { + .name = "cbc(aes)", + .driver_name = "cbc-aes-caam-qi2", + .blocksize = AES_BLOCK_SIZE, + .type = CRYPTO_ALG_TYPE_GIVCIPHER, + .template_ablkcipher = { + .setkey = ablkcipher_setkey, + .encrypt = ablkcipher_encrypt, + .decrypt = ablkcipher_decrypt, + .givencrypt = ablkcipher_givencrypt, + .geniv = "", + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, + }, + { + .name = "cbc(des3_ede)", + .driver_name = "cbc-3des-caam-qi2", + .blocksize = DES3_EDE_BLOCK_SIZE, + .type = CRYPTO_ALG_TYPE_GIVCIPHER, + .template_ablkcipher = { + .setkey = ablkcipher_setkey, + .encrypt = ablkcipher_encrypt, + .decrypt = ablkcipher_decrypt, + .givencrypt = ablkcipher_givencrypt, + .geniv = "", + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .ivsize = DES3_EDE_BLOCK_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, + }, + { + .name = "cbc(des)", + .driver_name = "cbc-des-caam-qi2", + .blocksize = DES_BLOCK_SIZE, + .type = CRYPTO_ALG_TYPE_GIVCIPHER, + .template_ablkcipher = { + .setkey = ablkcipher_setkey, + .encrypt = ablkcipher_encrypt, + .decrypt = ablkcipher_decrypt, + .givencrypt = ablkcipher_givencrypt, + .geniv = "", + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .ivsize = DES_BLOCK_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, + }, + { + .name = "ctr(aes)", + .driver_name = "ctr-aes-caam-qi2", + .blocksize = 1, + .type = CRYPTO_ALG_TYPE_ABLKCIPHER, + .template_ablkcipher = { + .setkey = ablkcipher_setkey, + .encrypt = ablkcipher_encrypt, + .decrypt = ablkcipher_decrypt, + .geniv = "chainiv", + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128, + }, + { + .name = "rfc3686(ctr(aes))", + .driver_name = "rfc3686-ctr-aes-caam-qi2", + .blocksize = 1, + .type = CRYPTO_ALG_TYPE_GIVCIPHER, + .template_ablkcipher = { + .setkey = ablkcipher_setkey, + .encrypt = ablkcipher_encrypt, + .decrypt = ablkcipher_decrypt, + .givencrypt = ablkcipher_givencrypt, + .geniv = "", + .min_keysize = AES_MIN_KEY_SIZE + + CTR_RFC3686_NONCE_SIZE, + .max_keysize = AES_MAX_KEY_SIZE + + CTR_RFC3686_NONCE_SIZE, + .ivsize = CTR_RFC3686_IV_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128, + }, + { + .name = "xts(aes)", + .driver_name = "xts-aes-caam-qi2", + .blocksize = AES_BLOCK_SIZE, + .type = CRYPTO_ALG_TYPE_ABLKCIPHER, + .template_ablkcipher = { + .setkey = xts_ablkcipher_setkey, + .encrypt = ablkcipher_encrypt, + .decrypt = ablkcipher_decrypt, + .geniv = "eseqiv", + .min_keysize = 2 * AES_MIN_KEY_SIZE, + .max_keysize = 2 * AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS, + } +}; + static struct caam_aead_alg driver_aeads[] = { { .aead = { @@ -2406,6 +3130,48 @@ static struct caam_aead_alg driver_aeads[] = { }, }; +static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template + *template) +{ + struct caam_crypto_alg *t_alg; + struct crypto_alg *alg; + + t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL); + if (!t_alg) + return ERR_PTR(-ENOMEM); + + alg = &t_alg->crypto_alg; + + snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); + snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", + template->driver_name); + alg->cra_module = THIS_MODULE; + alg->cra_exit = caam_cra_exit; + alg->cra_priority = CAAM_CRA_PRIORITY; + alg->cra_blocksize = template->blocksize; + alg->cra_alignmask = 0; + alg->cra_ctxsize = sizeof(struct caam_ctx); + alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | + template->type; + switch (template->type) { + case CRYPTO_ALG_TYPE_GIVCIPHER: + alg->cra_init = caam_cra_init_ablkcipher; + alg->cra_type = &crypto_givcipher_type; + alg->cra_ablkcipher = template->template_ablkcipher; + break; + case CRYPTO_ALG_TYPE_ABLKCIPHER: + alg->cra_init = caam_cra_init_ablkcipher; + alg->cra_type = &crypto_ablkcipher_type; + alg->cra_ablkcipher = template->template_ablkcipher; + break; + } + + t_alg->caam.class1_alg_type = template->class1_alg_type; + t_alg->caam.class2_alg_type = template->class2_alg_type; + + return t_alg; +} + static void caam_aead_alg_init(struct caam_aead_alg *t_alg) { struct aead_alg *alg = &t_alg->aead; @@ -2878,6 +3644,8 @@ static int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv) return 0; } +static struct list_head alg_list; + static int dpaa2_caam_probe(struct fsl_mc_device *dpseci_dev) { struct device *dev; @@ -2959,6 +3727,44 @@ static int dpaa2_caam_probe(struct fsl_mc_device *dpseci_dev) } /* register crypto algorithms the device supports */ + INIT_LIST_HEAD(&alg_list); + for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { + struct caam_crypto_alg *t_alg; + struct caam_alg_template *alg = driver_algs + i; + u32 alg_sel = alg->class1_alg_type & OP_ALG_ALGSEL_MASK; + + /* Skip DES algorithms if not supported by device */ + if (!priv->sec_attr.des_acc_num && + ((alg_sel == OP_ALG_ALGSEL_3DES) || + (alg_sel == OP_ALG_ALGSEL_DES))) + continue; + + /* Skip AES algorithms if not supported by device */ + if (!priv->sec_attr.aes_acc_num && + (alg_sel == OP_ALG_ALGSEL_AES)) + continue; + + t_alg = caam_alg_alloc(alg); + if (IS_ERR(t_alg)) { + err = PTR_ERR(t_alg); + dev_warn(dev, "%s alg allocation failed: %d\n", + alg->driver_name, err); + continue; + } + t_alg->caam.dev = dev; + + err = crypto_register_alg(&t_alg->crypto_alg); + if (err) { + dev_warn(dev, "%s alg registration failed: %d\n", + t_alg->crypto_alg.cra_driver_name, err); + kfree(t_alg); + continue; + } + + list_add_tail(&t_alg->entry, &alg_list); + registered = true; + } + for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) { struct caam_aead_alg *t_alg = driver_aeads + i; u32 c1_alg_sel = t_alg->caam.class1_alg_type & @@ -3034,6 +3840,16 @@ static int __cold dpaa2_caam_remove(struct fsl_mc_device *ls_dev) crypto_unregister_aead(&t_alg->aead); } + if (alg_list.next) { + struct caam_crypto_alg *t_alg, *n; + + list_for_each_entry_safe(t_alg, n, &alg_list, entry) { + crypto_unregister_alg(&t_alg->crypto_alg); + list_del(&t_alg->entry); + kfree(t_alg); + } + } + dpaa2_dpseci_disable(priv); dpaa2_dpseci_dpio_free(priv); dpaa2_dpseci_free(priv); diff --git a/drivers/crypto/caam/caamalg_qi2.h b/drivers/crypto/caam/caamalg_qi2.h index bfb3a6416f91..8840721595c8 100644 --- a/drivers/crypto/caam/caamalg_qi2.h +++ b/drivers/crypto/caam/caamalg_qi2.h @@ -170,6 +170,27 @@ struct aead_edesc { struct dpaa2_sg_entry sgt[0]; }; +/* + * ablkcipher_edesc - s/w-extended ablkcipher descriptor + * @src_nents: number of segments in input scatterlist + * @dst_nents: number of segments in output scatterlist + * @iv_dma: dma address of iv for checking continuity and link table + * @qm_sg_bytes: length of dma mapped qm_sg space + * @qm_sg_dma: I/O virtual address of h/w link table + * @sgt: the h/w link table + */ +struct ablkcipher_edesc { + int src_nents; + int dst_nents; + dma_addr_t iv_dma; + int qm_sg_bytes; + dma_addr_t qm_sg_dma; +#define CAAM_QI_MAX_ABLKCIPHER_SG \ + ((CAAM_QI_MEMCACHE_SIZE - offsetof(struct ablkcipher_edesc, sgt)) / \ + sizeof(struct dpaa2_sg_entry)) + struct dpaa2_sg_entry sgt[0]; +}; + /** * caam_flc - Flow Context (FLC) * @flc: Flow Context options @@ -200,7 +221,7 @@ enum optype { * @op_type: operation type * @cbk: Callback function to invoke when job is completed * @ctx: arbit context attached with request by the application - * @edesc: extended descriptor; points to aead_edesc + * @edesc: extended descriptor; points to one of {ablkcipher,aead}_edesc */ struct caam_request { struct dpaa2_fl_entry fd_flt[2];