Dragonblood - attacking WPA3's SAE handshake

Dragonblood: The Attacks That Broke WPA3's SAE Handshake

WPA3 replaced WPA2's pre-shared-key authentication with SAE, the Simultaneous Authentication of Equals. SAE is a password-authenticated key exchange built on the Dragonfly handshake, and its central promise is resistance to offline dictionary attacks: capturing the handshake should tell an observer nothing about the password. WPA2 fails that test, which is why a captured 4-way handshake can be cracked offline.

Dragonblood, published by Mathy Vanhoef and Eyal Ronen in 2019, is a set of attacks showing that SAE's design and its early implementations did not deliver on that promise. The attacks fall into four groups: side-channel leaks that enable an offline dictionary attack after all, downgrade attacks that push a connection back to WPA2 or a weaker curve, a denial-of-service vector against the access point, and a cluster of implementation bugs. This article covers how each works, the CVEs involved, and the Hash-to-Element fix that closed the side channels.

SAE and the Dragonfly Handshake

SAE is a balanced PAKE: both sides hold the same password and prove knowledge of it to each other without revealing it, ending with a shared Pairwise Master Key (PMK). The 4-way handshake that installs session keys still runs afterward, exactly as in WPA2, but the PMK now comes from SAE instead of directly from the passphrase.

The handshake has two phases. First each side converts the password into a Password Element (PWE), a point on the negotiated group (an elliptic curve, or an integer modulo a prime for MODP groups). Then the two sides exchange Commit messages (a scalar and an element derived from the PWE and a random secret), derive a shared secret from them, and exchange Confirm messages (a hash that proves each side computed the same secret).

sequenceDiagram
    participant C as Client (STA)
    participant AP as Access Point
    Note over C,AP: Both hold the shared password
    Note over C,AP: Each derives PWE = password element
    C->>AP: Commit (scalar + element)
    AP->>C: Commit (scalar + element)
    Note over C,AP: Each derives shared secret k,
then the PMK C->>AP: Confirm (hash over k) AP->>C: Confirm (hash over k) Note over C,AP: PMK established, 4-way handshake follows

The SAE Commit/Confirm exchange. The security of the whole handshake depends on the PWE derivation revealing nothing about the password.

The Confirm phase is sound. The problem Dragonblood exposes is entirely in how the PWE is derived from the password, and in what that derivation leaks through timing and memory access patterns.

Hunting and Pecking: the Weak Point

The original SAE specification derives the PWE with an algorithm called Hunting and Pecking. It is a try-and-increment loop: hash the password with a counter and both MAC addresses, reduce the result modulo the group prime, and test whether the result corresponds to a valid group element. If it does, that is the PWE. If not, increment the counter and try again.

# Hunting-and-Pecking (simplified). The iteration count and the
# validity test both depend on the secret password, which is the leak.
found   = false
counter = 1
while counter <= K or not found:
    seed  = KDF(password, counter, max(MAC_A, MAC_B), min(MAC_A, MAC_B))
    value = seed mod p
    if is_quadratic_residue(value):   # branch depends on the password
        if not found:
            PWE   = to_point(value)
            found = true              # a naive impl stops here
    counter += 1

Two properties of this loop leak information:

  • The number of iterations needed before a valid element is found depends on the password (and the MAC addresses). An implementation that stops as soon as it succeeds runs for a password-dependent amount of time.
  • The validity test inside each iteration - a quadratic-residue check for MODP groups, or a square-root / point-decompression branch for elliptic curves - takes a different code path depending on the intermediate value, which itself depends on the password.
graph TD
    START["password + MAC_A + MAC_B"] --> CTR["counter = 1"]
    CTR --> SEED["seed = KDF(password, counter,
MAC_A, MAC_B)"] SEED --> VAL["value = seed mod p"] VAL --> CHK{"valid group
element?"} CHK -->|no: counter += 1| SEED CHK -->|yes| PWE["PWE = derived point"] SEED --> LEAK["Iteration count and internal
branch depend on the password"] LEAK --> PART["Feeds the password
partitioning attack"]

Hunting and Pecking. Both the loop count and the per-iteration branch are functions of the password, so an attacker who can measure either narrows down the password.

The specification tried to blunt the timing leak by requiring at least a fixed minimum number of iterations. That mitigation is incomplete: it hides the total count but not the per-iteration branch behavior, and implementations that took shortcuts reintroduced the count leak.

The Side-Channel Leaks

Dragonblood turns the leaks above into two concrete measurement techniques.

Timing side channel (MODP groups). When the network negotiates a MODP group - integers modulo a prime rather than an elliptic curve - the number of Hunting-and-Pecking iterations varies enough to measure remotely. RFC 5114 groups 22, 23, and 24 are the practical targets. An attacker sends commit frames from different spoofed MAC addresses and times the access point's responses; the response time correlates with how many iterations that MAC address required, which is a function of the password.

Cache side channel (elliptic curves). For ECC groups the iteration-count signal is weak, but the branch inside each iteration is not. Whether the algorithm computes a square root (indicating a valid point) touches different memory, so an attacker running unprivileged code on the same machine as the victim - a phone app, a process on a shared AP - can use a FLUSH+RELOAD cache attack to learn, per iteration, which branch was taken. That per-iteration pattern is tied to the password. This is CVE-2019-9494.

Brainpool curves (the second round). After the first fixes disabled the weak MODP groups, a follow-up showed that the PWE derivation for Brainpool curves still had a measurable timing difference, because the extra reduction steps Brainpool requires reintroduced a secret-dependent branch. This is CVE-2019-13377. A 2020 paper, "Dragonblood is Still Leaking," further demonstrated the cache side channel surviving in shipping devices well after the initial disclosure.

The Password Partitioning Attack

None of the side channels reveal the password directly. What they reveal is how many iterations a given password needed, or which branch it took, for a specific pair of MAC addresses. That is enough to run a password partitioning attack, which is an offline dictionary attack in disguise.

The attacker collects side-channel measurements for several different MAC addresses (spoofing the client address is trivial). Then, offline, for each candidate password in a wordlist, the attacker simulates Hunting and Pecking with those same MAC addresses and computes the iteration counts and branch patterns that password would produce. Any candidate whose simulated behavior does not match the measured behavior is discarded. Each additional measurement partitions the remaining candidates further, and after enough measurements only the correct password survives.

The work is offline and cheap once the measurements are collected. Vanhoef and Ronen estimated that brute-forcing all 8-character lowercase passwords this way costs on the order of $125 in cloud compute, and that dictionary runs are far cheaper. SAE's core promise - no offline dictionary attack - fails against an implementation that leaks the PWE derivation.

Downgrade Attacks

The side channels attack the cryptography. The downgrade attacks attack the negotiation around it, and they need no side-channel measurement at all.

Transition-mode downgrade. WPA3 was designed to coexist with WPA2 during migration. In transition mode, one SSID advertises both WPA3-SAE and WPA2-PSK so old and new clients can both connect. An attacker within range sets up a rogue access point with the same SSID that offers only WPA2, and uses deauthentication or simply a stronger signal to make a WPA3-capable client associate to it. The client falls back to the WPA2 4-way handshake, and the attacker captures enough of it for a standard offline crack. The client briefly detects the anomaly, but not before the handshake material is on the air.

Security-group downgrade. SAE lets the two sides negotiate which group to use. An attacker can forge messages that reject the stronger groups a client offers, pushing both parties onto the weakest group they have in common - for example, a MODP group that is also vulnerable to the timing side channel. This is a downgrade within WPA3 itself, not a fallback to WPA2.

Both downgrades share a root cause: the protection is only as strong as the weakest option the endpoints still accept. A network that offers transition mode is exposed to the WPA2 fallback regardless of how sound its SAE implementation is.

Denial of Service

Deriving the PWE and processing an SAE commit is computationally expensive, especially for elliptic-curve groups where it involves scalar multiplication. SAE includes an anti-clogging mechanism - the access point can demand a token before doing the expensive work - but Dragonblood showed it is not enough. An attacker spoofing many client MAC addresses can flood the access point with commit frames, and the cost of the crypto (and of issuing and checking anti-clogging tokens) can exhaust the AP's CPU, knocking legitimate clients off the network. On resource-constrained access points the flood needs only a handful of forged commits per second to have an effect.

The Dragonblood CVEs

The disclosures span WPA3-SAE and its close relative EAP-pwd, which is an enterprise EAP method that uses the same Dragonfly password-to-element derivation. The SAE entries are the WPA3-Personal ones; the EAP-pwd entries share the underlying flaw but apply to enterprise authentication.

CVE Component Class Summary
CVE-2019-9494 SAE (WPA3) Cache side-channel Secret-dependent branch in the PWE derivation leaks via FLUSH+RELOAD.
CVE-2019-9496 SAE (WPA3) Validation / DoS Missing state validation on SAE confirm lets forged messages crash or desync the peer.
CVE-2019-13377 SAE (WPA3) Timing side-channel Brainpool-curve PWE derivation still leaks timing after the first round of fixes.
CVE-2019-9495 EAP-pwd Cache side-channel EAP-pwd sibling of 9494; same branch leak in the enterprise method.
CVE-2019-9497 EAP-pwd Validation Server does not validate the peer's commit scalar/element (reflection).
CVE-2019-9498 EAP-pwd Validation Server accepts a commit with an invalid curve point.
CVE-2019-9499 EAP-pwd Validation Client accepts an invalid commit, enabling server impersonation.

The timing leak on the MODP groups (22, 23, 24) was addressed by dropping support for those groups rather than by a dedicated CVE; hostapd and wpa_supplicant simply stopped negotiating them.

The Fix: Hash-to-Element

Patching each leak individually was a losing game, as the Brainpool follow-up showed. The durable fix was to replace Hunting and Pecking entirely with a constant-time derivation called Hash-to-Element (H2E), also known as hash-to-curve. H2E maps the password to a group element in a fixed amount of work with no secret-dependent loop and no secret-dependent branch.

# Hash-to-Element (H2E): fixed work, no secret-dependent loop or branch.
u   = KDF(password, ...)      # one pass, constant time
PWE = SSWU(u)                 # constant-time map onto the curve

The core of H2E is a constant-time mapping (the Simplified Shallue-van de Woestijne-Ulas method, SSWU, for the curves WPA3 uses) that takes any input to a valid curve point without branching on whether an intermediate value happened to be a square. Because the work no longer depends on the password, the timing and cache signals that Dragonblood measured disappear.

Hunting and Pecking Hash-to-Element
Loop Variable iterations until success None; single pass
Branch Secret-dependent validity test Constant-time map
Timing leak Yes (count and branch) No
Cache leak Yes (branch) No

The Wi-Fi Alliance made H2E part of later WPA3 releases and mandatory for Wi-Fi 6E and any SAE operation in the 6 GHz band, where Hunting and Pecking is not allowed at all. Alongside H2E, the practical mitigations are: disable the weak MODP groups, require Protected Management Frames (already mandatory in WPA3) to blunt deauthentication-driven downgrades, and where possible drop transition mode in favor of WPA3-only SSIDs.

Where This Stands Today

WPA3 is not broken as a design. The side channels were implementation properties of the original PWE derivation, and H2E removes them. Current access points and clients negotiate H2E by default, and 6 GHz networks are required to use it. Three exposures remain in practice:

  • Old firmware that still supports Hunting and Pecking and the weak groups, especially devices that never received the 2019-2020 patches.
  • Transition-mode SSIDs, which remain downgrade-exposed to WPA2 no matter how current the SAE implementation is, because the WPA2 fallback is the point of transition mode.
  • EAP-pwd deployments, which are less common but carry the same Dragonfly derivation and the same class of bugs.

Auditing your own networks comes down to inventory: which SSIDs advertise WPA3-only, which advertise transition mode, which are still WPA2, and whether the firmware on your access points is recent enough to use H2E.

Auditing WPA3 Exposure with BLEShark Nano

The BLEShark Nano does not run the Dragonblood side channels. The timing and cache attacks require precise measurement against a specific SAE implementation, which is a client-side research technique rather than a capture-device feature. Where the device fits is the inventory and verification work above.

Its WiFi scanner reports the advertised security mode of every access point in range, so you can walk a site and list which SSIDs are WPA3-only, which are running transition mode (and therefore still WPA2-downgradeable), and which are plain WPA2. On networks you own or are authorized to test, its WPA2 handshake and PMKID capture demonstrate exactly what a transition-mode downgrade would hand an attacker: the same crackable WPA2 material, saved as a standard PCAP for your records.

For a larger site, a Shiver mesh of up to 16 BLEShark Nano nodes (ESP-NOW, 20-50m between hops) lets several scan points build one security-mode inventory across a building. In EU configurations, deauthentication is disabled for RED compliance, so downgrade demonstrations that rely on forcing a reconnect are limited to passive observation of natural association events.

BLEShark Nano is intended for authorized security research and education. Scan and capture only on networks you own or have explicit written permission to test.

Get the BLEShark Nano - $36.99+

Back to blog

Leave a comment