public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/2] Remove low-level SHA-1 functions
@ 2026-01-23  5:16 Eric Biggers
  2026-01-23  5:16 ` [PATCH net-next 1/2] ipv6: Switch to higher-level " Eric Biggers
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Eric Biggers @ 2026-01-23  5:16 UTC (permalink / raw)
  To: netdev
  Cc: linux-crypto, Ard Biesheuvel, Jason A . Donenfeld, David Ahern,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Eric Biggers

This series updates net/ipv6/addrconf.c to use the regular SHA-1
functions, then removes sha1_init_raw() and sha1_transform().

Please consider these for net-next.

(These were originally patches 25-26 of the series
https://lore.kernel.org/linux-crypto/20250712232329.818226-1-ebiggers@kernel.org/ )

Eric Biggers (2):
  ipv6: Switch to higher-level SHA-1 functions
  lib/crypto: sha1: Remove low-level functions from API

 include/crypto/sha1.h | 10 -------
 lib/crypto/sha1.c     | 63 ++++++++++++-------------------------------
 net/ipv6/addrconf.c   | 21 +++++++++------
 3 files changed, 30 insertions(+), 64 deletions(-)


base-commit: 31d44a37820f00de8156d1c1960dbf1bf04263c2
-- 
2.52.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net-next 1/2] ipv6: Switch to higher-level SHA-1 functions
  2026-01-23  5:16 [PATCH net-next 0/2] Remove low-level SHA-1 functions Eric Biggers
@ 2026-01-23  5:16 ` Eric Biggers
  2026-01-26  3:46   ` David Ahern
  2026-01-23  5:16 ` [PATCH net-next 2/2] lib/crypto: sha1: Remove low-level functions from API Eric Biggers
  2026-01-28  0:10 ` [PATCH net-next 0/2] Remove low-level SHA-1 functions patchwork-bot+netdevbpf
  2 siblings, 1 reply; 5+ messages in thread
From: Eric Biggers @ 2026-01-23  5:16 UTC (permalink / raw)
  To: netdev
  Cc: linux-crypto, Ard Biesheuvel, Jason A . Donenfeld, David Ahern,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Eric Biggers

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>
---
 net/ipv6/addrconf.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7138e0e67991..6db9cf9e2a50 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3337,15 +3337,14 @@ static bool ipv6_reserved_interfaceid(struct in6_addr address)
 static int ipv6_generate_stable_address(struct in6_addr *address,
 					u8 dad_count,
 					const struct inet6_dev *idev)
 {
 	static DEFINE_SPINLOCK(lock);
-	static __u32 digest[SHA1_DIGEST_WORDS];
-	static __u32 workspace[SHA1_WORKSPACE_WORDS];
+	static struct sha1_ctx sha_ctx;
 
 	static union {
-		char __data[SHA1_BLOCK_SIZE];
+		u8 __data[SHA1_BLOCK_SIZE];
 		struct {
 			struct in6_addr secret;
 			__be32 prefix[2];
 			unsigned char hwaddr[MAX_ADDR_LEN];
 			u8 dad_count;
@@ -3366,24 +3365,30 @@ static int ipv6_generate_stable_address(struct in6_addr *address,
 		return -1;
 
 retry:
 	spin_lock_bh(&lock);
 
-	sha1_init_raw(digest);
+	sha1_init(&sha_ctx);
+
 	memset(&data, 0, sizeof(data));
-	memset(workspace, 0, sizeof(workspace));
 	memcpy(data.hwaddr, idev->dev->perm_addr, idev->dev->addr_len);
 	data.prefix[0] = address->s6_addr32[0];
 	data.prefix[1] = address->s6_addr32[1];
 	data.secret = secret;
 	data.dad_count = dad_count;
 
-	sha1_transform(digest, data.__data, workspace);
+	sha1_update(&sha_ctx, data.__data, sizeof(data));
 
+	/*
+	 * Note that the SHA-1 finalization is omitted here, and the digest is
+	 * pulled directly from the internal SHA-1 state (making it incompatible
+	 * with standard SHA-1).  Unusual, but technically okay since the data
+	 * length is fixed and is a multiple of the SHA-1 block size.
+	 */
 	temp = *address;
-	temp.s6_addr32[2] = (__force __be32)digest[0];
-	temp.s6_addr32[3] = (__force __be32)digest[1];
+	temp.s6_addr32[2] = (__force __be32)sha_ctx.state.h[0];
+	temp.s6_addr32[3] = (__force __be32)sha_ctx.state.h[1];
 
 	spin_unlock_bh(&lock);
 
 	if (ipv6_reserved_interfaceid(temp)) {
 		dad_count++;
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net-next 2/2] lib/crypto: sha1: Remove low-level functions from API
  2026-01-23  5:16 [PATCH net-next 0/2] Remove low-level SHA-1 functions Eric Biggers
  2026-01-23  5:16 ` [PATCH net-next 1/2] ipv6: Switch to higher-level " Eric Biggers
@ 2026-01-23  5:16 ` Eric Biggers
  2026-01-28  0:10 ` [PATCH net-next 0/2] Remove low-level SHA-1 functions patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: Eric Biggers @ 2026-01-23  5:16 UTC (permalink / raw)
  To: netdev
  Cc: linux-crypto, Ard Biesheuvel, Jason A . Donenfeld, David Ahern,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Eric Biggers

Now that there are no users of the low-level SHA-1 interface, remove it.

Specifically:

- Remove SHA1_DIGEST_WORDS (no longer used)
- Remove sha1_init_raw() (no longer used)
- Rename sha1_transform() to sha1_block_generic() and make it static
- Move SHA1_WORKSPACE_WORDS into lib/crypto/sha1.c

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
 include/crypto/sha1.h | 10 -------
 lib/crypto/sha1.c     | 63 ++++++++++++-------------------------------
 2 files changed, 17 insertions(+), 56 deletions(-)

diff --git a/include/crypto/sha1.h b/include/crypto/sha1.h
index 27f08b972931..4d973e016cd6 100644
--- a/include/crypto/sha1.h
+++ b/include/crypto/sha1.h
@@ -24,20 +24,10 @@ struct sha1_state {
 	u32 state[SHA1_DIGEST_SIZE / 4];
 	u64 count;
 	u8 buffer[SHA1_BLOCK_SIZE];
 };
 
-/*
- * An implementation of SHA-1's compression function.  Don't use in new code!
- * You shouldn't be using SHA-1, and even if you *have* to use SHA-1, this isn't
- * the correct way to hash something with SHA-1 (use crypto_shash instead).
- */
-#define SHA1_DIGEST_WORDS	(SHA1_DIGEST_SIZE / 4)
-#define SHA1_WORKSPACE_WORDS	16
-void sha1_init_raw(__u32 *buf);
-void sha1_transform(__u32 *digest, const char *data, __u32 *W);
-
 /* State for the SHA-1 compression function */
 struct sha1_block_state {
 	u32 h[SHA1_DIGEST_SIZE / 4];
 };
 
diff --git a/lib/crypto/sha1.c b/lib/crypto/sha1.c
index 52788278cd17..daf18c862fdf 100644
--- a/lib/crypto/sha1.c
+++ b/lib/crypto/sha1.c
@@ -47,11 +47,11 @@ static const struct sha1_block_state sha1_iv = {
 #else
   #define setW(x, val) (W(x) = (val))
 #endif
 
 /* This "rolls" over the 512-bit array */
-#define W(x) (array[(x)&15])
+#define W(x) (workspace[(x)&15])
 
 /*
  * Where do we get the source from? The first 16 iterations get it from
  * the input data, the next mix it from the 512-bit array.
  */
@@ -68,38 +68,24 @@ static const struct sha1_block_state sha1_iv = {
 #define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E )
 #define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E )
 #define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E )
 #define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) ,  0xca62c1d6, A, B, C, D, E )
 
-/**
- * sha1_transform - single block SHA1 transform (deprecated)
- *
- * @digest: 160 bit digest to update
- * @data:   512 bits of data to hash
- * @array:  16 words of workspace (see note)
- *
- * This function executes SHA-1's internal compression function.  It updates the
- * 160-bit internal state (@digest) with a single 512-bit data block (@data).
- *
- * Don't use this function.  SHA-1 is no longer considered secure.  And even if
- * you do have to use SHA-1, this isn't the correct way to hash something with
- * SHA-1 as this doesn't handle padding and finalization.
- *
- * Note: If the hash is security sensitive, the caller should be sure
- * to clear the workspace. This is left to the caller to avoid
- * unnecessary clears between chained hashing operations.
- */
-void sha1_transform(__u32 *digest, const char *data, __u32 *array)
+#define SHA1_WORKSPACE_WORDS 16
+
+static void sha1_block_generic(struct sha1_block_state *state,
+			       const u8 data[SHA1_BLOCK_SIZE],
+			       u32 workspace[SHA1_WORKSPACE_WORDS])
 {
 	__u32 A, B, C, D, E;
 	unsigned int i = 0;
 
-	A = digest[0];
-	B = digest[1];
-	C = digest[2];
-	D = digest[3];
-	E = digest[4];
+	A = state->h[0];
+	B = state->h[1];
+	C = state->h[2];
+	D = state->h[3];
+	E = state->h[4];
 
 	/* Round 1 - iterations 0-16 take their input from 'data' */
 	for (; i < 16; ++i)
 		T_0_15(i, A, B, C, D, E);
 
@@ -117,39 +103,24 @@ void sha1_transform(__u32 *digest, const char *data, __u32 *array)
 
 	/* Round 4 */
 	for (; i < 80; ++i)
 		T_60_79(i, A, B, C, D, E);
 
-	digest[0] += A;
-	digest[1] += B;
-	digest[2] += C;
-	digest[3] += D;
-	digest[4] += E;
-}
-EXPORT_SYMBOL(sha1_transform);
-
-/**
- * sha1_init_raw - initialize the vectors for a SHA1 digest
- * @buf: vector to initialize
- */
-void sha1_init_raw(__u32 *buf)
-{
-	buf[0] = 0x67452301;
-	buf[1] = 0xefcdab89;
-	buf[2] = 0x98badcfe;
-	buf[3] = 0x10325476;
-	buf[4] = 0xc3d2e1f0;
+	state->h[0] += A;
+	state->h[1] += B;
+	state->h[2] += C;
+	state->h[3] += D;
+	state->h[4] += E;
 }
-EXPORT_SYMBOL(sha1_init_raw);
 
 static void __maybe_unused sha1_blocks_generic(struct sha1_block_state *state,
 					       const u8 *data, size_t nblocks)
 {
 	u32 workspace[SHA1_WORKSPACE_WORDS];
 
 	do {
-		sha1_transform(state->h, data, workspace);
+		sha1_block_generic(state, data, workspace);
 		data += SHA1_BLOCK_SIZE;
 	} while (--nblocks);
 
 	memzero_explicit(workspace, sizeof(workspace));
 }
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next 1/2] ipv6: Switch to higher-level SHA-1 functions
  2026-01-23  5:16 ` [PATCH net-next 1/2] ipv6: Switch to higher-level " Eric Biggers
@ 2026-01-26  3:46   ` David Ahern
  0 siblings, 0 replies; 5+ messages in thread
From: David Ahern @ 2026-01-26  3:46 UTC (permalink / raw)
  To: Eric Biggers, netdev
  Cc: linux-crypto, Ard Biesheuvel, Jason A . Donenfeld, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman

On 1/22/26 10:16 PM, Eric Biggers wrote:
> 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>
> ---
>  net/ipv6/addrconf.c | 21 +++++++++++++--------
>  1 file changed, 13 insertions(+), 8 deletions(-)
> 

Acked-by: David Ahern <dsahern@kernel.org>



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next 0/2] Remove low-level SHA-1 functions
  2026-01-23  5:16 [PATCH net-next 0/2] Remove low-level SHA-1 functions Eric Biggers
  2026-01-23  5:16 ` [PATCH net-next 1/2] ipv6: Switch to higher-level " Eric Biggers
  2026-01-23  5:16 ` [PATCH net-next 2/2] lib/crypto: sha1: Remove low-level functions from API Eric Biggers
@ 2026-01-28  0:10 ` patchwork-bot+netdevbpf
  2 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-01-28  0:10 UTC (permalink / raw)
  To: Eric Biggers
  Cc: netdev, linux-crypto, ardb, Jason, dsahern, edumazet, kuba,
	pabeni, horms

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu, 22 Jan 2026 21:16:54 -0800 you wrote:
> This series updates net/ipv6/addrconf.c to use the regular SHA-1
> functions, then removes sha1_init_raw() and sha1_transform().
> 
> Please consider these for net-next.
> 
> (These were originally patches 25-26 of the series
> https://lore.kernel.org/linux-crypto/20250712232329.818226-1-ebiggers@kernel.org/ )
> 
> [...]

Here is the summary with links:
  - [net-next,1/2] ipv6: Switch to higher-level SHA-1 functions
    https://git.kernel.org/netdev/net-next/c/5023479627e3
  - [net-next,2/2] lib/crypto: sha1: Remove low-level functions from API
    https://git.kernel.org/netdev/net-next/c/9ddfabcc1ed8

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-01-28  0:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-23  5:16 [PATCH net-next 0/2] Remove low-level SHA-1 functions Eric Biggers
2026-01-23  5:16 ` [PATCH net-next 1/2] ipv6: Switch to higher-level " Eric Biggers
2026-01-26  3:46   ` David Ahern
2026-01-23  5:16 ` [PATCH net-next 2/2] lib/crypto: sha1: Remove low-level functions from API Eric Biggers
2026-01-28  0:10 ` [PATCH net-next 0/2] Remove low-level SHA-1 functions patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox