Skip to content

Commit 532f419

Browse files
arndbherbertx
authored andcommitted
crypto: stm32 - Try to fix hash padding
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: 8a1012d ("crypto: stm32 - Support for STM32 HASH module") Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 40784d7 commit 532f419

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

drivers/crypto/stm32/stm32-hash.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,9 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev)
553553
{
554554
struct stm32_hash_request_ctx *rctx = ahash_request_ctx(hdev->req);
555555
struct scatterlist sg[1], *tsg;
556-
int err = 0, len = 0, reg, ncp;
556+
int err = 0, len = 0, reg, ncp = 0;
557557
unsigned int i;
558-
const u32 *buffer = (const u32 *)rctx->buffer;
558+
u32 *buffer = (void *)rctx->buffer;
559559

560560
rctx->sg = hdev->req->src;
561561
rctx->total = hdev->req->nbytes;
@@ -620,10 +620,13 @@ static int stm32_hash_dma_send(struct stm32_hash_dev *hdev)
620620
reg |= HASH_CR_DMAA;
621621
stm32_hash_write(hdev, HASH_CR, reg);
622622

623-
for (i = 0; i < DIV_ROUND_UP(ncp, sizeof(u32)); i++)
624-
stm32_hash_write(hdev, HASH_DIN, buffer[i]);
625-
626-
stm32_hash_set_nblw(hdev, ncp);
623+
if (ncp) {
624+
memset(buffer + ncp, 0,
625+
DIV_ROUND_UP(ncp, sizeof(u32)) - ncp);
626+
writesl(hdev->io_base + HASH_DIN, buffer,
627+
DIV_ROUND_UP(ncp, sizeof(u32)));
628+
}
629+
stm32_hash_set_nblw(hdev, DIV_ROUND_UP(ncp, sizeof(u32)));
627630
reg = stm32_hash_read(hdev, HASH_STR);
628631
reg |= HASH_STR_DCAL;
629632
stm32_hash_write(hdev, HASH_STR, reg);

0 commit comments

Comments
 (0)