Documentation
¶
Overview ¶
Package eapol decodes EAPOL-Key frames — the WPA / WPA2 / WPA3 4-way handshake frames captured from any 802.1X-bearing medium. Pure offline parser; no transport, no hardware.
Wrap-vs-native judgement: EAPOL is an IEEE standard (802.1X for the L2 frame, 802.11i for the Key descriptor format), all fully public. The walker is bit-level decoding over a 95+ byte frame. Wrapping a FAP for this would require an SD-card install + a firmware-fork dependency for a pure parser. Native delivers offline analysis (operators can paste a captured EAPOL frame from tcpdump / Wireshark / hcxdumptool / Marauder and inspect every field without a WiFi adapter attached), unit-testable round-trips, and an output shape that chains naturally into the existing marauder_handoff_hashcat flow (which converts captured frames to hashcat .hc22000).
What this package covers:
- 802.1X frame header decode (version, type, body length)
- EAPOL-Key descriptor walk (key info bitfield, key length, replay counter, nonce, IV, RSC, MIC, key data length, key data)
- Key Information bitfield decode — descriptor version, pairwise vs group, install / ack / mic / secure / error / request / encrypted / SMK flags
- Handshake-message identification (M1 / M2 / M3 / M4 from the Ack / MIC / Install / Secure flag combinations)
- Key Data Encapsulation (KDE) walker for the most common elements: RSN IE, GTK, MAC address
What this package does NOT cover (deliberately out of scope):
- PMK / PTK derivation (covered by `mfkey32_recover` / hashcat / aircrack — the handshake gets handed off there)
- MIC validation (needs the derived PTK)
- Encrypted Key Data decryption (needs the KEK)
- Reassembling fragmented EAPOL across 802.11 frames
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type EAPOLKey ¶
type EAPOLKey struct {
// Header is the parent 802.1X frame header.
Header Header `json:"header"`
// DescriptorType: 1 = RC4 (WPA1), 2 = RSN (WPA2/WPA3).
DescriptorType int `json:"descriptor_type"`
DescriptorTypeName string `json:"descriptor_type_name"`
// KeyInfo is the decoded bitfield.
KeyInfo KeyInfo `json:"key_info"`
// HandshakeMessage is "M1", "M2", "M3", "M4", or "" when the
// flag pattern doesn't match a documented message.
HandshakeMessage string `json:"handshake_message,omitempty"`
// KeyLength is the 2-byte BE length of the pairwise temporal
// key (16 for TKIP, 16 for CCMP).
KeyLength int `json:"key_length"`
// ReplayCounter is the 8-byte BE replay counter. Same value
// in both halves of an M1/M2 exchange.
ReplayCounter string `json:"replay_counter"`
// KeyNonce is the 32-byte ANonce (from AP) or SNonce (from
// client) used in PTK derivation.
KeyNonce string `json:"key_nonce"`
// KeyIV is the 16-byte IV for the encrypted Key Data field.
// Zero in pure CCMP setups; non-zero in TKIP.
KeyIV string `json:"key_iv"`
// KeyRSC is the 8-byte Receive Sequence Counter (for the
// installed group key in M3).
KeyRSC string `json:"key_rsc"`
// KeyReserved is the 8-byte reserved field.
KeyReserved string `json:"key_reserved"`
// KeyMIC is the 16-byte Message Integrity Code (HMAC-SHA1 or
// AES-CMAC over the rest of the frame). Zero in M1.
KeyMIC string `json:"key_mic"`
// KeyDataLength is the 2-byte BE length of the Key Data
// field.
KeyDataLength int `json:"key_data_length"`
// KeyData is the raw Key Data hex. When EncryptedKeyData is
// set we can't dissect; otherwise KDEs walks the substructure.
KeyData string `json:"key_data"`
// KDEs is the decoded list of Key Data Encapsulation
// elements (RSN IE, GTK, MAC address). nil when KeyData is
// encrypted or empty.
KDEs []KDE `json:"kdes,omitempty"`
}
EAPOLKey is the structured view of an EAPOL-Key frame (descriptor type + key info + nonce + ... + key data).
func Decode ¶
Decode parses a hex-encoded EAPOL frame. Tolerates ':' / '-' / '_' / whitespace separators.
func DecodeBytes ¶
DecodeBytes is the byte-slice variant of Decode for callers that already have raw EAPOL bytes.
type Header ¶
type Header struct {
// Version is the 802.1X protocol version (1=WPA1/802.1X-2001,
// 2=WPA2/802.1X-2004, 3=802.1X-2010).
Version int `json:"version"`
// Type is the EAPOL frame type (3 = EAPOL-Key).
Type int `json:"type"`
// TypeName is the human-readable type — "EAPOL-Key",
// "EAPOL-Start", "EAPOL-Logoff", "EAPOL-Encapsulated-ASF-Alert".
TypeName string `json:"type_name"`
// BodyLength is the declared length of the frame body (after
// the 4-byte header), big-endian uint16.
BodyLength int `json:"body_length"`
}
Header is the 802.1X frame header (4 bytes).
type KDE ¶
type KDE struct {
// OUI is the 3-byte vendor identifier (00-0F-AC for IEEE).
OUI string `json:"oui"`
// DataType is the 1-byte KDE type:
// 1 = GTK, 2 = MAC address, 4 = PMKID, 6 = IGTK, 7 = IGTK
// PN, 8 = WPA spec
DataType int `json:"data_type"`
TypeName string `json:"type_name"`
// Length is the total KDE length (after the type byte).
Length int `json:"length"`
// DataHex is the raw KDE data after the OUI / type / length
// header.
DataHex string `json:"data_hex"`
}
KDE is one Key Data Encapsulation element. See IEEE 802.11-2020 §12.7.2 Table 12-9.
type KeyInfo ¶
type KeyInfo struct {
// Raw is the 2-byte field for callers that want bit-level
// access.
Raw int `json:"raw"`
// DescriptorVersion is the 3-bit version field (bits 0-2):
// 1 = ARC4-encrypted, HMAC-MD5 MIC (WPA / TKIP)
// 2 = NIST-AES-encrypted, HMAC-SHA1 MIC (WPA2 / CCMP)
// 3 = AES-128-CMAC MIC (802.11w PMF)
DescriptorVersion int `json:"descriptor_version"`
DescriptorName string `json:"descriptor_name"`
// KeyType: bit 3. 1 = Pairwise (PTK), 0 = Group (GTK).
KeyType int `json:"key_type"`
KeyTypeName string `json:"key_type_name"`
// KeyIndex (bits 4-5) — deprecated in WPA2, kept for WEP/WPA
// compatibility.
KeyIndex int `json:"key_index"`
Install bool `json:"install"`
KeyAck bool `json:"key_ack"`
KeyMIC bool `json:"key_mic"`
Secure bool `json:"secure"`
Error bool `json:"error"`
Request bool `json:"request"`
// EncryptedKeyData: bit 12 (WPA2/3). When set, the Key Data
// field is encrypted with the KEK and we cannot dissect KDEs.
EncryptedKeyData bool `json:"encrypted_key_data"`
// SMK: bit 13 (Station-to-Station Link). Rare.
SMK bool `json:"smk_message"`
}
KeyInfo is the decoded 2-byte Key Information bitfield. The IEEE 802.11i flags drive the handshake message identification.