Trying to deploy WPA3 on my home network
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 (
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.
WPA3 is great
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.
WPA3 is maybe not great?
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.
All paths lead to hostap
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.
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.
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
This commit added
documentation on how SAE support can be added: you'll have to add
SAE to the
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
file and generates the
hostapd.conf for you.
The file that performs this task is stored in
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
grep, we can determine the currently set config key:
# grep wpa_key_mgmt /tmp/run/hostapd-phy0.conf wpa_key_mgmt=WPA-PSK
/lib/netifd/hostapd.sh now to add
SAE to this key.
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
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
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
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.
Obtaining wpa_supplicant that supports 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
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
If the top entry in debian/changelog has a version formatted like:
then the script will automatically download the specified revision from hostapd's
git. As of writing this document the latest hostapd git commit is
Let's try it out by adding a version to
export VER=2.7+git00+c773c7d5ddbc8ca031614e1c999b05bec43778aa cd wpa-2.6 DEBFULLNAME=N EMAIL=U@H dch -v 2:$VER debian/rules get-orig-source
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.
dch ran successfully, it tells us that it renamed the directory we are inside.
on updating packages says that in order to update the source code, one has to
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
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>,
<version> set to the current version of the distro you have.
Convincing wpa_supplicant to use SAE
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.
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
wpa_supplicant, the one it's supposed to use.
This network has the number 0.
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
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
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 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.
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
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
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
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
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))' 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:
Once the build is done, it populates the
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.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
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 <email@example.com> 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
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.
Adding SAE support to wpa_supplicant
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
so updating that one to add SAE support might be easier.
So, let's try to just use the Android 9 version of
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_LIBRARIESfirstname.lastname@example.org_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
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
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
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
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.
Entering Kernel space in 3, 2, 1
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
However, the phone always chose
After adding some log output, it seemed that this code erased
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
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;
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
But unfortunately, my phone uses kernel version
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
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
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
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
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
WPA-PSK was present,
wpa_supplicant apparently added
SAE to all
WPA-PSK networks during saving.
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
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
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
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,
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.