eapol

package
v0.331.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2026 License: AGPL-3.0 Imports: 4 Imported by: 0

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

func Decode(hexBlob string) (EAPOLKey, error)

Decode parses a hex-encoded EAPOL frame. Tolerates ':' / '-' / '_' / whitespace separators.

func DecodeBytes

func DecodeBytes(b []byte) (EAPOLKey, error)

DecodeBytes is the byte-slice variant of Decode for callers that already have raw EAPOL bytes.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL