Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751424AbdILJhJ (ORCPT ); Tue, 12 Sep 2017 05:37:09 -0400 Received: from mout.kundenserver.de ([217.72.192.75]:61513 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751373AbdILJhH (ORCPT ); Tue, 12 Sep 2017 05:37:07 -0400 From: Arnd Bergmann To: Lionel Debieve Cc: Arnd Bergmann , Herbert Xu , "David S. Miller" , Maxime Coquelin , Alexandre Torgue , linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] crypto: stm32 - Try to fix hash padding Date: Tue, 12 Sep 2017 11:35:39 +0200 Message-Id: <20170912093553.2580986-2-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170912093553.2580986-1-arnd@arndb.de> References: <20170912093553.2580986-1-arnd@arndb.de> X-Provags-ID: V03:K0:AJkvj2x9HxjC7RGwXlK5bQ5Tjcu3QZRmWOuiPiIX5kPdYxi312W PHa2lxYpPGv9fSh9gF506a3Kxt7/YssSDBj4oxB3kC9VwQ+FDVEoAGlIZeB2T1tNQ3B9vxG MYS6JKvRIQGW297HNs5yeWLUueqVYxC6c6PaHyk+wXTZfa+jwN4iiFVNqkGtHSYI3DBDoT/ W8MFTQ5HdYZy9G1ybHWvQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:9Au2K2g0QHQ=:tm11RMAdi8rsEIylyuv2Ct ze+IbsZUj856PEv0HeArX9PPH44gFKTqlyhThBIeiIBKTXM0XOsMu00tAxc9I2lmI8rKpL+fv Efr0pWz7R+v+oowXj8yaD5hua50FRatXpiEd2/xv7AZdi0YeYje+iOcJ4gR34jeXPc8xlb5Mb ivOTxuYDRlgquRE61f1US8BdKjdnTXf+Lx03/ubkRjNGp+35bYHjB8vxvFP0v3dMnzucqg3Ze /Ej2vMnfYiZVMNUWAikI17M1TO4plRIooO0Q9r1AN36B4el+l7VxaeGMtA8JQQurpd2rRf5HC MhSNQVig5Um/XcQrDr73dqh+feBAOxchiUbOF255DmVLZTrkDJdauZs+WEtlD5NZJb9ErESQ8 rNrinBdu4Knjr4cPHkMNPhDGRJPIJTlAo9eSr7LlJ89GmMUlwH71ufliOhS1yTfQ/2mtNbCn6 OLpyQXTDg9VEzwsZCDq/52s6pr4VY533Gloi7UQ02DWXsIl7QlWkRaw/PBJtTgzAqLkoR5bJk Ic0JgitJE5ZTuNfl6r9oV5eUMuIbYN6zPk0eCoV2L80yrkd1ng6n+7Eb6h5ETgD1AobZHM3Wm 2/1woIAQ4MNstRdy7+xXLzlaW3UOhXHFL4HB+vLncjj44V6hfmlRcu97ZTG6jS1iBTSI1H4T0 Ca9hwe8tVBDCkQWMuG+ul+XiEa2Ei44EJ317keMI/XLZL3MtDvAQMMng33KQeEir+wihvICHg ULN1gDtgWjqCrMkKL60fBs7fPd58r7G5W0c/6w== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3017 Lines: 77 gcc warns that the length for the extra unaligned data in the hash function may be used unaligned. In theory this could happen if we pass a zero-length sg_list, or if sg_is_last() was never true: In file included from drivers/crypto/stm32/stm32-hash.c:23: drivers/crypto/stm32/stm32-hash.c: In function 'stm32_hash_one_request': include/uapi/linux/kernel.h:12:49: error: 'ncp' may be used uninitialized in this function [-Werror=maybe-uninitialized] #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) Neither of these can happen in practice, so the warning is harmless. However while trying to suppress the warning, I noticed multiple problems with that code: - On big-endian kernels, we byte-swap the data like we do for register accesses, however this is a data stream and almost certainly needs to use a single writesl() instead of series of writel() to give the correct hash. - If the length is not a multiple of four bytes, we skip the last word entirely, since we write the truncated length using stm32_hash_set_nblw(). - If we change the code to round the length up rather than down, the last bytes contain stale data, so it needs some form of padding. This tries to address all four problems, by correctly initializing the length to zero, using endian-safe copy functions, adding zero-padding and passing the padded length. I have done no testing on this patch, so please review carefully and if possible test with an unaligned length and big-endian kernel builds. Fixes: 8a1012d3f2ab ("crypto: stm32 - Support for STM32 HASH module") Signed-off-by: Arnd Bergmann --- drivers/crypto/stm32/stm32-hash.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c index 3c23a23e9ee5..b2ed2bccdb66 100644 --- a/drivers/crypto/stm32/stm32-hash.c +++ b/drivers/crypto/stm32/stm32-hash.c @@ -553,9 +553,9 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev) { struct stm32_hash_request_ctx *rctx = ahash_request_ctx(hdev->req); struct scatterlist sg[1], *tsg; - int err = 0, len = 0, reg, ncp; + int err = 0, len = 0, reg, ncp = 0; unsigned int i; - const u32 *buffer = (const u32 *)rctx->buffer; + u32 *buffer = (void *)rctx->buffer; rctx->sg = hdev->req->src; rctx->total = hdev->req->nbytes; @@ -620,10 +620,13 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev) reg |= HASH_CR_DMAA; stm32_hash_write(hdev, HASH_CR, reg); - for (i = 0; i < DIV_ROUND_UP(ncp, sizeof(u32)); i++) - stm32_hash_write(hdev, HASH_DIN, buffer[i]); - - stm32_hash_set_nblw(hdev, ncp); + if (ncp) { + memset(buffer + ncp, 0, + DIV_ROUND_UP(ncp, sizeof(u32)) - ncp); + writesl(hdev->io_base + HASH_DIN, buffer, + DIV_ROUND_UP(ncp, sizeof(u32))); + } + stm32_hash_set_nblw(hdev, DIV_ROUND_UP(ncp, sizeof(u32))); reg = stm32_hash_read(hdev, HASH_STR); reg |= HASH_STR_DCAL; stm32_hash_write(hdev, HASH_STR, reg); -- 2.9.0