Recently, news broke about a new possible offline attack on WPA2 using PMKID. To summarize the attack, WPA2 protected APs can end up broadcasting PMKID values which can then be used to offline-brute-force the password.
These PMKID values are computed this way:
PMKID = HMAC-SHA1-128(PMK, "PMK Name" | MAC_AP | MAC_STA)
Where PMK is computed this way (according to this link):
PMK = PBKDF2(HMAC−SHA1, PSK, SSID, 4096, 256)
PSK is the pre-shared key password. All the other values (MAC_AP
, MAC_STA
, SSID
)
are public and known by the attacker.
Thus, given the PMKID, an attacker could perform an
offline brute force attack on the shared password.
Fortunately, my local WiFi network is secure because my password has higher entropy than 128 bit, making it impossible to brute force it. However, this new revelation reminded me that I was still depending on WPA2. Why is that still the case?
None of my devices on my network have official WPA3 support yet. But despite that, I attempted to obtain WPA3 support on each of them.
The post goes into a lot of detail and is a bit long. If you are not interested in the details, you may prefer to only read the summary section near the end.
First, a few notes on WPA3.
WPA3 replaces WPA2-PSK with a key agreement protocol called "SAE" which stands for "Simultaneous Authentication of Equals".
This mode is much better than WPA2-PSK because it:
- has perfect forward secrecy (which WPA2 lacks), and
- protects from offline brute force attacks.
The first advantage is great because it means that even if an attacker gets your password, they can't use it to decrypt any passively recorded communication of yours. With WPA2, such decryption is always possible.
As for the second advantage, most passwords used in WiFi networks (let's be honest, most passwords anywhere) are simple enough that they can be cracked using offline brute force attacks with low cost. Forcing an attack to be online (either via a MITM or via a client trying different passwords) dramatically reduces attacker capabilities.
WPA3 also adds other modes like DPP or OWE. This blog post provides some technical info on how the WPA3 modes work. But in this project, I didn't put any focus on these two.
The comment section of the schneier.com blog post on WPA3 made me a bit cautious though. It seems that Dragonfly, the scheme that SAE bases on, has been the subject of some controversy.
This 2013 summary was linked by one of the commenters, from a time when apparently Dragonfly had been proposed for inclusion into TLS version 1.3.
I actually don't have an idea how relevant this criticism still is. Maybe all of the issues got fixed? Maybe only some of them? A paper that proves the security of SAE has been published since those E-Mails, but I doubt that this resolves all of the points. For example, are the mentioned timing attacks still relevant? No idea.
My current assumption is that if SAE were really totally insecure, there'd have been more prominent writeups about its insecurity, in more drastic words. So maybe SAE is not perfect, but it surely is better than the prior WPA2-PSK exchange protocol.
J-PAKE might have been a better choice but well...
I still think it's worth it to switch to WPA3. If the security issues turn out to be more grave, I can always go back.
On my private WiFi, there are three devices:
- The WiFi AP, using OpenWRT 18.06
- My netbook, using Kubuntu 18.04
- My phone, using LineageOS 14.1 (Android)
All of them use some Linux distro. Even though these distros are highly different from each other (Busybox/musl on OpenWRT, GNU/glibc/systemd on Kubuntu, Android/bionic on LineageOS), they all base their WiFi implementations on the hostap project.
The hostap
project is split in two components:
- hostapd, which lets you run a WiFi access point, and
- wpa_supplicant, which lets you connect to an existing WiFi network
The two components do share code together.
So, does hostap support WPA3 yet? This question has, in fact, been asked twice already on the mailing list: first in March, then again in June.
According to the E-Mails, hostap
from the master
branch should support WPA3.
The last release of hostap
was version 2.6 in 2016, which
is almost 2 years ago. We don't want to wait for a release of hostap
in order to start to use SAE.
In preparation for switching my WiFi to WPA3, I have updated my router from OpenWRT 15.05.01 to the brand-new 18.06 (released on July 30, 2018). It's the first release since the reunification of the OpenWRT project.
According to the file package/network/services/hostapd/Makefile
, OpenWRT 18.06 uses hostapd commit fa617ee6a from April 2018.
The E-Mail by the hostap maintainer saying that WPA3 was supported on master was from March.
So OpenWRT 18.06 should theoretically have a recent enough hostapd.
hostapd's configuration is controlled by a config file with the default name hostapd.conf
.
This commit added
documentation on how SAE support can be added: you'll have to add SAE
to the wpa_key_mgmt
key.
However, OpenWRT doesn't let/want you to change the config files directly. Instead, it uses UCI that acts as a layer between the user and hostapd.conf.
In particular, the OpenWRT system parses the /etc/config/wireless
file and generates the hostapd.conf
for you.
The file that performs this task is stored in package/network/services/hostapd/files/hostapd.sh
.
Let's find out where it's stored on the device:
# find / -name hostapd.sh
/lib/netifd/hostapd.sh
/overlay/upper/lib/netifd/hostapd.sh
/rom/lib/netifd/hostapd.sh
Now, let's find out where the hostapd.conf
file is stored:
# find / -name *hostapd*.conf
/tmp/run/hostapd-phy0.conf
Using grep
, we can determine the currently set config key:
# grep wpa_key_mgmt /tmp/run/hostapd-phy0.conf
wpa_key_mgmt=WPA-PSK
Let's edit /lib/netifd/hostapd.sh
now to add SAE
to this key.
Inside the hostapd_append_wpa_key_mgmt
function, we can conveniently add a line like:
append wpa_key_mgmt "SAE"
Now, we can run /etc/init.d/network restart
to re-run the script.
Note: the command will bring down the network during its operations,
so if you connect to your OpenWRT box through the network,
it might render the ssh session unresponsive.
After all the network is being restarted and ssh uses the network.
But for me the ssh session got responsive again after
waiting a bit.
After the command was run, the wpa_key_mgmt
key should
include SAE
. And indeed it does:
# grep wpa_key_mgmt /tmp/run/hostapd-phy0.conf
wpa_key_mgmt=WPA-PSK SAE
But for some reason, the WiFi network isn't showing up any more.
logread | grep hostapd
is giving us a very suspicious log message:
daemon.err hostapd: Line 32: invalid key_mgmt 'SAE'
Looking at the source code of hostapd, it seems that SAE
is treated
as invalid if CONFIG_SAE
is not set.
Now, do we have to compile OpenWRT? Or is there a way around it?
Fortunately, looking at the Makefile again, we can see that wpad-mesh has this flag enabled.
So we only have to replace our currently installed wpad with wpad-mesh
:
opkg remove wpad-mini
opkg install wpad-mesh
Now let's try /etc/init.d/network restart
again.
Logread now tells us that the WiFi network was set up successfully:
hostapd: wlan0: interface state UNINITIALIZED->ENABLED
After this, the network should have SAE
capabilities.
The next device to migrate over is my netbook. It uses wpa_supplicant which has a .conf file similar to hostapd, and just like with OpenWRT, the user doesn't edit the .conf file directly, but uses an intermediary. For (K)ubuntu, this intermediary is NetworkManager.
Sadly, NetworkManager doesn't seem to support WPA3 yet.
But that shouldn't concern us right now. First, we'll need to get wpa_supplicant
to support SAE.
The Ubuntu 18.04 wpa_supplicant
package is pointing to 2.6,
the last stable release. Therefore we need to update the package locally to a more recent git version.
Debian provides utilities/scripts for compiling existing packages locally and changing the source if desired.
As preparation, one needs to obtain the required build dependencies via sudo apt build-dep wpasupplicant
.
Then, you obtain the source code of the current package via the apt source wpasupplicant
command.
You should probably do this in a dedicated subdirectory because it'll create a lot of files in your pwd
.
After this, one could directly compile the source code using debuild -us -uc -i -I
.
But we want to do our own changes first.
Fortunately, the maintainers of the wpa package have helped us a bit with
their debian/get-orig-source
script.
If the top entry in debian/changelog has a version formatted like:
<anything>+git<number>+<revision>
then the script will automatically download the specified revision from hostapd's
git. As of writing this document the latest hostapd git commit is c773c7d5ddbc8ca031614e1c999b05bec43778aa
.
Let's try it out by adding a version to debian/changelog
:
export VER=2.7+git00+c773c7d5ddbc8ca031614e1c999b05bec43778aa
cd wpa-2.6
DEBFULLNAME=N EMAIL=U@H dch -v 2:$VER
debian/rules get-orig-source
The dch
command will open an interactive editor for you to write something into.
You must write something otherwise dch will terminate and not add the version.
You can just write "SAE" or some keyboard spam, it doesn't matter.
After dch
ran successfully, it tells us that it renamed the directory we are inside.
Debian's guide
on updating packages says that in order to update the source code, one has to
move the debian
directory to the new location. Let's try this by doing:
cd ..
cd ..
mv wpa-$VER/debian debian
rm -r wpa-$VER
tar xvf wpa_$VER.orig.tar.xz
cd wpa-$VER/
mv ../debian .
Then we can try running debuild -us -uc -i -I
but it will give us errors
about patches not applying. Turns out that a lot of patches present in the
debian package were actually backports of master commits onto the stable release.
We should thus remove them:
pushd debian/patches
sed -i "/000.*.patch/d" series
sed -i "/VU-228519\/.*/d" series
sed -i "/wpa_disable_eapol_key_retries.patch/d" series
sed -i "/fix-pem-decryption.patch/d" series
sed -i "/nl80211-Fix.*.patch/d" series
sed -i "/wpa_supplicant-update-MAC-when-driver-detects-a-change.patch/d" series
sed -i "/android_hal_fw_path_change.patch/d" series
popd
export QUILT_PATCHES="debian/patches"
while quilt push; do quilt refresh; done
Remember that in OpenWRT we also needed the CONFIG_SAE
flag.
We'll need it here as well:
echo "CONFIG_SAE=y" >> debian/config/hostapd/linux
echo "CONFIG_SAE=y" >> debian/config/wpasupplicant/linux
Now we can finally build the package:
debuild -us -uc -i -I
And install it using:
dpkg -i wpasupplicant_2.7+git00+c773c7d5ddbc8ca031614e1c999b05bec43778aa_amd64.deb
You can always install the distro provided version using sudo apt install wpasupplicant=<version>
,
with <version>
set to the current version of the distro you have.
Now the new wpasupplicant can be tried out.
We can avoid talking to NetworkManager, which doesn't know about SAE, by talking to wpa_supplicant directly via the wpa_cli command:
sudo wpa_cli status
This prints out the status of the current connection. Most importantly, you can do:
sudo wpa_cli status | grep key_mgmt
And it'll print you the key management mechanism currently used, whether it's SAE, WPA-PSK or something different.
For useful links on wpa_cli
, there is an invaluable list of commands here,
an Arch wiki mention here,
and a guide to use wpa_cli directly to connect to networks here.
wpa_supplicant
maintains a list of stored networks, and uses it to connect one of the available networks.
The stored networks can be listed by:
sudo wpa_cli list_networks
NetworkManager interfaces with wpa_supplicant
by setting up one network and then changing it according
to its own stored settings. Even if NetworkManager knows about multiple networks, it only passes one
to wpa_supplicant
, the one it's supposed to use.
This network has the number 0.
Similarly to hostapd
, wpa_supplicant
uses a key_mgmt
value to list the key algorithms
that should be used to establish a connection.
NetworkManager sets this value as well, as one can observe with:
sudo wpa_cli get_network 0 key_mgmt
We can now set this value to support SAE
only and tell wpa_supplicant
to re-connect
to the network.
sudo wpa_cli set_network 0 key_mgmt SAE
sudo wpa_cli reassociate
If everything went well, we should see usage of SAE:
$ sudo wpa_cli status | grep key_mgmt
key_mgmt=SAE
NetworkManager's tray menu will still show something like WPA2-PSK
,
but this is because we talked to wpa_supplicant
directly :).
This approach isn't viable however, because NetworkManager will
often re-set the key_mgmt
value of the current network.
As we are already patching and self-compiling wpa_supplicant
,
we can easily add one more change: If we change the config
parsing code to treat "WPA-PSK
" as if "WPA-PSK SAE
" were present,
we can trick wpa_supplicant
into opportunistically supporting SAE
,
so supporting SAE
where it is available.
The requirement on WPA2-PSK
is still present however, due to NetworkManager.
Doing this right before our debbuild step will apply the config parsing change to wpa_supplicant:
quilt new sae-if-psk.patch
quilt add wpa_supplicant/config.c
sed -i "s/WPA_KEY_MGMT_PSK;/WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_SAE;/" wpa_supplicant/config.c
quilt refresh
With this change, we can obtain the wanted key_mgmt
without further involvement:
$ sudo wpa_cli status | grep key_mgmt
key_mgmt=SAE
So, the netbook is ported as well!
For reference, these were the full build instructions to for the custom-built wpa_supplicant that I used:
export VER=2.7+git00+c773c7d5ddbc8ca031614e1c999b05bec43778aa
apt source wpasupplicant
cd wpa-2.6
DEBFULLNAME=N EMAIL=U@H dch -v 2:$VER
debian/rules get-orig-source
cd ..
mv wpa-$VER/debian debian
rm -r wpa-$VER
tar xvf wpa_$VER.orig.tar.xz
cd wpa-$VER/
mv ../debian .
pushd debian/patches
sed -i "/000.*.patch/d" series
sed -i "/VU-228519\/.*/d" series
sed -i "/wpa_disable_eapol_key_retries.patch/d" series
sed -i "/fix-pem-decryption.patch/d" series
sed -i "/nl80211-Fix.*.patch/d" series
sed -i "/wpa_supplicant-update-MAC-when-driver-detects-a-change.patch/d" series
sed -i "/android_hal_fw_path_change.patch/d" series
popd
export QUILT_PATCHES="debian/patches"
while quilt push; do quilt refresh; done
echo "CONFIG_SAE=y" >> debian/config/hostapd/linux
echo "CONFIG_SAE=y" >> debian/config/wpasupplicant/linux
quilt new sae-if-psk.patch
quilt add wpa_supplicant/config.c
sed -i "s/WPA_KEY_MGMT_PSK;/WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_SAE;/" wpa_supplicant/config.c
quilt refresh
debuild -us -uc -i -I
The last (and probably hardest) device to be migrated is my phone, the Galaxy S2.
Android uses wpa_supplicant
as well, as observable by this search.
Thus, we might be able to use a similar trick as above to update wpa_supplicant and then
patch it to parse WPA-PSK
just like SAE
.
According to this default.xml entry, this fork of wpa_supplicant is being used.
The wpa_supplicant
fork seems to have been started some long time ago with a fixed version of hostapd and then
patches by upstream got happily happily cherry picked on top.
Seems like it's one of those ugly Android forks you keep hearing about.
But first things first. Before we can update wpa_supplicant
, we need to find out how to compile it and
get our modified version onto the Android device in the first place.
Android, in embedded tradition, doesn't allow you to recompile individual system packages
and exchange them with modified versions. This would have made our life much easier,
but apparently they want you to compile the whole system OS in one piece.
Thus, the first challenge is building LineageOS from source code.
Mostly I was following the device-specific (but auto generated) official build guide.
I'll mostly point out things I did or ran into that weren't mentioned in the guide.
First of all, I fortunately didn't have to obtain the tools adb
and repo
manually,
but could just use their official Ubuntu packages by doing sudo apt install adb repo
.
Also, my device doesn't use fastboot for flashing, so I didn't install it at all.
This way I didn't need to add bin
directories and didn't need any changes in my PATH
env var
either.
During running the brunch i9100
step, I got this error:
build/core/base_rules.mk:183: *** vendor/samsung/galaxys2-common/proprietary: MODULE.TARGET.SHARED_LIBRARIES.libUMP already defined by hardware/samsung/exynos4/hal/libUMP.
After a bit of googling I found this post.
The instructions were a bit outdated, as the entire fimp stuff was gone.
I only had to remove the i9100 from the line in device/samsung/galaxys2-common/extract-files.sh
,
as described in the post.
I also got this error:
flex-2.5.39: loadlocale.c:130: _nl_intern_locale_data: Assertion `cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME[0]))' failed.
This was probably because of me having a german locale on my computer. StackOverflow had a solution for my problem. All I had to do was:
export LC_ALL=C
Once the build is done, it populates the out/target/product/i9100
directory.
First, remember to always do your backups! Without wanting to spoil things, they turned out to be very useful down the line.
How to flash LineageOS is described on this page.
In principle, if LineageOS is already present on the phone, flashing is as easy as:
- copying the zip file to the phone via something like
adb push out/target/product/i9100/lineage-14.1-*-UNOFFICIAL-i9100.zip /sdcard0
- rebooting to the TWRP recovery image e.g. via
adb reboot recovery
- and selecting and installing the zip file via the GUI
However, the LineageOS install that was present on my phone had been using official signing keys. This gave me an "error 7" during installation with an error message like:
Can't install this package on top of incompatible data. Please try another package or run a factory reset
The solution was to run a migration script provided by LineageOS, as described here.
During the process, I also updated my TWRP from 3.1.0-0
to 3.2.3-0
but then
ran into an error of the form:
sysutil: mmap(292396813, R, PRIVATE, 21, 0) failed: Out of memory
sysutil: Map of '/sdcard0/lineage-14.1-20180814-UNOFFICIAL-i9100.zip' failed
Failed to map file '/sdcard0/lineage-14.1-20180814-UNOFFICIAL-i9100.zip'
Error installing zip file '/sdcard0/lineage-14.1-20180814-UNOFFICIAL-i9100.zip'
The problem is known. The workaround I applied was to revert to version 3.1.0-0
.
There are two approaches to verify on the client whether a successful SAE connection has been established.
The first way is to use wpa_cli
, similar to above. To my surprise, LineageOS actually
does ship with wpa_cli
per default.
But attempts to use it end in wpa_cli
not being able to communicate with the wpa_supplicant daemon:
$ adb shell
i9100:/ # wpa_cli
wpa_cli v2.6-devel-7.1.2
Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors
This software may be distributed under the terms of the BSD license.
See README for more details.
Using interface 'wlan0'
Interactive mode
Could not connect to wpa_supplicant: wlan0 - re-trying
My guess is that the problem is an overzealous security policy or something like that. I found this patch for a different device, but when I tried to apply the patch to my device, the patch didn't have any effect.
So I tried a different approach: logcat
. It's Android's unified logging utility.
The Android fork of wpa_supplicant
has been patched to output its log through this utility,
including a log level translation. Really sophisticated :).
We can patch wpa_supplicant
to change the log level of any output we desire,
to appear in logcat output.
One can search logcat output for wpa_supplicant
by doing adb logcat wpa_supplicant:I *:S
(without adb at the front if you are on-device).
However, with default settings this command stays suspiciously silent and only reports some entries of the form:
rfkill: WLAN unblocked
I've been searching for a long time inside the wpa_supplicant
codebase for the cause of this,
but I was looking at the wrong codebase the whole time:
It turns out that wpa_supplicant
logcat logs are being filtered out by the OS,
and that there's a setting in the developer options to turn that off.
Now we have all prerequisites to try out any changes we do to wpa_supplicant
.
I actually ran the full build with an unmodified source and flashed that onto my device
in preparation, because then I'd know where to look when I ran into any issues.
At the branch history of the LineagOS wpa_supplicant
fork, the latest
commit that looks like a backported one is this
one. And indeed, there is an analogon of the commit in the upstream hostap
project, which is this.
That's from October 2017, but full SAE support arrived only in March/April 2018.
Android 9 (pie) had been released a few days ago and maybe it bases on a newer wpa_supplicant
,
so updating that one to add SAE support might be easier.
So, let's try to just use the Android 9 version of wpa_supplicant
:
cd external/wpa_supplicant_8
$ git remote add android-upstream https://android.googlesource.com/platform/external/wpa_supplicant_8
$ git remote update
$ git checkout android-9.0.0_r3
And then rebuild. We then get:
ninja: error: 'lineage/out/target/product/i9100/obj/SHARED_LIBRARIES/android.hardware.wifi.hostapd@1.0_intermediates/export_includes', needed by 'lineage/out/target/product/i9100/obj/EXECUTABLES/hostapd_intermediates/import_includes', missing and no known rule to make it
So that didn't go really well. I then tried to save the approach by taking the Android.mk
from
the working older version:
git checkout 55f469ac1a07c8f134de1c5a8b04b7513c928b64 hostapd/Android.mk
git checkout 55f469ac1a07c8f134de1c5a8b04b7513c928b64 wpa_supplicant/Android.mk
But no avail. You are just getting more and more build errors and you basically need to create a hybrid Android.mk
of the newer and older versions and so I gave up and tried a different approach.
So my next attempt was to go a more direct route: applying all the patches between the last commit from upstream on that repo and the latest master.
git format-patch b488a12948751f57871f09baa345e59b23959a41..c773c7d5ddbc8ca031614e1c999b05bec43778aa
ls *.patch | wc -l
This gives us a giant amount of 791 patches. git am -3
'ing them causes merge conflicts right
in the first few patches and I don't really want to resolve each of them. So doing this directly isn't viable.
If we filter the patch names and are only taking the ones containing SAE
,
we have a more manageable amount: 35.
ls *SAE*.patch | wc -l
I then invoked a command like
git am -3 /path/to/hostap/*SAE*.patch
and fixed the merge conflicts for each patch.
This is a real hack as it relies on the author putting "SAE" into all
the commits relevant for SAE.
It actually turned out that some upstream commits have been missing from the android fork of wpa_supplicant
,
so I had to additionally apply one SAE related patch to fix the build.
Overall it was quite a bit of work but I won't go into more detail.
If you are interested in the result, I've uploaded it to github here.
The branch also includes changes to do more logging and to treat all WPA-PSK network config entries
as if they supported SAE.
After getting the modified wpa_supplicant
to compile successfully,
I flashed it to my phone and tried to connect it to my WiFi network,
hoping that it would build up this connection using SAE
.
However, the phone always chose WPA-PSK
.
After adding some log output, it seemed that this code erased
the SAE
from the protocol list again:
if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
So apparently some "driver" flags weren't set. In this context,
driver just means the back end side of wpa_supplicant
, aka the
way it talks to the kernel/OS/etc. Each driver implements a different
API.
On modern Linuxes, the used driver is NL80211, which talks to the kernel via the header with the same name.
This driver contains the following code:
if (flags & NL80211_FEATURE_SAE)
capa->flags |= WPA_DRIVER_FLAGS_SAE;
And NL80211_FEATURE_SAE
is defined in Linux's nl80211.h.
Running git blame in Linux git for the file gives us this
commit that introduced the value to the header.
The first kernel release that included this commit was 3.8
.
But unfortunately, my phone uses kernel version 3.0.101-lineage-gb7ffe7f2aea
,
and thus it doesn't contain that value in the header.
In fact, the only way the wpa_supplicant
driver compiles is because it ships with a
copy of the nl80211.h
header.
So, it seems that not just wpa_supplicant needs SAE
support, but also the kernel itself.
Android has a rich "alternative kernels" culture, where people create modified kernels
and publish them for others in the community to use them.
So maybe there are kernels that have updated the kernel version to something newer than 3.0
.
An online search turned up a modded kernel called dorimanx
which includes, as it claims, an update to Linux 3.15.
But it seems that the nl80211.h
header doesn't live up to this claim: in dorimanx's version of that header there is no trace of NL80211_FEATURE_SAE
, neither in the enum where it'd normally live, nor the entire file.
So it seems that dorimanx
isn't useful to our purposes and that we have to add SAE support to the kernel ourselves.
Given the experience with wpa_supplicant
,
backporting the patches seems the better solution compared to updating the entire kernel.
The commit that introduced this NL80211_FEATURE_SAE
value is surrounded
by other wifi related commits. This is probably due to the nature of how the Linux kernel
is being developed: an individual developer proposes a patch and sends it to the
maintainer of that specific part of the kernel. The maintainer then reviews it
and if everything is okay, it is being included in a proposed list of
patches that is being sent to Linus Torvalds who then
can include the patch in a future kernel release.
Out of this group of wifi related commits, there are three commits that seem to be relevant enough to motivate a backport:
- mac80211: Take status code as parameter to ieee80211_send_auth (700e8ea6770df311)
- cfg80211: Allow user space to specify non-IEs to SAE Authentication (e39e5b5e7206767a)
- mac80211: Allow station mode SAE to be implemented in user space (6b8ece3a7031523a)
Backporting the first two patches was more or less easy, but the third patch is a bit bigger and it's also been changing code that was modified quite a bit by a refactor that happened since the kernel that my phone was based on, and the kernel that the patch was based on. After a bit of figuring it was possible to backport the third commit as well.
I've uploaded the resulting kernel source to a branch on github.
But for some reason, even though the code seems to be actually enabling the NL80211_FEATURE_SAE
feature,
wpa_supplicant
is not receiving that info. I ran out of time before I could find out why this is the case.
So I gave up, and flashed back the official Lineage OS image. Due to my change to always add SAE
during config file
parsing if WPA-PSK
was present, wpa_supplicant
apparently added SAE
to all WPA-PSK
networks during saving.
But the wpa_supplicant
copy from official Lineage OS couldn't cope with that value and just deleted
all networks with SAE
in their name and thus I would have lost all saved WPA-PSK
networks,
but fortunately, I could just apply the backup :). This is precisely why you should do backups!
I wanted to migrate my WiFi network communication to use SAE, which is a new, more secure authentication mechanism that is part of WPA3.
All of my three devices on my WiFi run a distribution of Linux: OpenWRT, Kubuntu, Android. Also, all of them use the hostap project for WiFi authentication. I could successfully add SAE support to my OpenWRT and Kubuntu devices, but gave up with my Android device.
Only a master version of hostap supports the version of SAE that ships with WPA3. Also, it needs specific SAE build flags to be enabled. Last but not least, it needs to be told to use SAE in its configuration.
Thankfully, OpenWRT already ships a package with hostapd that uses a master version and a SAE build flag. I changed a configuration generation shell script provided by the OS to make hostapd enable SAE for the particular network.
For Kubuntu, I custom-compiled a wpa_supplicant
package using the
master version with the SAE build flag enabled.
I also had to modify config file parsing code of wpa_supplicant
to enable
SAE support.
For my Android phone, I went to great lengths, in comparison to the other two devices,
until I gave up.
I've backported 35 SAE patches to the Android-custom wpa_supplicant
fork.
Then I discovered that for SAE support, kernel 3.8 is required but my kernel was 3.0.
So I backported some kernel patches as well. But no avail: For some reason,
my wpa_supplicant
was still of the opinion that my kernel lacked SAE support. Then I gave up.
During this entire process, I ran into multiple restrictions and issues in my way,
that I didn't feel present in the other Linux distributions.
I worked on the project on and off during the first half of August 2018. Thanks go to @nagisa for proofreading and reviewing my post.
Thanks for the great write up! I really appreciate the effort you put into citing sources.