
fonctionnalité WPA3 pour la puce Wi-Fi d'un MacBook Pro 2014
wl fermé)Apple/Broadcom n'a jamais donné le BCM4360 (14e4:43a0) WPA3. Son seul pilote Linux est le blob fermé broadcom-sta (wl) ; brcmfmac ne peut pas le piloter. Cela ajoute WPA3-SAE + 802.11w PMF complet à ce blob fermé — entièrement depuis le logiciel hôte, aucune source de firmware.
Testé en ondes contre un AP WPA3 uniquement, MFP requis : auth SAE → assoc → 4-way → données CCMP, stable, et résistant aux attaques deauth-flood et SA-Query teardown.
Le blob est un ELF .o non-strippé et relogeable (pas une image firmware finale) — c'est toute la raison pour laquelle cela fonctionne. Nous ne le réécrivons pas ; nous linkons du nouveau C contre lui et redirigeons quelques sites d'appel :
wpa_supplicant exécute SAE + le 4-way (le crypto du blob est SHA-1 seulement ; SAE nécessite SHA-256).wl_cfg80211_hybrid.c, wl_linux.c) fait le pont entre auth/assoc/clés.auth pour qu'il accepte SAE (alg=3).objcopy --globalize-symbol — rendre ~10 fonctions internes du blob appelables depuis notre C.wl_reloc.py — réécrire .rela.text pour que les appels du blob à wlc_recv/wlc_sendauth/wlc_authresp_client atterrissent dans nos hooks __wrap_*.Cela suffit pour piloter les trames SAE sur les ondes, injecter l'IE RSN de wpa_supplicant dans la req d'assoc, installer des clés dérivées de l'espace utilisateur, et ajouter un PMF logiciel (supprimer les deauth non protégées ; SW-CCMP répond aux SA-Queries).
Outils : Ghidra (headless), nm, objdump, strings, un sniffer en mode moniteur (iw + tcpdump).
# 1. The blob ships inside broadcom-sta and is NOT stripped (~4091 syms) -> Ghidra recovers names.
GHIDRA=/opt/ghidra
$GHIDRA/support/analyzeHeadless ./proj wl -import wlc_hybrid.o_amd64 \
-analysisTimeoutPerFile 3600 # auto-analyze, then decompile in the GUI
# 2. Triage what's present BEFORE picking a strategy (absent crypto must move host-side):
nm wlc_hybrid.o_amd64 | grep -iE 'sha256|sae|bip|igtk|mmie' # -> empty here
nm wlc_hybrid.o_amd64 | grep -iE 'wpa|akm|sup|sendauth|key_insert'
# 3. Verify any offset before you patch it (.text vaddr V == file offset V+0x40 in this blob):
objdump -d --start-address=0x47d40 --stop-address=0x47d60 wlc_hybrid.o_amd64
Stratégie : commencer aux points d'entrée cfg80211 dans la colle ouverte (wl_cfg80211_connect, wl_set_auth_type) et suivre les iovars (auth, wpa_auth, wsec) dans le blob. Décompiler ce qu'ils atteignent : la porte AKM (bcmwpa_akm2WPAauth), le FSM join/auth (wlc_join_BSS + l'avanceur auth→assoc à 0x5b79d), le dispatch RX (wlc_recv), et le chemin PMK/clé (wlc_sup_set_pmk, wlc_key_insert). Vérifier chaque adresse avec objdump.
.o relogeable non-strippé (file, nm). Une image firmware strippée ne fonctionnera pas ainsi.set_pmk/key-insert.build.sh (--add-symbol re_auth_advance=..., la liste globalize) et patches/wl_reloc.py (les cibles __wrap_*).wl_linux.c (wlc+0x6a8 txq, bsscfg+0x320 assoc, scb+0x18 bss) — ce sont des dispositions et diffèrent par version de blob.Noyau se bloque complètement pendant SAE, aucune backtrace. Une adresse --add-symbol était décalée d'un chiffre hexa (0x15b79d vs 0x5b79d), atterrissant au milieu d'une instruction → call <garbage> → faute NX. L'indice est l'avertissement de compilation objtool: ... can't find starting instruction ; vérifier que chaque symbole synthétique est un vrai début de fonction.
Impossible de capturer la panique. efi-pstore est cassé sur Apple EFI ; netconsole ne peut pas TX sur une carte USB-ethernet. Diffuser dmesg --follow via SSH vers une deuxième machine — cela vide l'oops avant le redémarrage.
L'AP rejette l'assoc (statut 31, politique MFP). Le blob construit son propre IE RSN PSK/sans MFP. Capturer le sme->ie de wpa_supplicant dans .connect et pointer le tampon IE de la req d'assoc du blob (*(bsscfg+0x320)+0x30) vers celui-ci — satisfait également la vérification RSN-IE du 4-way.
Nécessite les en-têtes noyau, gcc, binutils, python3. Le blob n'est pas dans ce dépôt (propriétaire).
# 1. Get the pristine blob from broadcom-sta 6.30.223.271:
# hybrid-v35_64-nodebug-pcoem-6_30_223_271.tar.gz -> lib/wlc_hybrid.o_amd64
cp /path/to/wlc_hybrid.o_amd64 wl-src/lib/wlc_hybrid.o_amd64.orig
# 2. Build:
./build.sh # -> wl-src/wl.ko (or download it from Releases)
sudo rmmod b43 brcmfmac bcma ssb wl 2>/dev/null # free the card
sudo insmod wl-src/wl.ko # wlan0 appears
NetworkManager pilote WPA3-SAE à travers ce pilote — utilisez simplement l'interface wifi : choisissez votre réseau, entrez le mot de passe, terminé. NM l'enregistre et se reconnecte automatiquement à chaque démarrage. Équivalent en ligne de commande :
nmcli con add type wifi ifname wlan0 con-name w ssid "YOUR_SSID"
nmcli con modify w wifi-sec.key-mgmt sae wifi-sec.psk "YOUR_PASS" 802-11-wireless-security.pmf 3
nmcli con up w # NM does SAE + 4-way + DHCP
(Alternative autonome : sudo ./examples/connect.sh wlan0 examples/wpa3-sae.conf.example.)
sudo dkms/install.sh
Enregistre le pilote avec DKMS (auto-reconstruction lors des mises à jour du noyau), blackliste les pilotes conflictuels dans l'arborescence + le wl standard, et charge le nôtre au démarrage avant NetworkManager. Connectez-vous ensuite depuis l'interface wifi. Détails et le seul piège DKMS : dkms/README.md. Pour une reconstruction manuelle unique, exécutez ./build.sh → wl-src/wl.ko.
Le pilote affiche des débogages verbeux WPA3/PMF par défaut. Silenciez-le à l'exécution (ou définitivement) :
echo 0 | sudo tee /sys/module/wl/parameters/re_verbose # this boot
echo 'options wl re_verbose=0' | sudo tee /etc/modprobe.d/wl-quiet.conf # permanent
wlc_hybrid.o_amd64) est propriétaire Broadcom — procurez-vous le depuis broadcom-sta vous-même. Le wl.ko dans les Releases l'incorpore (même situation que broadcom-sta-dkms de Debian).dmesgL'installation de clé échoue -22 — seulement l'IGTK (BIP, idx 4); le moteur de clés matériel n'a pas de slot BIP. Accepter l'IGTK dans le logiciel ; PTK/GTK s'installent bien et les données circulent.
Le blob ne décrypte jamais les trames de gestion, donc les SA-Queries 802.11w arrivent en texte chiffré. Capturer la PTK et faire AES-CCM dans le logiciel (noyau ccm(aes)) pour lire la requête et émettre une réponse chiffrée.