diff mbox series

hostapd: fallback to psk when generating r0kh/r1kh

Message ID 20220107201936.6704-1-cotequeiroz@gmail.com
State Accepted, archived
Delegated to: David Bauer
Headers show
Series hostapd: fallback to psk when generating r0kh/r1kh | expand

Commit Message

Eneas U de Queiroz Jan. 7, 2022, 8:19 p.m. UTC
The 80211r r0kh and r1kh defaults are generated from the md5sum of
"$mobility_domain/$auth_secret".  auth_secret is only set when using EAP
authentication, but the default key is used for SAE/PSK as well.  In
this case,  auth_secret is empty, and the default value of the key can
be computed from the SSID alone.

Fallback to using $key when auth_secret is empty.  While at it, rename
the variable holding the generated key from 'key' to 'ft_key', to avoid
clobbering the PSK.

Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
---

This should be cherry-picked to 21.02 as well.

 package/network/services/hostapd/files/hostapd.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Eneas U de Queiroz Feb. 18, 2022, 1:15 p.m. UTC | #1
I have sent this a while ago.  Can anyone review this (Felix, as the
author of r0kh/r1kh generator?).

On Fri, Jan 7, 2022 at 5:19 PM Eneas U de Queiroz <cotequeiroz@gmail.com> wrote:
>
> The 80211r r0kh and r1kh defaults are generated from the md5sum of
> "$mobility_domain/$auth_secret".  auth_secret is only set when using EAP
> authentication, but the default key is used for SAE/PSK as well.  In
> this case,  auth_secret is empty, and the default value of the key can
> be computed from the SSID alone.
>
> Fallback to using $key when auth_secret is empty.  While at it, rename
> the variable holding the generated key from 'key' to 'ft_key', to avoid
> clobbering the PSK.
>
> Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
> ---
>
> This should be cherry-picked to 21.02 as well.
>
>  package/network/services/hostapd/files/hostapd.sh | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh
> index d9d5f34877..e00fc21cd9 100644
> --- a/package/network/services/hostapd/files/hostapd.sh
> +++ b/package/network/services/hostapd/files/hostapd.sh
> @@ -876,10 +876,10 @@ hostapd_set_bss_options() {
>                                 set_default pmk_r1_push 0
>
>                                 [ -n "$r0kh" -a -n "$r1kh" ] || {
> -                                       key=`echo -n "$mobility_domain/$auth_secret" | md5sum | awk '{print $1}'`
> +                                       ft_key=`echo -n "$mobility_domain/${auth_secret:-${key}}" | md5sum | awk '{print $1}'`
>
> -                                       set_default r0kh "ff:ff:ff:ff:ff:ff,*,$key"
> -                                       set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$key"
> +                                       set_default r0kh "ff:ff:ff:ff:ff:ff,*,$ft_key"
> +                                       set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$ft_key"
>                                 }
>
>                                 [ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N"


So that one can grasp a bit better what this is about--the commit
message was under par--see this post:

https://forum.openwrt.org/t/802-11r-fast-transition-how-to-understand-that-ft-works/110920/81?u=cotequeiroz

Basically, if you have ieee80211r=1, ft_psk_generate_local=0, and have
not setup r0kh or r1kh, then hostapd.sh will generate a 128-bit key
from the 2-byte mobility domain (defaults to the first 2 byes of the
SSID md5sum) and the auth_secret.

The intention of the script originally was to support just EAP, so it
uses the auth_secret to generate a key.  However, it is possible
(ft_psk_generate_local does not work with SAE) to use generated keys
when using PSK, in which case auth_secret will not be ordinarily set,
and the default key can be trivially computed.

Cheers,

Eneas
David Bauer Feb. 18, 2022, 6:15 p.m. UTC | #2
Hi Eneas,

On 1/7/22 21:19, Eneas U de Queiroz wrote:
> The 80211r r0kh and r1kh defaults are generated from the md5sum of
> "$mobility_domain/$auth_secret".  auth_secret is only set when using EAP
> authentication, but the default key is used for SAE/PSK as well.  In
> this case,  auth_secret is empty, and the default value of the key can
> be computed from the SSID alone.
> 
> Fallback to using $key when auth_secret is empty.  While at it, rename
> the variable holding the generated key from 'key' to 'ft_key', to avoid
> clobbering the PSK.

Just so i get this right - This means the same configuration is 
incompatible between firmware containing this commit and firmware that 
does not? In this case i would not pick it it 21.02.

Otherwise LGTM.

Best
David

> 
> Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
> ---
> 
> This should be cherry-picked to 21.02 as well.
> 
>   package/network/services/hostapd/files/hostapd.sh | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh
> index d9d5f34877..e00fc21cd9 100644
> --- a/package/network/services/hostapd/files/hostapd.sh
> +++ b/package/network/services/hostapd/files/hostapd.sh
> @@ -876,10 +876,10 @@ hostapd_set_bss_options() {
>   				set_default pmk_r1_push 0
>   
>   				[ -n "$r0kh" -a -n "$r1kh" ] || {
> -					key=`echo -n "$mobility_domain/$auth_secret" | md5sum | awk '{print $1}'`
> +					ft_key=`echo -n "$mobility_domain/${auth_secret:-${key}}" | md5sum | awk '{print $1}'`
>   
> -					set_default r0kh "ff:ff:ff:ff:ff:ff,*,$key"
> -					set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$key"
> +					set_default r0kh "ff:ff:ff:ff:ff:ff,*,$ft_key"
> +					set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$ft_key"
>   				}
>   
>   				[ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N"
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Eneas U de Queiroz Feb. 18, 2022, 7:34 p.m. UTC | #3
Hi David

Thanks for looking into this.

On Fri, Feb 18, 2022 at 3:15 PM David Bauer <mail@david-bauer.net> wrote:

> Just so i get this right - This means the same configuration is
> incompatible between firmware containing this commit and firmware that
> does not? In this case i would not pick it it 21.02.

TLDR: For the use case that was intended, it does not; it will
intentionally break the insecure setup.

Here's the commit message that introduced the defaults:

21eb0a5aa3 hostapd: add default values for r0kh/r1kh

This allows WPA enterprise roaming in the same mobility domain without any
manual key configuration (aside from radius credentials)

My understanding is that the intention was to use this for EAP only.
However, the key gets set even if PSK is used.  In that case it will
have an unset 'auth_secret', and that's where this becomes a security
issue.
The FT key is derived from "$mobility_domain/$auth_secret".  If
'auth_secret' is null, then the key is computed from
"$mobility_domain/" only, and 'mobility_domain' itself is computed
from the SSID by default.  At the end, you have an easy, working setup
with a default FT key that can be computed from just the SSID--and
nothing wrong is visible from the user POV.

There are several ways of fixing this: (1) don't compute r0kh/r1kh if
not using EAP.
(2) Use the PSK if auth_secret is unset.  (3) warn the user that a key
has not been set, but keep things as they are.

I like (2) because it is useful.  You can get FT working with WPA3-SAE
just by turning 802.11r on and turning off ft_psk_generate_local,
without having to set up the key.

Can there be breakage? Yes, and it is intended.  It'll break the
insecure PSK/FT default setup I described above, when you have some AP
running with the fix and some without it.

EAP setups will not be affected: even if 'key' is set but
'auth_secret' is unset (a possible breakage scenario), the code in
line 682[1] will set 'auth_secret'  from 'key' if the former is empty:
[ -n "$auth_secret" ] || json_get_var auth_secret key
So you can't have an EAP setup with 'auth_secret' unset and 'key' set.

(1) will create the same breakage, without adding anything useful.

Cheers,

Eneas

[1] https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=package/network/services/hostapd/files/hostapd.sh;h=d9d5f348775debade847f267b1ca1dc86444e41d;hb=HEAD#l682
diff mbox series

Patch

diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh
index d9d5f34877..e00fc21cd9 100644
--- a/package/network/services/hostapd/files/hostapd.sh
+++ b/package/network/services/hostapd/files/hostapd.sh
@@ -876,10 +876,10 @@  hostapd_set_bss_options() {
 				set_default pmk_r1_push 0
 
 				[ -n "$r0kh" -a -n "$r1kh" ] || {
-					key=`echo -n "$mobility_domain/$auth_secret" | md5sum | awk '{print $1}'`
+					ft_key=`echo -n "$mobility_domain/${auth_secret:-${key}}" | md5sum | awk '{print $1}'`
 
-					set_default r0kh "ff:ff:ff:ff:ff:ff,*,$key"
-					set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$key"
+					set_default r0kh "ff:ff:ff:ff:ff:ff,*,$ft_key"
+					set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$ft_key"
 				}
 
 				[ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N"