We know that in WPA2's four-way handshake, a MIC is generated in order verify the supplicant (client). But how it is generated? Is something hashed to get the MIC? The PTK (pairwise transient key) depends on the nonces and MAC addresses and also the PMK (Pairwise Master Key); what are the inputs upon which the MIC depends?
According to https://www.shellvoide.com/wifi/understanding-wpa-wpa2-hash-mic-cracking-process-python/, the MIC is computed on each message as an HMAC using the Key Confirmation Key (KCK) as the key, the message payload as the body, and the SHA1 hashing algorithm (in WPA2; WPA1 used the MD5 hashing algorithm).
MIC = HMAC_SHA1(KCK, payload)
The KCK is a portion (first 16 bytes) of the Pairwise Transient Key (PTK). The PTK is computed using a custom pseudo-random function (PRF) itself based on iterated HMAC-SHA1 using the PMK (Pairwise Master Key) as the key, and the payload incorporating various constants plus MAC addresses of client and access point (AP) and the client and AP nonces. See the linked article for an implementation of the custom PRF and its constants. The PMK is 32 bytes computed using PBKDF2 (Password-Based Key Derivation Function 2) with the pre-shared key (PSK, the password in plain text) as the password and the SSID as the salt, 4096 iterations, and the HMAC-SHA1 hashing algorithm.
KCK = PTK[0:16] PTK = CustomPRF(PMK, "Pairwise key expansion", SUM(CL_MAC, AP_MAC, SNONCE, ANONCE)) PMK = PBKDF2(PSK, SSID, 4096, HMAC_SHA1)[0:32]
As such, the MIC is computed by hashing (using SHA1, for WPA2) the message body with the KCK appended and prepended (that being the HMAC construction). The following fields all go into computing the MIC:
- The message body
- The PTK, which is based on:
- The MACs of the client and AP
- The nonces of the client and AP
- The PMK, which itself is based on:
- The PSK (password)
- The SSID