Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ipv6: Switch to higher-level SHA-1 functions

There's now a proper SHA-1 API that follows the usual conventions for
hash function APIs: sha1_init(), sha1_update(), sha1_final(), sha1().
The only remaining user of the older low-level SHA-1 API,
sha1_init_raw() and sha1_transform(), is ipv6_generate_stable_address().
I'd like to remove this older API, which is too low-level.

Unfortunately, ipv6_generate_stable_address() does in fact skip the
SHA-1 finalization for some reason. So the values it computes are not
standard SHA-1 values, and it sort of does want the low-level API.

Still, it's still possible to use the higher-level functions sha1_init()
and sha1_update() to get the same result, provided that the resulting
state is used directly, skipping sha1_final().

So, let's do that instead. This will allow removing the low-level API.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Acked-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260123051656.396371-2-ebiggers@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Biggers and committed by
Jakub Kicinski
50234796 62777c80

+13 -8
+13 -8
net/ipv6/addrconf.c
··· 3339 3339 const struct inet6_dev *idev) 3340 3340 { 3341 3341 static DEFINE_SPINLOCK(lock); 3342 - static __u32 digest[SHA1_DIGEST_WORDS]; 3343 - static __u32 workspace[SHA1_WORKSPACE_WORDS]; 3342 + static struct sha1_ctx sha_ctx; 3344 3343 3345 3344 static union { 3346 - char __data[SHA1_BLOCK_SIZE]; 3345 + u8 __data[SHA1_BLOCK_SIZE]; 3347 3346 struct { 3348 3347 struct in6_addr secret; 3349 3348 __be32 prefix[2]; ··· 3367 3368 retry: 3368 3369 spin_lock_bh(&lock); 3369 3370 3370 - sha1_init_raw(digest); 3371 + sha1_init(&sha_ctx); 3372 + 3371 3373 memset(&data, 0, sizeof(data)); 3372 - memset(workspace, 0, sizeof(workspace)); 3373 3374 memcpy(data.hwaddr, idev->dev->perm_addr, idev->dev->addr_len); 3374 3375 data.prefix[0] = address->s6_addr32[0]; 3375 3376 data.prefix[1] = address->s6_addr32[1]; 3376 3377 data.secret = secret; 3377 3378 data.dad_count = dad_count; 3378 3379 3379 - sha1_transform(digest, data.__data, workspace); 3380 + sha1_update(&sha_ctx, data.__data, sizeof(data)); 3380 3381 3382 + /* 3383 + * Note that the SHA-1 finalization is omitted here, and the digest is 3384 + * pulled directly from the internal SHA-1 state (making it incompatible 3385 + * with standard SHA-1). Unusual, but technically okay since the data 3386 + * length is fixed and is a multiple of the SHA-1 block size. 3387 + */ 3381 3388 temp = *address; 3382 - temp.s6_addr32[2] = (__force __be32)digest[0]; 3383 - temp.s6_addr32[3] = (__force __be32)digest[1]; 3389 + temp.s6_addr32[2] = (__force __be32)sha_ctx.state.h[0]; 3390 + temp.s6_addr32[3] = (__force __be32)sha_ctx.state.h[1]; 3384 3391 3385 3392 spin_unlock_bh(&lock); 3386 3393