public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/4] ipv6: sr: make SR HMAC __init continue on missing algos
@ 2025-03-10 16:58 Nicolai Stange
  2025-03-10 16:58 ` [PATCH v1 1/4] ipv6: sr: reject unsupported SR HMAC algos with -ENOENT Nicolai Stange
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Nicolai Stange @ 2025-03-10 16:58 UTC (permalink / raw)
  To: David S. Miller, David Ahern
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev,
	linux-kernel, Nicolai Stange

Hi all,

this series prepares for prohibiting any SHA1 usage when booting in FIPS
mode -- SHA1 will be sunset by NIST by the end of 2030 ([1]) and then at
latest, attempts to instantiate it will have to be made to fail with
-ENOENT (in FIPS mode only). Note that distros might want to make this
move downstream today already.

The problem is that the SR HMAC __init, and thus the IPv6 subsys as a whole,
fails to come up upon encountering such an error.

This series makes it to continue upon ENOENTs from the hmac instantiations.

Thanks!

Nicolai

[1] https://www.nist.gov/news-events/news/2022/12/nist-retires-sha-1-cryptographic-algorithm

Nicolai Stange (4):
  ipv6: sr: reject unsupported SR HMAC algos with -ENOENT
  ipv6: sr: factor seg6_hmac_exit()'s per-algo code into separate
    function
  ipv6: sr: factor seg6_hmac_init_algo()'s per-algo code into separate
    function
  ipv6: sr: continue initialization at ENOENT HMAC instantiation
    failures

 net/ipv6/seg6_hmac.c | 141 +++++++++++++++++++++++++------------------
 1 file changed, 81 insertions(+), 60 deletions(-)

-- 
2.47.1


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

* [PATCH v1 1/4] ipv6: sr: reject unsupported SR HMAC algos with -ENOENT
  2025-03-10 16:58 [PATCH v1 0/4] ipv6: sr: make SR HMAC __init continue on missing algos Nicolai Stange
@ 2025-03-10 16:58 ` Nicolai Stange
  2025-03-18  9:02   ` Paolo Abeni
  2025-03-10 16:58 ` [PATCH v1 2/4] ipv6: sr: factor seg6_hmac_exit()'s per-algo code into separate function Nicolai Stange
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Nicolai Stange @ 2025-03-10 16:58 UTC (permalink / raw)
  To: David S. Miller, David Ahern
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev,
	linux-kernel, Nicolai Stange

The IPv6 SR HMAC implementation supports sha1 and sha256, but would
silently accept any other value configured for the ->alg_id -- it just
would fail to create such an HMAC then.

That's certainly fine, as users attempting to configure random ->alg_ids
don't deserve any better.

However, a subsequent patch will enable a scenario where the instantiation
of a supported HMAC algorithm may fail, namely with SHA1 when booted in
FIPS mode.

As such an instantiation failure would depend on the system configuration,
i.e. whether FIPS mode is enabled or not, it would be better to report a
proper error back at configuration time rather than to e.g. silently drop
packets during operation.

Make __hmac_get_algo() to filter algos with ->tfms == NULL, indicating
an instantiation failure. Note that this cannot happen yet at this very
moment, as the IPv6 SR HMAC __init code would have failed then. As said,
it's a scenario enabled only with a subsequent patch.

Make seg6_hmac_info_add() to return -ENOENT to the user in case
__hmac_get_algo() fails to find a matching algo.

Signed-off-by: Nicolai Stange <nstange@suse.de>
---
 net/ipv6/seg6_hmac.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
index bbf5b84a70fc..77bdb41d3b82 100644
--- a/net/ipv6/seg6_hmac.c
+++ b/net/ipv6/seg6_hmac.c
@@ -108,7 +108,7 @@ static struct seg6_hmac_algo *__hmac_get_algo(u8 alg_id)
 	alg_count = ARRAY_SIZE(hmac_algos);
 	for (i = 0; i < alg_count; i++) {
 		algo = &hmac_algos[i];
-		if (algo->alg_id == alg_id)
+		if (algo->alg_id == alg_id && algo->tfms)
 			return algo;
 	}
 
@@ -293,8 +293,13 @@ EXPORT_SYMBOL(seg6_hmac_info_lookup);
 int seg6_hmac_info_add(struct net *net, u32 key, struct seg6_hmac_info *hinfo)
 {
 	struct seg6_pernet_data *sdata = seg6_pernet(net);
+	struct seg6_hmac_algo *algo;
 	int err;
 
+	algo = __hmac_get_algo(hinfo->alg_id);
+	if (!algo || !algo->tfms)
+		return -ENOENT;
+
 	err = rhashtable_lookup_insert_fast(&sdata->hmac_infos, &hinfo->node,
 					    rht_params);
 
-- 
2.47.1


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

* [PATCH v1 2/4] ipv6: sr: factor seg6_hmac_exit()'s per-algo code into separate function
  2025-03-10 16:58 [PATCH v1 0/4] ipv6: sr: make SR HMAC __init continue on missing algos Nicolai Stange
  2025-03-10 16:58 ` [PATCH v1 1/4] ipv6: sr: reject unsupported SR HMAC algos with -ENOENT Nicolai Stange
@ 2025-03-10 16:58 ` Nicolai Stange
  2025-03-10 16:58 ` [PATCH v1 3/4] ipv6: sr: factor seg6_hmac_init_algo()'s " Nicolai Stange
  2025-03-10 16:58 ` [PATCH v1 4/4] ipv6: sr: continue initialization at ENOENT HMAC instantiation failures Nicolai Stange
  3 siblings, 0 replies; 7+ messages in thread
From: Nicolai Stange @ 2025-03-10 16:58 UTC (permalink / raw)
  To: David S. Miller, David Ahern
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev,
	linux-kernel, Nicolai Stange

Move the per-algo cleanup code from seg6_hmac_exit() into a separate
function, the new seg6_hmac_free_algo(), in order to make it accessible
to upcoming error handling code at initialization time.

Make seg6_hmac_free_algo() to clear out ->tfms and ->shashs in order to
make it idempotent.

Otherwise this is a refactoring only, there is no change in behaviour.

Signed-off-by: Nicolai Stange <nstange@suse.de>
---
 net/ipv6/seg6_hmac.c | 48 +++++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
index 77bdb41d3b82..2d7a400e074f 100644
--- a/net/ipv6/seg6_hmac.c
+++ b/net/ipv6/seg6_hmac.c
@@ -355,6 +355,31 @@ int seg6_push_hmac(struct net *net, struct in6_addr *saddr,
 }
 EXPORT_SYMBOL(seg6_push_hmac);
 
+static void seg6_hmac_free_algo(struct seg6_hmac_algo *algo)
+{
+	struct crypto_shash *tfm;
+	struct shash_desc *shash;
+	int cpu;
+
+	if (algo->shashs) {
+		for_each_possible_cpu(cpu) {
+			shash = *per_cpu_ptr(algo->shashs, cpu);
+			kfree(shash);
+		}
+		free_percpu(algo->shashs);
+		algo->shashs = NULL;
+	}
+
+	if (algo->tfms) {
+		for_each_possible_cpu(cpu) {
+			tfm = *per_cpu_ptr(algo->tfms, cpu);
+			crypto_free_shash(tfm);
+		}
+		free_percpu(algo->tfms);
+		algo->tfms = NULL;
+	}
+}
+
 static int seg6_hmac_init_algo(void)
 {
 	struct seg6_hmac_algo *algo;
@@ -423,30 +448,11 @@ int __net_init seg6_hmac_net_init(struct net *net)
 
 void seg6_hmac_exit(void)
 {
-	struct seg6_hmac_algo *algo = NULL;
-	struct crypto_shash *tfm;
-	struct shash_desc *shash;
-	int i, alg_count, cpu;
+	int i, alg_count;
 
 	alg_count = ARRAY_SIZE(hmac_algos);
 	for (i = 0; i < alg_count; i++) {
-		algo = &hmac_algos[i];
-
-		if (algo->shashs) {
-			for_each_possible_cpu(cpu) {
-				shash = *per_cpu_ptr(algo->shashs, cpu);
-				kfree(shash);
-			}
-			free_percpu(algo->shashs);
-		}
-
-		if (algo->tfms) {
-			for_each_possible_cpu(cpu) {
-				tfm = *per_cpu_ptr(algo->tfms, cpu);
-				crypto_free_shash(tfm);
-			}
-			free_percpu(algo->tfms);
-		}
+		seg6_hmac_free_algo(&hmac_algos[i]);
 	}
 }
 EXPORT_SYMBOL(seg6_hmac_exit);
-- 
2.47.1


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

* [PATCH v1 3/4] ipv6: sr: factor seg6_hmac_init_algo()'s per-algo code into separate function
  2025-03-10 16:58 [PATCH v1 0/4] ipv6: sr: make SR HMAC __init continue on missing algos Nicolai Stange
  2025-03-10 16:58 ` [PATCH v1 1/4] ipv6: sr: reject unsupported SR HMAC algos with -ENOENT Nicolai Stange
  2025-03-10 16:58 ` [PATCH v1 2/4] ipv6: sr: factor seg6_hmac_exit()'s per-algo code into separate function Nicolai Stange
@ 2025-03-10 16:58 ` Nicolai Stange
  2025-03-18  9:07   ` Paolo Abeni
  2025-03-10 16:58 ` [PATCH v1 4/4] ipv6: sr: continue initialization at ENOENT HMAC instantiation failures Nicolai Stange
  3 siblings, 1 reply; 7+ messages in thread
From: Nicolai Stange @ 2025-03-10 16:58 UTC (permalink / raw)
  To: David S. Miller, David Ahern
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev,
	linux-kernel, Nicolai Stange

In order to prepare for ignoring certain instantiation failures and
continue with the remaining supported algorithms, factor the per-algo
initialization code into a separate function:
- rename seg6_hmac_init_algo() to seg6_hmac_init_algos() and
- move its per-algo initialization code into a new function,
  seg6_hmac_init_algo().

This is a refactoring only, there is no change in behaviour.

Signed-off-by: Nicolai Stange <nstange@suse.de>
---
 net/ipv6/seg6_hmac.c | 88 ++++++++++++++++++++++++--------------------
 1 file changed, 49 insertions(+), 39 deletions(-)

diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
index 2d7a400e074f..85e90d8d8050 100644
--- a/net/ipv6/seg6_hmac.c
+++ b/net/ipv6/seg6_hmac.c
@@ -380,51 +380,61 @@ static void seg6_hmac_free_algo(struct seg6_hmac_algo *algo)
 	}
 }
 
-static int seg6_hmac_init_algo(void)
+static int seg6_hmac_init_algo(struct seg6_hmac_algo *algo)
 {
-	struct seg6_hmac_algo *algo;
-	struct crypto_shash *tfm;
+	struct crypto_shash *tfm, **p_tfm;
 	struct shash_desc *shash;
-	int i, alg_count, cpu;
+	int cpu, shsize;
 	int ret = -ENOMEM;
 
+	algo->tfms = alloc_percpu(struct crypto_shash *);
+	if (!algo->tfms)
+		goto error_out;
+
+	for_each_possible_cpu(cpu) {
+		tfm = crypto_alloc_shash(algo->name, 0, 0);
+		if (IS_ERR(tfm)) {
+			ret = PTR_ERR(tfm);
+			goto error_out;
+		}
+		p_tfm = per_cpu_ptr(algo->tfms, cpu);
+		*p_tfm = tfm;
+	}
+
+	p_tfm = raw_cpu_ptr(algo->tfms);
+	tfm = *p_tfm;
+
+	shsize = sizeof(*shash) + crypto_shash_descsize(tfm);
+
+	algo->shashs = alloc_percpu(struct shash_desc *);
+	if (!algo->shashs)
+		goto error_out;
+
+	for_each_possible_cpu(cpu) {
+		shash = kzalloc_node(shsize, GFP_KERNEL,
+				     cpu_to_node(cpu));
+		if (!shash)
+			goto error_out;
+		*per_cpu_ptr(algo->shashs, cpu) = shash;
+	}
+
+	return 0;
+
+error_out:
+	seg6_hmac_free_algo(algo);
+	return ret;
+}
+
+static int seg6_hmac_init_algos(void)
+{
+	int i, alg_count;
+	int ret;
+
 	alg_count = ARRAY_SIZE(hmac_algos);
-
 	for (i = 0; i < alg_count; i++) {
-		struct crypto_shash **p_tfm;
-		int shsize;
-
-		algo = &hmac_algos[i];
-		algo->tfms = alloc_percpu(struct crypto_shash *);
-		if (!algo->tfms)
+		ret = seg6_hmac_init_algo(&hmac_algos[i]);
+		if (ret)
 			goto error_out;
-
-		for_each_possible_cpu(cpu) {
-			tfm = crypto_alloc_shash(algo->name, 0, 0);
-			if (IS_ERR(tfm)) {
-				ret = PTR_ERR(tfm);
-				goto error_out;
-			}
-			p_tfm = per_cpu_ptr(algo->tfms, cpu);
-			*p_tfm = tfm;
-		}
-
-		p_tfm = raw_cpu_ptr(algo->tfms);
-		tfm = *p_tfm;
-
-		shsize = sizeof(*shash) + crypto_shash_descsize(tfm);
-
-		algo->shashs = alloc_percpu(struct shash_desc *);
-		if (!algo->shashs)
-			goto error_out;
-
-		for_each_possible_cpu(cpu) {
-			shash = kzalloc_node(shsize, GFP_KERNEL,
-					     cpu_to_node(cpu));
-			if (!shash)
-				goto error_out;
-			*per_cpu_ptr(algo->shashs, cpu) = shash;
-		}
 	}
 
 	return 0;
@@ -436,7 +446,7 @@ static int seg6_hmac_init_algo(void)
 
 int __init seg6_hmac_init(void)
 {
-	return seg6_hmac_init_algo();
+	return seg6_hmac_init_algos();
 }
 
 int __net_init seg6_hmac_net_init(struct net *net)
-- 
2.47.1


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

* [PATCH v1 4/4] ipv6: sr: continue initialization at ENOENT HMAC instantiation failures
  2025-03-10 16:58 [PATCH v1 0/4] ipv6: sr: make SR HMAC __init continue on missing algos Nicolai Stange
                   ` (2 preceding siblings ...)
  2025-03-10 16:58 ` [PATCH v1 3/4] ipv6: sr: factor seg6_hmac_init_algo()'s " Nicolai Stange
@ 2025-03-10 16:58 ` Nicolai Stange
  3 siblings, 0 replies; 7+ messages in thread
From: Nicolai Stange @ 2025-03-10 16:58 UTC (permalink / raw)
  To: David S. Miller, David Ahern
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, netdev,
	linux-kernel, Nicolai Stange

As it currently stands, the IPv6 SR HMAC __init, and thus the IPv6
subsystem's __init, would fail to come up if any of the HMAC algo
instantiations failed.

This used to be fine, as they usually don't. However, that situation will
change, because NIST announced to sunset SHA1 by 2030, and then at latest
instantiations thereof through the cryptomgr will have to made to fail with
-ENOENT when booted in FIPS mode. Note that the sunset date has
implications on certificates' lifetimes for those issued today already, so
distributions might be eager to disable SHA1 in FIPS mode downstream
starting now.

Make seg6_hmac_init_algos() to ignore ENOENT HMAC algo instantiation
errors. Note that in this case, a failed algo will have its ->tfms == NULL,
and __hmac_get_algo() would filter such ones already.

Signed-off-by: Nicolai Stange <nstange@suse.de>
---
 net/ipv6/seg6_hmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
index 85e90d8d8050..4a63ee4dbf7e 100644
--- a/net/ipv6/seg6_hmac.c
+++ b/net/ipv6/seg6_hmac.c
@@ -433,7 +433,7 @@ static int seg6_hmac_init_algos(void)
 	alg_count = ARRAY_SIZE(hmac_algos);
 	for (i = 0; i < alg_count; i++) {
 		ret = seg6_hmac_init_algo(&hmac_algos[i]);
-		if (ret)
+		if (ret && ret != -ENOENT)
 			goto error_out;
 	}
 
-- 
2.47.1


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

* Re: [PATCH v1 1/4] ipv6: sr: reject unsupported SR HMAC algos with -ENOENT
  2025-03-10 16:58 ` [PATCH v1 1/4] ipv6: sr: reject unsupported SR HMAC algos with -ENOENT Nicolai Stange
@ 2025-03-18  9:02   ` Paolo Abeni
  0 siblings, 0 replies; 7+ messages in thread
From: Paolo Abeni @ 2025-03-18  9:02 UTC (permalink / raw)
  To: Nicolai Stange, David S. Miller, David Ahern
  Cc: Eric Dumazet, Jakub Kicinski, Simon Horman, netdev, linux-kernel

On 3/10/25 5:58 PM, Nicolai Stange wrote:
> The IPv6 SR HMAC implementation supports sha1 and sha256, but would
> silently accept any other value configured for the ->alg_id -- it just
> would fail to create such an HMAC then.
> 
> That's certainly fine, as users attempting to configure random ->alg_ids
> don't deserve any better.
> 
> However, a subsequent patch will enable a scenario where the instantiation
> of a supported HMAC algorithm may fail, namely with SHA1 when booted in
> FIPS mode.
> 
> As such an instantiation failure would depend on the system configuration,
> i.e. whether FIPS mode is enabled or not, it would be better to report a
> proper error back at configuration time rather than to e.g. silently drop
> packets during operation.
> 
> Make __hmac_get_algo() to filter algos with ->tfms == NULL, indicating
> an instantiation failure. Note that this cannot happen yet at this very
> moment, as the IPv6 SR HMAC __init code would have failed then. As said,
> it's a scenario enabled only with a subsequent patch.
> 
> Make seg6_hmac_info_add() to return -ENOENT to the user in case
> __hmac_get_algo() fails to find a matching algo.
> 
> Signed-off-by: Nicolai Stange <nstange@suse.de>

Please specify the target tree inside the subj prefix, in this case
'net-next'.

> ---
>  net/ipv6/seg6_hmac.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
> index bbf5b84a70fc..77bdb41d3b82 100644
> --- a/net/ipv6/seg6_hmac.c
> +++ b/net/ipv6/seg6_hmac.c
> @@ -108,7 +108,7 @@ static struct seg6_hmac_algo *__hmac_get_algo(u8 alg_id)
>  	alg_count = ARRAY_SIZE(hmac_algos);
>  	for (i = 0; i < alg_count; i++) {
>  		algo = &hmac_algos[i];
> -		if (algo->alg_id == alg_id)
> +		if (algo->alg_id == alg_id && algo->tfms)
>  			return algo;
>  	}
>  
> @@ -293,8 +293,13 @@ EXPORT_SYMBOL(seg6_hmac_info_lookup);
>  int seg6_hmac_info_add(struct net *net, u32 key, struct seg6_hmac_info *hinfo)
>  {
>  	struct seg6_pernet_data *sdata = seg6_pernet(net);
> +	struct seg6_hmac_algo *algo;
>  	int err;
>  
> +	algo = __hmac_get_algo(hinfo->alg_id);
> +	if (!algo || !algo->tfms)

The above check '!algo->tfms' looks redundant with the previous one.

Thanks,

Paolo


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

* Re: [PATCH v1 3/4] ipv6: sr: factor seg6_hmac_init_algo()'s per-algo code into separate function
  2025-03-10 16:58 ` [PATCH v1 3/4] ipv6: sr: factor seg6_hmac_init_algo()'s " Nicolai Stange
@ 2025-03-18  9:07   ` Paolo Abeni
  0 siblings, 0 replies; 7+ messages in thread
From: Paolo Abeni @ 2025-03-18  9:07 UTC (permalink / raw)
  To: Nicolai Stange, David S. Miller, David Ahern
  Cc: Eric Dumazet, Jakub Kicinski, Simon Horman, netdev, linux-kernel



On 3/10/25 5:58 PM, Nicolai Stange wrote:
> In order to prepare for ignoring certain instantiation failures and
> continue with the remaining supported algorithms, factor the per-algo
> initialization code into a separate function:
> - rename seg6_hmac_init_algo() to seg6_hmac_init_algos() and
> - move its per-algo initialization code into a new function,
>   seg6_hmac_init_algo().
> 
> This is a refactoring only, there is no change in behaviour.
> 
> Signed-off-by: Nicolai Stange <nstange@suse.de>
> ---
>  net/ipv6/seg6_hmac.c | 88 ++++++++++++++++++++++++--------------------
>  1 file changed, 49 insertions(+), 39 deletions(-)
> 
> diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
> index 2d7a400e074f..85e90d8d8050 100644
> --- a/net/ipv6/seg6_hmac.c
> +++ b/net/ipv6/seg6_hmac.c
> @@ -380,51 +380,61 @@ static void seg6_hmac_free_algo(struct seg6_hmac_algo *algo)
>  	}
>  }
>  
> -static int seg6_hmac_init_algo(void)
> +static int seg6_hmac_init_algo(struct seg6_hmac_algo *algo)
>  {
> -	struct seg6_hmac_algo *algo;
> -	struct crypto_shash *tfm;
> +	struct crypto_shash *tfm, **p_tfm;
>  	struct shash_desc *shash;
> -	int i, alg_count, cpu;
> +	int cpu, shsize;
>  	int ret = -ENOMEM;

Please respect the reverse christmas tree order above.

>  
> +	algo->tfms = alloc_percpu(struct crypto_shash *);
> +	if (!algo->tfms)
> +		goto error_out;

Could be simply:
		return ret;

/P


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

end of thread, other threads:[~2025-03-18  9:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-10 16:58 [PATCH v1 0/4] ipv6: sr: make SR HMAC __init continue on missing algos Nicolai Stange
2025-03-10 16:58 ` [PATCH v1 1/4] ipv6: sr: reject unsupported SR HMAC algos with -ENOENT Nicolai Stange
2025-03-18  9:02   ` Paolo Abeni
2025-03-10 16:58 ` [PATCH v1 2/4] ipv6: sr: factor seg6_hmac_exit()'s per-algo code into separate function Nicolai Stange
2025-03-10 16:58 ` [PATCH v1 3/4] ipv6: sr: factor seg6_hmac_init_algo()'s " Nicolai Stange
2025-03-18  9:07   ` Paolo Abeni
2025-03-10 16:58 ` [PATCH v1 4/4] ipv6: sr: continue initialization at ENOENT HMAC instantiation failures Nicolai Stange

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