Hash functions play a crucial role in various applications, including hash maps, integrity checks, pseudo-random value generation, and transforming a passphrase into a usable key. In this discussion, we’ll explore specific hash-based functions used in the 802.11 specifications. These functions are essential for mapping a passphrase to a key, deriving new keys from a master key, and ensuring authentication.
HMAC (Keyed-Hash Message Authentication Code)
Hash functions alone do not provide authentication. They simply take input data and produce a digest. If a sender calculates a hash and appends it to the transmitted data, an attacker could modify the data, recompute the hash, and send the altered message. The receiver, unaware of the tampering, would assume the message is intact.
This is where HMAC (Keyed-Hash Message Authentication Code) becomes essential. HMAC relies on a shared secret key between the sender and receiver. By hashing the key along with the message, HMAC ensures that an attacker cannot modify the data and regenerate a valid hash without knowing the secret key.
HMAC Implementation
HMAC is described in RFC 2104, but it does not specify a particular hash function. At the time of the RFC’s writing, common hash algorithms included MD5 and SHA-1. In this example, we’ll use SHA-1, but keep in mind that newer cryptographic standards favor more secure hash functions like SHA-2 and SHA-3.

The algorithm is straightforward:
- Key Processing:
- If the input key (K) is longer than the hash function’s block size (SHA-1 uses 512-bit (64-byte) blocks), it is first hashed using the chosen hash function.
- If the key is shorter than the block size, it is padded with zeros up to the block size.
- XORing the Key:
- The key is XORed byte by byte with
0x36
(Inner Pad), producing XOR_ipad. - The same key is XORed byte by byte with
0x5C
(Outer Pad), producing XOR_opad.
- The key is XORed byte by byte with
- Computing the HMAC Digest:
- First, the hash function is applied to the concatenation of XOR_ipad and the message, resulting in Hash_ipad.
- Then, the hash function is applied again to the concatenation of XOR_opad and Hash_ipad.
- Final Output:
- The result of this second hash operation is the HMAC digest, also known as the MAC (Message Authentication Code).
And voilà! We have our HMAC.
Example HMAC-SHA1
key: ‘1Hundredwire_this_is_a_very_long_secret_with_more_than_64_bytes!!’
message: ‘This message is authenticated’
Message in hex: 0x54686973206d6573736167652069732061757468656e74696361746564
HMAC – Example – Key Processing
The key is encoded in UTF-8, converting to hexadecimal we have:
0x3148756e64726564776972655f746869735f69735f615f766572795f6c6f6e675f7365637265745f776974685f6d6f72655f7468616e5f36345f62797465732121.
Since the key is longer than 64 bytes, we hash it with SHA-1 to reduce it to 20 bytes.
After running SHA-1 with the key we have:
key = 0xcac4bfc6f1f805f44c5b1d9e93b280da03b96ad9 which will be padded with zeroes until it reaches 512 bits.
key = 0xcac4bfc6f1f805f44c5b1d9e93b280da03b96ad90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
HMAC – Example – XORing the Key
XOR_ipad = key ⊕ ipad (ipad is 0x36
for each key byte)
XOR_ipad = 0xfcf289f0c7ce33c27a6d2ba8a584b6ec358f5cef3636363636363636363636363636363636363636363636363636363636363636363636363636363636363636
XOR_opad = key ⊕ opad (opad is 0x5C
for each key byte)
XOR_opad = 0x9698e39aada459a8100741c2cfeedc865fe536855c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c
HMAC – Example – Computing the HMAC Digest
HMAC Digest = SHA-1 ( XOR_opad | SHA-1(XOR_ipad | Message ) )
SHA-1(XOR_ipad | Message ) = 18c3adcb7bfb3812d7efb6b88b84dcad09f144cd
HMAC Digest = SHA-1 (XOR_opad | 18c3adcb7bfb3812d7efb6b88b84dcad09f144cd ) )
HMAC Digest = ece5d6c59e809261dec303180a6d73c67d23a8a3
PRF (Pseudorandom Function)
A Pseudorandom Function (PRF) is a cryptographic function that produces outputs with pseudorandom properties, making it useful for key derivation. In the IEEE 802.11 standard, PRFs play a crucial role in deriving the Pairwise Transient Key (PTK), which is essential for secure Wi-Fi communication.
The PRF function has the folowing inputs:
- Key (K): A secret key used for HMAC computation.
- Label (A): A fixed string defining the specific usage of the PRF.
- Variable-Length Data (B): A data string.
- Output Length (L): The desired number of output bits.
HMAC-SHA1 Computation in PRFs
The PRF function relies on HMAC-SHA1 and processes inputs as follows:
- The message for HMAC-SHA1 is constructed as:
Message = A | Y | B | X- Y: A single octet set to
0x00
(separator byte) - X: A loop counter starting from
0x00
and incrementing each iteration.
- Y: A single octet set to
- Since SHA-1 produces 160-bit (20-byte) outputs, the PRF runs multiple iterations until the required output length L is reached.
- The final output is the concatenation of all HMAC-SHA1 results, truncated to L bytes.
Example PRF Computation (IEEE 802.11 Test Case 1)
- Key (K):
0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
- Label (A):
"prefix"
(0x707265666978
) - Data (B):
"Hi There"
(0x4869205468657265
) - Output Length (L):
64 bytes
Since L = 64 bytes and each HMAC-SHA1 output is 20 bytes, the loop runs 4 times ( ceil( 64 / 20)
= 4 ).
Computation Steps
Iteration 1 (X = 0x00)
- Message = A | Y | B | X
- Message = 0x707265666978 | 0x00 | 0x4869205468657265 | 0x00
- Output_0 = HMAC-SHA1(0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b, 0x70726566697800486920546865726500)
- Output_0 = bcd4c650b30b9684951829e0d75f9d54b862175e
Iteration 2 (X = 0x01)
Message = 0x707265666978 | 0x00 | 0x4869205468657265 | 0x01
Output_1 = HMAC-SHA1(0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b, 0x70726566697800486920546865726501)
Output_1 = d9f00606e17d8da35402ffee75df78c3d31e0f88
Iteration 3 (X = 0x02)
Output_2 = HMAC-SHA1(0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b, 0x70726566697800486920546865726502)
Output_2 = 9f012120c0862beb67753e7439ae242edb837369
Iteration 4 (X = 0x03)
Output_3 = HMAC-SHA1(0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b, 0x70726566697800486920546865726503)
Output_3 = 8356cf5a209b346755f01094184b9fc56a7426c3
The final output is the concatenation of all iterations, truncated to 64 bytes (L).
Output = bcd4c650b30b9684951829e0d75f9d54b862175ed9f00606e17d8da35402ffee75df78c3d31e0f889f012120c0862beb67753e7439ae242edb8373698356cf5a
This matches the official IEEE 802.11 specification test vector (Test Case 1).
With HMAC and PRF covered, we now have a solid foundation for understanding the key derivation process in Wi-Fi security. Next, we’ll explore PBKDF2, which strengthens passphrase-based key generation using HMAC-SHA1.
I hope this has been helpful to you.
Stay tuned!
Diego Capassi
References
IEEE Std 802.11™-2016, “IEEE Standard for Information technology—Telecommunications and information exchange between systems—Local and metropolitan area networks—Specific requirements—Part 11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications,” IEEE, 2016.
Krawczyk, H., Bellare, M., & Canetti, R. (1997). HMAC: Keyed-Hashing for Message Authentication. RFC 2104. Internet Engineering Task Force (IETF).