diff mbox series

[RFC,v2,2/3] ipv6: move from sha1 to blake2s in address calculation

Message ID 20220114142015.87974-3-Jason@zx2c4.com (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series remove remaining users of SHA-1 | expand

Checks

Context Check Description
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 12 maintainers not CCed: andrii@kernel.org kuba@kernel.org kpsingh@kernel.org daniel@iogearbox.net john.fastabend@gmail.com kafai@fb.com songliubraving@fb.com ast@kernel.org dsahern@kernel.org yhs@fb.com yoshfuji@linux-ipv6.org davem@davemloft.net
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: line length of 92 exceeds 80 columns WARNING: line length of 95 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next success VM_Test
bpf/vmtest-bpf-next-PR success PR summary
netdev/tree_selection success Guessing tree name failed - patch did not apply, async

Commit Message

Jason A. Donenfeld Jan. 14, 2022, 2:20 p.m. UTC
BLAKE2s is faster and more secure. SHA-1 has been broken for a long time
now. This also removes some code complexity, and lets us potentially
remove sha1 from lib, which would further reduce vmlinux size. This also
lets us use the secret in the proper field for a secret, rather than the
prepending done in the prior construction.

Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Cc: Fernando Gont <fgont@si6networks.com>
Cc: Erik Kline <ek@google.com>
Cc: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 net/ipv6/addrconf.c | 56 ++++++++++++---------------------------------
 1 file changed, 14 insertions(+), 42 deletions(-)
diff mbox series

Patch

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3eee17790a82..47048aafebd3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -61,7 +61,7 @@ 
 #include <linux/delay.h>
 #include <linux/notifier.h>
 #include <linux/string.h>
-#include <linux/hash.h>
+#include <crypto/blake2s.h>
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
@@ -3224,61 +3224,33 @@  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 union {
-		char __data[SHA1_BLOCK_SIZE];
-		struct {
-			struct in6_addr secret;
-			__be32 prefix[2];
-			unsigned char hwaddr[MAX_ADDR_LEN];
-			u8 dad_count;
-		} __packed;
-	} data;
-
-	struct in6_addr secret;
-	struct in6_addr temp;
 	struct net *net = dev_net(idev->dev);
-
-	BUILD_BUG_ON(sizeof(data.__data) != sizeof(data));
+	const struct in6_addr *secret;
+	struct blake2s_state hash;
+	struct in6_addr proposal;
 
 	if (idev->cnf.stable_secret.initialized)
-		secret = idev->cnf.stable_secret.secret;
+		secret = &idev->cnf.stable_secret.secret;
 	else if (net->ipv6.devconf_dflt->stable_secret.initialized)
-		secret = net->ipv6.devconf_dflt->stable_secret.secret;
+		secret = &net->ipv6.devconf_dflt->stable_secret.secret;
 	else
 		return -1;
 
 retry:
-	spin_lock_bh(&lock);
-
-	sha1_init(digest);
-	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);
-
-	temp = *address;
-	temp.s6_addr32[2] = (__force __be32)digest[0];
-	temp.s6_addr32[3] = (__force __be32)digest[1];
-
-	spin_unlock_bh(&lock);
+	blake2s_init_key(&hash, sizeof(proposal.s6_addr32[2]) * 2, secret, sizeof(*secret));
+	blake2s_update(&hash, (u8 *)&address->s6_addr32[0], sizeof(address->s6_addr32[0]) * 2);
+	blake2s_update(&hash, idev->dev->perm_addr, idev->dev->addr_len);
+	blake2s_update(&hash, (u8 *)&dad_count, sizeof(dad_count));
+	blake2s_final(&hash, (u8 *)&proposal.s6_addr32[2]);
 
-	if (ipv6_reserved_interfaceid(temp)) {
+	if (ipv6_reserved_interfaceid(proposal)) {
 		dad_count++;
-		if (dad_count > dev_net(idev->dev)->ipv6.sysctl.idgen_retries)
+		if (dad_count > net->ipv6.sysctl.idgen_retries)
 			return -1;
 		goto retry;
 	}
 
-	*address = temp;
+	*address = proposal;
 	return 0;
 }