lib/crypto: sha1: Explicitly specify alignment of sha1_ctx::buf
PATCH 1/1 lib/crypto: sha1: Explicitly specify alignment of sha1_ctx::buf
__sha1_final() writes a __be64 to &ctx->buf[56] using a plain write. That assumes that the alignment of buf is at least that of __be64. It is, since it immediately follows a u64 field. However, to make this assumption explicit it's best to specify the field alignment explicitly too, like what is done in the corresponding SHA-2 and MD5 structs.
--- include/crypto/sha1.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/crypto/sha1.h +1 -1
@@ -38,11 +38,11 @@ struct sha1_block_state {* @buf: partial block buffer; bytecount % SHA1_BLOCK_SIZE bytes are valid */ struct sha1_ctx {struct sha1_block_state state;u64 bytecount; -u8 buf[SHA1_BLOCK_SIZE ]; +u8 buf[SHA1_BLOCK_SIZE ]__aligned(__alignof__(__be64)) ; };/** * sha1_init() - Initialize a SHA-1 context for a new message * @ctx: the context to initialize
base-commit: 6bc9effb4cbf9b6eba0f51aba1c8893dfd4c8100
Signature · 1 line
2.53.0
Quoted 16 lines · Eric Biggers
__sha1_final()writes a__be64to &ctx->buf[56] using a plain write. That assumes that the alignment of buf is at least that of__be64. It is, since it immediately follows a u64 field. However, to make this assumption explicit it's best to specify the field alignment explicitly too, like what is done in the corresponding SHA-2 and MD5 structs.Signed-off-by Eric Biggers <[email protected]>--- include/crypto/sha1.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)include/crypto/sha1.h +0
-0
include/crypto/sha1.h struct sha1_block_state { · line 44
Quoted 8 lines
include/crypto/sha1.h +1
-1@@ -38,11 +38,11 @@ struct sha1_block_state {* @buf: partial block buffer; bytecount % SHA1_BLOCK_SIZE bytes are valid */ struct sha1_ctx {struct sha1_block_state state;u64 bytecount; -u8 buf[SHA1_BLOCK_SIZE ]; +u8 buf[SHA1_BLOCK_SIZE ]__aligned(__alignof__(__be64)) ; };
Surprisingly, this patch actually breaks the build on 32-bit x86. The static assertions in crypto/sha1.c that verify the consistency of 'struct sha1_ctx' and 'struct sha1_state' start failing. gcc puts bytecount and buf at offsets 20 and 28 in the struct. I.e., it puts the u64 field on only a 4-byte boundary. However, __alignof__(__be64) actually returns 8, causing the offset of buf to change from 28 to 32. (The result is the same if __alignof__(u64) is used instead.)
Apparently __alignof__ returns the "preferred alignment". But what we want is "minimum alignment". Which is C11's _Alignof, which was deprecated in C23 and replaced with "alignof". Sigh.
Probably best to just keep this as-is until we can get drivers/crypto/ migrated off of 'struct sha1_state' and remove that.
- Eric