Skip to content

gibme-npm/eapol

Repository files navigation

@gibme/eapol

A comprehensive, low-level EAPOL (Extensible Authentication Protocol over LAN) Key Frame parser for Wi-Fi security protocols.

Parses and validates EAPOL-Key frames used in WPA/WPA2/WPA3 4-way handshakes, group key handshakes, and Fast Transition (802.11r) operations. Supports RSN/WPA IE parsing, all KDE types (GTK, IGTK, PMKID, etc.), and all standard cipher suites and AKM methods.

Parser-only implementation - does not perform cryptographic operations.

Requirements

  • Node.js >= 22

Installation

npm install @gibme/eapol

or

yarn add @gibme/eapol

Quick Start

import { Frame, EAPOL } from '@gibme/eapol';

// Parse from hex string
const frame = Frame.from('0203005f02...', 'hex');

// Parse from buffer
const frame = Frame.from(buffer);

// Identify the handshake message
console.log(`Message ${frame.messageNumber} of ${frame.handshakeType} handshake`);

// Validate the frame
const result = frame.validate();
if (!result.valid) {
    console.error('Validation errors:', result.errors);
}

Features

Frame Parsing

  • Parse complete EAPOL-Key frames from buffers or hex strings
  • Automatic frame detection — scans up to 512 bytes past 802.11/LLC headers to locate the EAPOL header
  • Supports EAPOL versions 1, 2, and 3 (802.1X-2001/2004/2010)
  • Extracts all key descriptor fields (nonces, MIC, replay counter, IVs, RSC, etc.)
  • Parses Key Information flags with full bit-field decoding

Security Protocol Support

Protocol Standard Description
WPA/TKIP IEEE 802.11i Legacy WPA with Microsoft OUI (00:50:F2:01)
WPA2/WPA3 IEEE 802.11i/ac/ax RSN Information Element (IE 0x30) parsing
Fast Transition IEEE 802.11r Full FT-IE and Mobility Domain parsing
PMF IEEE 802.11w Management Frame Protection with IGTK support
FILS IEEE 802.11ai Fast Initial Link Setup support

Key Data Encapsulation (KDE) Parsing

All standard KDE types are recognized and parsed:

  • GTK - Group Temporal Key (key ID, Tx flag, key material)
  • IGTK - Integrity Group Temporal Key with IPN (802.11w PMF)
  • PMKID - Pairwise Master Key Identifier (16 bytes)
  • MAC Address - TDLS peer identification
  • SMK - Station-to-Station Master Key (TDLS)
  • Nonce - Additional 32-byte nonce
  • Lifetime - Key lifetime in seconds
  • Error - Handshake error codes
  • Key ID - Generic key identifier
  • Multiband GTK / Key ID - Multi-band operation support

Cipher Suites

Complete constants for all IEEE 802.11 cipher suites:

Constant Value Usage
CCMP_128 0x04 WPA2/WPA3 standard
GCMP_128 0x08 WPA3
GCMP_256 0x09 WPA3 192-bit
CCMP_256 0x0a WPA3 192-bit
TKIP 0x02 Legacy WPA
WEP40 / WEP_104 0x01 / 0x05 Legacy (deprecated)
BIP_CMAC_128 0x06 PMF
BIP_GMAC_128 / BIP_GMAC_256 0x0b / 0x0c PMF
BIP_CMAC_256 0x0d PMF

Available via EAPOL.PairwiseCipherSuite, EAPOL.GroupCipherSuite, and EAPOL.ManagementFrameProtectionSuite.

AKM Suites

All standard Authentication and Key Management methods:

Constant Value Usage
PSK 0x02 WPA2-Personal
EAP 0x01 WPA2-Enterprise
SAE 0x08 WPA3-Personal
OWE 0x12 Opportunistic Wireless Encryption
FT_PSK / FT_SAE 0x04 / 0x09 Fast Transition variants
EAP_SUITE_B_192 0x0c WPA3-Enterprise 192-bit
FILS_SHA256 / FILS_SHA384 0x0e / 0x0f Fast Initial Link Setup
SAE_EXT_KEY / FT_SAE_EXT_KEY 0x18 / 0x19 SAE with Extended Key
PASN 0x13 Pre-Association Security Negotiation

Available via EAPOL.AkmSuite.

Frame Validation

Comprehensive validation including:

  • EAPOL version and descriptor type compatibility
  • Key Information flag consistency per IEEE 802.11 spec
  • Message-specific requirements (Messages 1-4 of the 4-way handshake)
  • Replay counter validation
  • RSN/WPA IE structure integrity (version, cipher counts, AKM counts)
  • KDE structure validation (IGTK IPN length, MAC address length, PMKID length, nonce length)
  • Nonce and MIC presence requirements
  • Pairwise key length checks
  • Encrypted key data flag consistency

Handshake Message Detection

Automatic identification of 4-way handshake messages based on flag combinations:

Message Direction Key Flags
Message 1 AP -> STA hasAck, no hasMic, no hasInstall
Message 2 STA -> AP hasMic, no hasAck, no isSecure
Message 3 AP -> STA hasAck, hasInstall, hasMic
Message 4 STA -> AP hasMic, isSecure, no hasAck

Also detects group key handshake messages.

Usage Examples

Identify Handshake Messages

import { Frame } from '@gibme/eapol';

const frame = Frame.from(buffer);

if (frame.isMessage1) {
    console.log('Message 1: AP -> STA (ANonce)');
    console.log('ANonce:', frame.keyNonce.toString('hex'));
}

if (frame.isMessage2) {
    console.log('Message 2: STA -> AP (SNonce, RSN IE)');
    console.log('SNonce:', frame.keyNonce.toString('hex'));
    console.log('RSN:', frame.rsn);
}

if (frame.isMessage3) {
    console.log('Message 3: AP -> STA (ANonce, GTK, Install)');
    console.log('GTK Key ID:', frame.gtk?.keyId);
    console.log('GTK:', frame.gtk?.gtk.toString('hex'));
}

if (frame.isMessage4) {
    console.log('Message 4: STA -> AP (Confirmation)');
}

Extract Security Information

const frame = Frame.from(buffer);

// RSN Information Element (WPA2/WPA3)
if (frame.rsn) {
    console.log('Version:', frame.rsn.version);
    console.log('Group Cipher:', frame.rsn.groupCipher.toString('hex'));
    console.log('Pairwise Ciphers:', frame.rsn.pairwiseCipherSuites.length);
    console.log('AKM Suites:', frame.rsn.akmSuites.length);
    console.log('MFP Required:', frame.rsn.capabilities.mfpRequired);
    console.log('MFP Capable:', frame.rsn.capabilities.mfpCapable);
    console.log('PMKIDs:', frame.rsn.pmkIds.length);
}

// Legacy WPA Information Element
if (frame.wpa) {
    console.log('WPA Version:', frame.wpa.version);
    console.log('Group Cipher:', frame.wpa.groupCipher.toString('hex'));
}

// Fast Transition (802.11r)
if (frame.ft) {
    console.log('Mobility Domain ID:', frame.mdid.toString('hex'));
    console.log('R0KH-ID:', frame.ft.r0KHId?.toString('hex'));
    console.log('R1KH-ID:', frame.ft.r1KHId?.toString('hex'));
}

Extract Keys

const frame = Frame.from(buffer);

// Group Temporal Key
if (frame.gtk) {
    console.log('GTK Key ID:', frame.gtk.keyId);
    console.log('GTK Tx Flag:', frame.gtk.txFlag);
    console.log('GTK:', frame.gtk.gtk.toString('hex'));
}

// Integrity Group Temporal Key (PMF)
if (frame.igtk) {
    console.log('IGTK Key ID:', frame.igtk.keyId);
    console.log('IGTK IPN:', frame.igtk.ipn.toString('hex'));
    console.log('IGTK:', frame.igtk.igtk.toString('hex'));
}

// PMKID (for fast roaming)
if (frame.pmkid) {
    console.log('PMKID:', frame.pmkid.pmkid.toString('hex'));
}

Compare Cipher Suites

import { Frame, EAPOL } from '@gibme/eapol';

const frame = Frame.from(buffer);

if (frame.rsn) {
    const supportsCCMP = frame.rsn.pairwiseCipherSuites.some(
        suite => suite.equals(EAPOL.PairwiseCipherSuite.CCMP_128)
    );

    const supportsSAE = frame.rsn.akmSuites.some(
        suite => suite.equals(EAPOL.AkmSuite.SAE)
    );

    console.log('Supports CCMP-128:', supportsCCMP);
    console.log('Supports WPA3-SAE:', supportsSAE);
}

Validate a Frame

const frame = Frame.from(buffer);
const validation = frame.validate();

if (!validation.valid) {
    console.error('Frame validation failed:');
    validation.errors.forEach(err => console.error(`  - ${err}`));
} else {
    console.log('Frame is valid');
    console.log('Key Descriptor Version valid:', frame.isValidKeyDescriptorVersion());
}

MIC Verification Support

const frame = Frame.from(buffer);

// Get the frame with MIC field zeroed for external MIC calculation
const zeroedFrame = frame.zeroedFrame;

// The MIC algorithm depends on the Key Descriptor Version
switch (frame.keyVersion) {
    case EAPOL.KeyVersion.HMAC_MD5_RC4:
        // HMAC-MD5 (WPA/TKIP)
        break;
    case EAPOL.KeyVersion.HMAC_SHA1_AES:
        // HMAC-SHA1-128 (WPA2/CCMP)
        break;
    case EAPOL.KeyVersion.AES_128_CMAC:
        // AES-128-CMAC (WPA3, PMF, FT)
        break;
}

API Reference

Frame.from(blob, encoding?)

Parses an EAPOL Key Frame from a buffer or string.

  • blob - Buffer or string containing the EAPOL frame
  • encoding - Optional BufferEncoding (default: 'hex')
  • Returns: Frame
  • Throws: Error if the blob does not contain a valid EAPOL Key Frame

Frame Properties

Property Type Description
version EAPOL.Version EAPOL protocol version (0x01-0x03)
type EAPOL.Type Packet type (0x03 for EAPOL-Key)
descriptor EAPOL.Descriptor Key descriptor type (RC4, RSN, FT, PMF, FILS, EHT)
keyVersion EAPOL.KeyVersion Crypto algorithm for MIC and key wrapping
replayCounter bigint 8-byte replay counter
keyLength number Pairwise key length in bytes
keyNonce Buffer 32-byte ANonce or SNonce
keyIv Buffer 16-byte initialization vector
keyRsc Buffer 8-byte receive sequence counter
keyId Buffer 8-byte key identifier (reserved)
mic Buffer Message Integrity Code
zeroedFrame Buffer Frame copy with MIC zeroed for verification

Key Information Flags

Property Type Description
keyInfo EAPOL.KeyInfo Complete key info structure
isPairwise boolean Pairwise key (PTK) vs group key (GTK)
hasInstall boolean Key should be installed
hasAck boolean From authenticator (AP)
hasMic boolean MIC field is valid
isSecure boolean Secure association established
hasError boolean Error flag
isRequest boolean Supplicant requests new key
isEncrypted boolean Key data is encrypted
isSmk boolean TDLS SMK message

Handshake Detection

Property Type Description
isMessage1 boolean Message 1 of 4-way handshake
isMessage2 boolean Message 2 of 4-way handshake
isMessage3 boolean Message 3 of 4-way handshake
isMessage4 boolean Message 4 of 4-way handshake
messageNumber 1 | 2 | 3 | 4 | undefined Detected message number
handshakeType string 'four-way', 'group-key', or 'unknown'

Parsed Information Elements

Property Type Description
rsn EAPOL.Rsn | undefined RSN IE (WPA2/WPA3)
wpa EAPOL.Wpa | undefined Legacy WPA IE
ft Partial<EAPOL.Ft> | undefined Fast Transition IE (802.11r)
mobilityDomain EAPOL.MobilityDomain | undefined Mobility Domain IE
ies EAPOL.Ie[] All parsed information elements

Parsed KDEs

Property Type Description
gtk EAPOL.GtkKde | undefined Group Temporal Key
igtk EAPOL.IgtkKde | undefined Integrity Group Temporal Key (PMF)
pmkid EAPOL.PmkidKde | undefined Pairwise Master Key Identifier
macAddr EAPOL.MacAddrKde | undefined MAC Address (TDLS)
smk EAPOL.SmkKde | undefined Station-to-Station Master Key
nonce EAPOL.NonceKde | undefined Additional nonce
lifetime EAPOL.LifetimeKde | undefined Key lifetime
error EAPOL.ErrorKde | undefined Error information
keyIdKde EAPOL.KeyIdKde | undefined Generic key identifier
multibandGtk EAPOL.MultibandGtkKde | undefined Multiband GTK
multibandKeyId EAPOL.MultibandKeyIdKde | undefined Multiband key identifier
kdes EAPOL.Kde[] All parsed KDEs
encryptedKeyData Buffer Raw encrypted key data (if encrypted)

Frame Methods

validate()

Validates the frame structure and content against IEEE 802.11 requirements.

Returns: { valid: boolean; errors: string[] }

isValidKeyDescriptorVersion()

Checks if the Key Descriptor Version is valid for the Descriptor Type.

Returns: boolean

Non-Goals

This library does not:

  • Capture packets from network interfaces
  • Implement cryptographic operations (PMK/PTK derivation, MIC calculation)
  • Perform active attacks or password cracking
  • Implement EAP authentication protocols
  • Act as a RADIUS server or supplicant

It is purely a parser and validator for already-captured EAPOL frames.

Use Cases

  • Wireless security analysis - Parse captured handshakes
  • DPSK implementations - Validate handshake frames
  • Network monitoring - Extract handshake parameters
  • Research & education - Understand WPA/WPA2/WPA3 protocols
  • Testing & validation - Verify frame structure and compliance
  • Forensics - Analyze captured Wi-Fi traffic

Supported Standards

  • IEEE 802.11i - RSN (WPA2)
  • IEEE 802.11r - Fast Transition (FT)
  • IEEE 802.11w - Protected Management Frames (PMF)
  • IEEE 802.11ai - Fast Initial Link Setup (FILS)
  • IEEE 802.11ac/ax - WPA3, GCMP ciphers
  • Wi-Fi Alliance - WPA, WPA2, WPA3

License

MIT

Contributing

Issues and pull requests welcome at github.com/gibme-npm/eapol

Author

Brandon Lehmann brandonlehmann@gmail.com

About

A comprehensive, low-level EAPOL Key Frame parser for Wi-Fi security protocols. Parses and validates EAPOL-Key frames used in WPA/WPA2/WPA3 4-way handshakes, group key handshakes, and 802.11r Fast Transition. Supports RSN/WPA IE parsing, all KDE types, cipher suites, and AKM methods. Parser-only, no cryptographic operations.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors