Before we about WPA3, Have a look at the WPA2 authentication and see how the PMK gets generated in WPA2 and know what is the weakness of the WPA2-PSK. You can have a look my earlier post from the link WPA2 4-way Handshake, WPA2 PMF 4-way Handshake to understand the limitations in the WPA2.
In the WPA2-PSK we do have a common PMK that is being generated. This PMK is same for all the clients, and it is also easy to get this PMK through the 4-way handshake with the sniffer captures with known SSID and passphrase.
What is new in the WPA3?
Our final goal here is to generate the PMK.
WPA3 will replace the PSK with SAE( Simultaneous Authentication of Equals (SAE) ). In WPA3 each client will have a different PMK that is being generated using the dragonfly frame exchange. It is not possible to get the PMK even if we capture the 4-way handshake.
SAE is based on Elliptic Curve Diffie–Hellman key exchange. Advantage of using the Diffie–Hellman is that both the parties will generate the public/private key pair,. Diffie–Hellman key exchange establishes a shared secret between two parties that can be used for secret communication for exchanging data. Below diagram shows the DH algorithm concept.

In the above figure both parties generate public and private keys and public keys are exchanged, but not their private keys. And both of them agree upon the common shared sceret.
WPA3 is also uses the similar method , but it uses Elliptic curve cryptography Diffie Helmen key exchange, and it is not an easy task to find out the shared secret that is being generated without the private keys. And every time there will be new private keys gets generated, so perfect forward secrecy is given.
An elliptic curve is the set of points that satisfy a specific mathematical equation. Elliptic curve looks like the below picture.

The below equation satisfies the Elliptic curve.
Y^2=x^3+a.x+b (modulo p)
ECC that we are going to use for this DH group 19.
y^2 = x^3 – 3 x + b
WPA3 Dragon Fly Key Exchange
The below are the steps involved in Generating the PMK for WPA3 Authentication. We will go through the each step in the post.
- Password to PWE & Public Commit X , Commit Y point Generation
- COMMIT Exchange
- Confirm Exchange
- Setting PMK
Step 1 : Password to PWE
Observe the below frame exchange on the WPA3 authentication. If you have trouble understanding the post , you can refer the RFC-7664

Below are the steps involved in the WPA3.
1) A point, G, on the elliptic curve, which serves as a generator for the ECC group. Each group gas a proper Generator G with point X and Y, and we have a largest Prime number selected for this group. Here we use DH-group-19. You can refer RFC5903 for the fixed input that DH-19 NIST P-256 expects for the program.
2) Prior to beginning the exchange of information, the peers must derive a secret element, called the Password Element (PE). PE is a [x,y] point that gets generated on the elliptic curve.
3) To get the PE, we need a seed. The seed will generated from the password, MAC Addresses of the entities (AP and Client) counter and few other key derivation functions. This seed value will be looped in a hunting and pecking procedure to generate the PE i.e [X,Y].
4) Hunting-and-pecking loop used to find the PE for a given password ensures that at least k iterations are always performed. Here we will run for 40 iterations in WPA3 to generate the PE.
I am pasting the Algorithm to know how this procedure works to generate the PE.
5) The identities are passed to the max() and min() functions to provide the necessary ordering of the inputs to function H(), while still allowing for a peer-to-peer exchange where both Alice and Bob each view themselves as the “initiator” of the exchange.
I am pasting the supplicant log from the AP side and observe that it will always run for 40 loops in supplicant code to get the password element and it will be the same procedure at the client as well.

PWE Generation after 40 loops Supplicant log on Client Side
SAE: counter = 039
SAE: pwd-seed – hexdump(len=32): c5 b3 34 7f e7 bf 2d 13 c4 44 f1 13 08 13 86 3d 6a d4 f0 c9 f2 86 a6 54 e9 ea ab b0 20 fb f8 2f
SAE: pwd-value – hexdump(len=32): eb 66 40 3b 99 d8 66 31 4c 1d 3e 9c 3d 5f e5 fa d5 79 6f 5b 07 f0 81 1b c5 53 45 e6 36 e5 92 ea
SAE: pwd-seed result 1 found=0xff
SAE: counter = 040
SAE: pwd-seed – hexdump(len=32): 24 c3 8c 89 53 0c 31 91 d4 f1 4f 39 82 e7 68 15 84 a8 74 0a bc a7 a1 f3 02 8c 9d a8 a1 f2 e5 47
SAE: pwd-value – hexdump(len=32): 78 7e d7 68 fd d6 ff f9 cd de f1 2b 4b a7 d4 3c 6d 14 90 f9 97 71 02 59 02 0a df 3f 1a ef e5 99
After 40 loops the first point on the elliptical curve will be the [X, Y] point. The resulting (x,y) pair becomes the Password Element, PE. Both the entities will derive the PE from the password.
Observe the below supplicant log to see the commit X and commit Y value that got generated after 40 loops.
Generation of Scalar X and Y point after PE generation, supplicant logs on Client Side.
SAE: counter = 040
SAE: pwd-seed – hexdump(len=32): 24 c3 8c 89 53 0c 31 91 d4 f1 4f 39 82 e7 68 15 84 a8 74 0a bc a7 a1 f3 02 8c 9d a8 a1 f2 e5 47
SAE: pwd-value – hexdump(len=32): 78 7e d7 68 fd d6 ff f9 cd de f1 2b 4b a7 d4 3c 6d 14 90 f9 97 71 02 59 02 0a df 3f 1a ef e5 99
SAE: pwd-seed result 0 found=0xff
SAE: own commit-scalar – hexdump(len=32): 91 81 fe bd 30 cc b5 87 0f a5 78 4c 9f c4 de 51 02 bd fd 9e c3 5b d0 48 06 bb 70 8c ca eb ae ac
SAE: own commit-element(x) – hexdump(len=32): b7 95 ec b9 18 cf b0 b4 0b a2 1d bd a6 15 11 6a 40 05 cc a6 ea 1e 93 2a f7 a2 6b 20 15 81 a8 c1
SAE: own commit-element(y) – hexdump(len=32): 98 88 dd 00 88 f1 cb ed 47 e8 05 50 69 88 26 95 6f 32 47 fd 70 24 07 12 dd fc b8 96 b5 78 66 ca
Step2 : COMMIT Exchange
1) In the Commit exchange both the parties exchange the X,Y,Scalar and Finite field element.
2) In the Commit Exchange, both sides commit to a single guess of the password.
3) First, each peer generates two random numbers, private and mask.
4) These two secrets and the Password Element (which was generated before this commit phase) are then used to construct the scalar and element.

4) The peers exchange their scalar and Element[X,Y] and check the peer’s scalar and Element.
5) If either the peer-scalar or Peer-Element fail validation, then the exchange MUST be terminated and authentication fails.
6) If both the peer-scalar and Peer-Element are valid, they are used with the Password Element and few inputs to the secret generated function to derive a shared secret.
Both the parties generate the same shared secret based on the public data exchanged. Public data is also the hashed message exchanges. But the other parties do know how to generate the same Shared Secret based on the ECDH Diffie-Helmen algorithm and with mathematical functions that the program use.

7) In the above supplicant log you can observe that X, Y and scalar values have been generated and they will be sent in a Commit message to the AP along with the finite field element.
8) To enforce key separation and cryptographic hygiene, the shared secret is stretched into two subkeys — a key confirmation key, kck, and a master key, mk. KCK here is not the same as what we see in 4-way Handshake.

9) Observe the below supplicant log that is being generated in the client and AP side after the commit exchange and observe that shared secret(k) is being generated in the both peers. And this shared secret is same in both the client and AP.
Supplicant log after the COMMIT Exchange, before the CONFIRM exchange -> client side log
SAE: Possible elements at the end of the frame – hexdump(len=0):
SAE: k – hexdump(len=32): e6 46 5c b2 65 ba 52 bc 79 92 10 c8 08 1b 02 f8 f1 35 f8 c9 b1 0d 8b ae ff fc fd 61 ba 32 bb 7d
SAE: keyseed – hexdump(len=32): a2 33 0d 9b 4e 48 86 4f a4 84 e0 cc a3 4d 9e 74 51 e1 80 2b 57 d0 62 12 3e 51 1a 5c 45 75 42 0c
SAE: PMKID – hexdump(len=16): 64 74 42 13 95 ba 3a d5 84 11 b0 dc 86 0b 1e 37
SAE: KCK – hexdump(len=32): 22 27 3e 57 65 49 99 3f cb c2 eb f9 7a ca c4 ca ae 91 dc 04 d2 8b 9c 8f a7 3f f4 ff 16 99 eb 47
SAE: PMK – hexdump(len=32): 33 6c df ba a6 98 95 49 52 76 70 c7 1d 50 be 43 cf dc 8d d7 42 85 37 e6 39 b5 ee 09 c8 0b 7d 7c
Supplicant log after the COMMIT Exchange, before the CONFIRM exchange AP side -> AP Side log
SAE: k – hexdump(len=32): e6 46 5c b2 65 ba 52 bc 79 92 10 c8 08 1b 02 f8 f1 35 f8 c9 b1 0d 8b ae ff fc fd 61 ba 32 bb 7d
SAE: keyseed – hexdump(len=32): a2 33 0d 9b 4e 48 86 4f a4 84 e0 cc a3 4d 9e 74 51 e1 80 2b 57 d0 62 12 3e 51 1a 5c 45 75 42 0c
SAE: PMKID – hexdump(len=16): 64 74 42 13 95 ba 3a d5 84 11 b0 dc 86 0b 1e 37
SAE: KCK – hexdump(len=32): 22 27 3e 57 65 49 99 3f cb c2 eb f9 7a ca c4 ca ae 91 dc 04 d2 8b 9c 8f a7 3f f4 ff 16 99 eb 47
SAE: PMK – hexdump(len=32): 33 6c df ba a6 98 95 49 52 76 70 c7 1d 50 be 43 cf dc 8d d7 42 85 37 e6 39 b5 ee 09 c8 0b 7d 7c
Observe that both the parties have generated the same keys after the COMMIT phase. They have to confirm whether the generated keys are same on both the sides.
Step3 : CONFIRM Exchange
1) In the Confirm Exchange, both sides confirm that they derived the same secret, and therefore, are in possession of the same password.
2) The Commit Exchange consists of an exchange of data that is the output of the random function, H(), the key confirmation key, and the two scalars and two elements exchanged in the Commit Exchange.

Where ( <sender-id>) is the identity of the sender of the confirm message.
3) The two peers exchange these confirmations and verify the correctness of the other peer’s confirmation that they receive. If the other peer’s confirmation is valid, authentication succeeds; if the other peer’s confirmation is not valid, authentication fails.
4) If authentication fails, all ephemeral state created as part of the particular run of the Dragonfly exchange MUST be irretrievably destroyed.
Observe the CONFIRM message received by the AP in the supplicant log.
CONFIRM Received by the AP
SAE: State Confirmed -> Accepted for peer e8:de:27:a9:94:fb (Accept Confirm)
RSN: added PMKSA cache entry for e8:de:27:a9:94:fb
CONFIRM Received by the Client Side
wlxe8de27a994fb: SME: SAE authentication transaction 2 status code 0
wlxe8de27a994fb: SME SAE confirm
SAE: peer-send-confirm 0
SME: SAE completed – setting PMK for 4-way handshake
WPA: Set PMK based on external data – hexdump(len=32): 33 6c df ba a6 98 95 49 52 76 70 c7 1d 50 be 43 cf dc 8d d7 42 85 37 e6 39 b5 ee 09 c8 0b 7d 7c
After this CONFIRM phase the generated PMK will be used, for 4-way Handshake. The 4-way Hand shake procedure will be similar to the WPA2. Here we have Dragonfly handshake to generate the PMK. Which will be unique for the each client.
Step4 : Setting PMK
PMK will get generated before the confirm exchange , and it will be used once the confirm exchange is done. Below function is used for Generating PMK, and input to the function is shared secret (k).
keyseed = H(<0>32, k)
PMK = KDF-512(keyseed, “SAE KCK and PMK”, (commit–scalar + peer–commit–scalar) modulo r)
Both the parties will generate same PMK. Generating the PTK from the PMK, and 4-way handshake is similar to the WPA2-PMF-Handshake.
You can find the below diagram as well to understand the dragonfly procedure, and it will help you to understand the things better. The below diagram explains the procedure that we have discussed above in a single picture.

In the Next post we will look in to the sniffer capture for the WPA3 HandShake and , and we will see the few attacking scenarios for this WPA3.