eapaka

package module
v0.0.0-...-db62758 Latest Latest
Warning

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

Go to latest
Published: Feb 22, 2026 License: MIT Imports: 14 Imported by: 0

README

go-eapaka

go-eapaka is a Go library for EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448) protocols. It provides robust functionality for marshaling (generating) and unmarshaling (parsing) EAP packets, designed for building RADIUS servers, EAP peers, and testing tools.

Features

  • Zero External Dependencies: Built using only the Go standard library (encoding/binary, crypto/*).
  • Security First: Implements constant-time MAC verification to prevent timing attacks and handles sensitive data with care.

Installation

go get github.com/oyaguma3/go-eapaka

Usage

Parsing an EAP Packet
package main

import (
	"fmt"
	"github.com/oyaguma3/go-eapaka"
)

func main() {
	// Example raw bytes (EAP-Request/AKA-Identity)
	data := []byte{...}

	pkt, err := eapaka.Parse(data)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Code: %d, Type: %d\n", pkt.Code, pkt.Type)
	
	for _, attr := range pkt.Attributes {
		switch a := attr.(type) {
		case *eapaka.AtIdentity:
			fmt.Printf("Identity: %s\n", a.Identity)
		}
	}
}
Creating an EAP Packet
package main

import (
	"github.com/oyaguma3/go-eapaka"
)

func main() {
	pkt := &eapaka.Packet{
		Code:       eapaka.CodeRequest,
		Identifier: 1,
		Type:       eapaka.TypeAKA,
		Subtype:    eapaka.SubtypeChallenge,
		Attributes: []eapaka.Attribute{
			&eapaka.AtRand{Rand: make([]byte, 16)}, // Fill with actual RAND
			&eapaka.AtAutn{Autn: make([]byte, 16)}, // Fill with actual AUTN
			&eapaka.AtMac{MAC: make([]byte, 16)},   // Placeholder for MAC
		},
	}

	// Calculate and set MAC (K_aut is required)
	// kAut := ...
	// pkt.CalculateAndSetMac(kAut)

	data, err := pkt.Marshal()
	if err != nil {
		panic(err)
	}
	
	// Send data...
}
AT_BIDDING (AKA/AKA' Negotiation)
bid := &eapaka.AtBidding{}
bid.SetAKAPrime(true) // Advertise AKA' support

pkt := &eapaka.Packet{
	Code:       eapaka.CodeRequest,
	Identifier: 1,
	Type:       eapaka.TypeAKA,
	Subtype:    eapaka.SubtypeIdentity,
	Attributes: []eapaka.Attribute{
		bid,
	},
}
Key Derivation (KDF)

Derive session keys for EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448).

// EAP-AKA' Example
identity := "0555444333222111"
ck := ... // from USIM
ik := ... // from USIM
autn := ... // from USIM
netName := "WLAN"

// 1. Derive CK', IK' (RFC 9048 / TS 33.402)
ckPrime, ikPrime, _ := eapaka.DeriveCKPrimeIKPrime(ck, ik, netName, autn)

// 2. Derive Master Keys (K_encr, K_aut, MSK, EMSK)
keys := eapaka.DeriveKeysAKAPrime(identity, ckPrime, ikPrime)

fmt.Printf("MSK: %x\n", keys.MSK)

Note on EAP-AKA' KDF: DeriveCKPrimeIKPrime follows TS 33.402 Annex A.2 and matches RFC 9048 Appendix D test vectors. See kdf_test.go for details.

MS-MPPE-Key Encryption

Encrypt the MS-MPPE-Send-Key and MS-MPPE-Recv-Key attributes for RADIUS.

// Split MSK into Send/Recv keys
sendKey := keys.MSK[0:32]
recvKey := keys.MSK[32:64]

// Encrypt keys (requires RADIUS shared secret and Request Authenticator)
secret := []byte("radius-secret")
reqAuth := ... // 16 bytes from RADIUS Access-Request

encSendKey, _ := eapaka.EncryptMPPEKey(sendKey, secret, reqAuth)
encRecvKey, _ := eapaka.EncryptMPPEKey(recvKey, secret, reqAuth)

Supported Attributes

Note: This library handles the attribute headers (Type and Length) and padding. For the attribute value (data), you must construct the byte slice yourself according to the RFC definitions and assign it to the corresponding field (e.g., Rand, Autn, Identity). For AT_RAND and AT_AUTN, pass only 16-byte Rand/Autn; the Reserved(2) bytes are handled internally.

  • Authentication: AT_RAND, AT_AUTN, AT_RES, AT_AUTS, AT_MAC
  • Identity: AT_IDENTITY, AT_PERMANENT_ID_REQ, AT_ANY_ID_REQ, AT_FULLAUTH_ID_REQ
  • Notification & Error: AT_NOTIFICATION, AT_CLIENT_ERROR_CODE
  • Re-authentication: AT_COUNTER, AT_COUNTER_TOO_SMALL, AT_NONCE_S, AT_NEXT_PSEUDONYM, AT_NEXT_REAUTH_ID
  • Encryption: AT_IV, AT_ENCR_DATA, AT_PADDING
  • EAP-AKA' Extensions: AT_KDF, AT_KDF_INPUT, AT_BIDDING (flags: AtBiddingFlagAKAPrime)
  • Others: AT_CHECKCODE, AT_RESULT_IND, AT_NONCE_MT, AT_VERSION_LIST, AT_SELECTED_VERSION

RFC Compliance Updates (2026-02-20)

The following behavior was updated to align with RFC 4187 / RFC 5448:

  • AT_RAND and AT_AUTN now encode/decode the Value field as Reserved(2) + RAND/AUTN(16) (RFC 4187).
  • AT_PADDING now validates strict RFC constraints:
    • Value length must be 2, 6, or 10 bytes (attribute total length 4, 8, or 12 bytes).
    • All bytes must be 0x00 on unmarshal.
  • AT_CHECKCODE now validates size as 0, 20 (EAP-AKA), or 32 (EAP-AKA').

Compatibility note:

  • If you relied on previous non-compliant behavior, parsing/marshaling results may change.
  • RFC-compliant peers should now interoperate correctly for AT_RAND / AT_AUTN.

References

License

MIT

Documentation

Overview

Package eapaka implements EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448) protocols.

It provides functionality to marshal and unmarshal EAP packets, handle EAP-AKA attributes (including Identity, Notification, Re-auth, etc.), and perform cryptographic operations.

Note: This library handles the attribute headers (Type and Length) and padding. For the attribute value (data), you must construct the byte slice yourself according to the RFC definitions and assign it to the corresponding field (e.g., Rand, Autn, Identity).

Usage

To parse an incoming EAP packet:

pkt, err := eapaka.Parse(data)
if err != nil {
	// handle error
}

To create and marshal a packet:

pkt := &eapaka.Packet{
	Code:       eapaka.CodeRequest,
	Identifier: 1,
	Type:       eapaka.TypeAKA,
	Subtype:    eapaka.SubtypeChallenge,
	Attributes: []eapaka.Attribute{
		&eapaka.AtRand{Rand: randData},
		&eapaka.AtAutn{Autn: autnData},
		&eapaka.AtMac{MAC: make([]byte, 16)}, // Placeholder
	},
}

// Calculate MAC
err := pkt.CalculateAndSetMac(kAut)

data, err := pkt.Marshal()
if err != nil {
	// handle error
}

To derive keys (EAP-AKA'):

autn := ... // from USIM/HSS
ckPrime, ikPrime, err := eapaka.DeriveCKPrimeIKPrime(ck, ik, "WLAN", autn)
keys := eapaka.DeriveKeysAKAPrime(identity, ckPrime, ikPrime)

To encrypt MS-MPPE-Keys:

encKey, err := eapaka.EncryptMPPEKey(keys.MSK[:32], secret, reqAuth)

References

  • RFC 3748: Extensible Authentication Protocol (EAP)
  • RFC 4187: EAP Method for 3rd Gen Authentication and Key Agreement (EAP-AKA)
  • RFC 5448: Improved EAP Method for 3rd Gen Authentication and Key Agreement (EAP-AKA')

Index

Examples

Constants

View Source
const (
	CodeRequest  uint8 = 1
	CodeResponse uint8 = 2
	CodeSuccess  uint8 = 3
	CodeFailure  uint8 = 4
)

EAP Codes (RFC 3748 Section 4)

View Source
const (
	TypeAKA      uint8 = 23 // RFC 4187
	TypeAKAPrime uint8 = 50 // RFC 5448
)

EAP Method Types

View Source
const (
	SubtypeChallenge              uint8 = 1
	SubtypeAuthenticationReject   uint8 = 2
	SubtypeSynchronizationFailure uint8 = 4
	SubtypeIdentity               uint8 = 5
	SubtypeNotification           uint8 = 12
	SubtypeReauthentication       uint8 = 13
	SubtypeClientError            uint8 = 14
)

EAP-AKA Subtypes (RFC 4187 Section 11)

View Source
const (
	KDFReserved         uint16 = 0
	KDFAKAPrimeWithCKIK uint16 = 1
)

AT_KDF values (RFC 9048 Section 8.3).

View Source
const (
	// AtBiddingFlagAKAPrime indicates support for EAP-AKA' and preference for it.
	// This is the D bit (MSB) from RFC 9048 Section 4.
	AtBiddingFlagAKAPrime uint16 = 0x8000
)

AT_BIDDING (RFC 9048 Section 4)

Variables

This section is empty.

Functions

func DeriveCKPrimeIKPrime

func DeriveCKPrimeIKPrime(ck, ik []byte, netName string, autn []byte) (ckPrime, ikPrime []byte, err error)

DeriveCKPrimeIKPrime derives CK' and IK' from CK, IK, AUTN, and Access Network Name. RFC 9048 Section 3.3 and TS 33.402 Annex A.2. netName: Access Network Name (AT_KDF_INPUT). autn: AUTN from the AKA run; SQN xor AK is derived from autn[0:6].

func EncryptMPPEKey

func EncryptMPPEKey(key []byte, secret []byte, reqAuth []byte) ([]byte, error)

EncryptMPPEKey encrypts the given key (e.g., MSK part) for inclusion in MS-MPPE-Send-Key or MS-MPPE-Recv-Key attributes.

Ref: RFC 2548 Section 2.4.2 and 2.4.3 key: The key to encrypt (typically 32 bytes). secret: The RADIUS shared secret. reqAuth: The Request Authenticator from the Access-Request packet (16 bytes).

func Is5GNetworkName

func Is5GNetworkName(networkName string) bool

Is5GNetworkName reports whether the AT_KDF_INPUT Network Name uses the 5G prefix.

func KdfValuesFromAttributes

func KdfValuesFromAttributes(attrs []Attribute) []uint16

KdfValuesFromAttributes extracts AT_KDF values in order.

func PeerIDFromAttributes

func PeerIDFromAttributes(attrs []Attribute, fallback string) string

PeerIDFromAttributes returns the exported Peer-Id using AT_IDENTITY if present. RFC 9048 Section 6.

func Requires5GIdentityForKdf

func Requires5GIdentityForKdf(networkName string, kdfValue uint16, isFastReauth bool) bool

Requires5GIdentityForKdf reports whether 5G identity handling applies for key derivation.

func ServerIDAKAPrime

func ServerIDAKAPrime() string

ServerIDAKAPrime returns the exported Server-Id (empty string). RFC 9048 Section 6.

func SessionIDAKAPrime

func SessionIDAKAPrime(rand, autn []byte) ([]byte, error)

SessionIDAKAPrime builds the EAP-AKA' Session-Id for full authentication. RFC 9048 Section 6: 0x32 || RAND || AUTN

func SessionIDAKAPrimeReauth

func SessionIDAKAPrimeReauth(nonceS, mac []byte) ([]byte, error)

SessionIDAKAPrimeReauth builds the EAP-AKA' Session-Id for fast re-authentication. RFC 9048 Section 6: 0x32 || NONCE_S || MAC

func ValidateKdfIdentity

func ValidateKdfIdentity(networkName string, kdfValue uint16, identity string, isFastReauth bool) error

ValidateKdfIdentity checks basic 5G identity requirements for key derivation. RFC 9048 Section 5.3.1 notes that "0" and "6" prefixes are not used in 5G.

func ValidateKdfOffer

func ValidateKdfOffer(values []uint16) error

ValidateKdfOffer checks RFC 9048 Section 3.2 requirements for AT_KDF offers.

func ValidateKdfReoffer

func ValidateKdfReoffer(offer []uint16, reoffer []uint16, selected uint16) error

ValidateKdfReoffer verifies that only the requested change occurred.

func ValidateKdfResponse

func ValidateKdfResponse(offer []uint16, response []uint16) (uint16, error)

ValidateKdfResponse validates a peer AT_KDF response against an offer. It returns the selected KDF value.

Types

type AkaKeys

type AkaKeys struct {
	K_encr []byte // 128 bits (16 bytes)
	K_aut  []byte // 128 bits (16 bytes)
	MSK    []byte // 512 bits (64 bytes)
	EMSK   []byte // 512 bits (64 bytes)
}

AkaKeys holds the key material derived for EAP-AKA (RFC 4187).

func DeriveKeysAKA

func DeriveKeysAKA(identity string, ck, ik []byte) AkaKeys

DeriveKeysAKA derives the key hierarchy for EAP-AKA as per RFC 4187. identity: The EAP Identity (NAI) from the EAP-Response/Identity packet. ck, ik: Cipher Key and Integrity Key provided by the USIM/HSS.

type AkaPrimeKeys

type AkaPrimeKeys struct {
	K_encr []byte // 128 bits (16 bytes)
	K_aut  []byte // 256 bits (32 bytes) - Note: Larger than AKA
	K_re   []byte // 256 bits (32 bytes)
	MSK    []byte // 512 bits (64 bytes)
	EMSK   []byte // 512 bits (64 bytes)
}

AkaPrimeKeys holds the key material derived for EAP-AKA' (RFC 5448).

func DeriveKeysAKAPrime

func DeriveKeysAKAPrime(identity string, ckPrime, ikPrime []byte) AkaPrimeKeys

DeriveKeysAKAPrime derives the key hierarchy for EAP-AKA' as per RFC 5448. identity: The EAP Identity (NAI). ckPrime, ikPrime: CK' and IK' derived from CK/IK and Network Name.

type AtAnyIdReq

type AtAnyIdReq struct {
}

AT_ANY_ID_REQ (RFC 4187 Section 10.3)

func (*AtAnyIdReq) Marshal

func (a *AtAnyIdReq) Marshal() ([]byte, error)

func (*AtAnyIdReq) Type

func (a *AtAnyIdReq) Type() AttributeType

func (*AtAnyIdReq) Unmarshal

func (a *AtAnyIdReq) Unmarshal(data []byte) error

type AtAutn

type AtAutn struct {
	Autn []byte // 16 bytes
}

AT_AUTN (RFC 4187 Section 10.7)

func (*AtAutn) Marshal

func (a *AtAutn) Marshal() ([]byte, error)

func (*AtAutn) Type

func (a *AtAutn) Type() AttributeType

func (*AtAutn) Unmarshal

func (a *AtAutn) Unmarshal(data []byte) error

type AtAuts

type AtAuts struct {
	Auts []byte // 14 bytes
}

AT_AUTS (RFC 4187 Section 10.9)

func (*AtAuts) Marshal

func (a *AtAuts) Marshal() ([]byte, error)

func (*AtAuts) Type

func (a *AtAuts) Type() AttributeType

func (*AtAuts) Unmarshal

func (a *AtAuts) Unmarshal(data []byte) error

type AtBidding

type AtBidding struct {
	Flags uint16
}

func (*AtBidding) Marshal

func (a *AtBidding) Marshal() ([]byte, error)

func (*AtBidding) SetAKAPrime

func (a *AtBidding) SetAKAPrime(enabled bool)

func (*AtBidding) SupportsAKAPrime

func (a *AtBidding) SupportsAKAPrime() bool

func (*AtBidding) Type

func (a *AtBidding) Type() AttributeType

func (*AtBidding) Unmarshal

func (a *AtBidding) Unmarshal(data []byte) error

type AtCheckcode

type AtCheckcode struct {
	Checkcode []byte
}

AT_CHECKCODE (RFC 4187 Section 10.13)

func (*AtCheckcode) Marshal

func (a *AtCheckcode) Marshal() ([]byte, error)

func (*AtCheckcode) Type

func (a *AtCheckcode) Type() AttributeType

func (*AtCheckcode) Unmarshal

func (a *AtCheckcode) Unmarshal(data []byte) error

type AtClientErrorCode

type AtClientErrorCode struct {
	Code uint16
}

AT_CLIENT_ERROR_CODE (RFC 4187 Section 10.20)

func (*AtClientErrorCode) Marshal

func (a *AtClientErrorCode) Marshal() ([]byte, error)

func (*AtClientErrorCode) Type

func (a *AtClientErrorCode) Type() AttributeType

func (*AtClientErrorCode) Unmarshal

func (a *AtClientErrorCode) Unmarshal(data []byte) error

type AtCounter

type AtCounter struct {
	Counter uint16
}

AT_COUNTER (RFC 4187 Section 10.16)

func (*AtCounter) Marshal

func (a *AtCounter) Marshal() ([]byte, error)

func (*AtCounter) Type

func (a *AtCounter) Type() AttributeType

func (*AtCounter) Unmarshal

func (a *AtCounter) Unmarshal(data []byte) error

type AtCounterTooSmall

type AtCounterTooSmall struct {
}

AT_COUNTER_TOO_SMALL (RFC 4187 Section 10.17)

func (*AtCounterTooSmall) Marshal

func (a *AtCounterTooSmall) Marshal() ([]byte, error)

func (*AtCounterTooSmall) Type

func (a *AtCounterTooSmall) Type() AttributeType

func (*AtCounterTooSmall) Unmarshal

func (a *AtCounterTooSmall) Unmarshal(data []byte) error

type AtEncrData

type AtEncrData struct {
	EncryptedData []byte
}

AT_ENCR_DATA (RFC 4187 Section 10.12)

func (*AtEncrData) Marshal

func (a *AtEncrData) Marshal() ([]byte, error)

func (*AtEncrData) Type

func (a *AtEncrData) Type() AttributeType

func (*AtEncrData) Unmarshal

func (a *AtEncrData) Unmarshal(data []byte) error

type AtFullauthIdReq

type AtFullauthIdReq struct {
}

AT_FULLAUTH_ID_REQ (RFC 4187 Section 10.4)

func (*AtFullauthIdReq) Marshal

func (a *AtFullauthIdReq) Marshal() ([]byte, error)

func (*AtFullauthIdReq) Type

func (a *AtFullauthIdReq) Type() AttributeType

func (*AtFullauthIdReq) Unmarshal

func (a *AtFullauthIdReq) Unmarshal(data []byte) error

type AtIdentity

type AtIdentity struct {
	Identity string
}

AT_IDENTITY (RFC 4187 Section 10.10)

func (*AtIdentity) Marshal

func (a *AtIdentity) Marshal() ([]byte, error)

func (*AtIdentity) Type

func (a *AtIdentity) Type() AttributeType

func (*AtIdentity) Unmarshal

func (a *AtIdentity) Unmarshal(data []byte) error

type AtIv

type AtIv struct {
	IV []byte // 16 bytes
}

AT_IV (RFC 4187 Section 10.12)

func (*AtIv) Marshal

func (a *AtIv) Marshal() ([]byte, error)

func (*AtIv) Type

func (a *AtIv) Type() AttributeType

func (*AtIv) Unmarshal

func (a *AtIv) Unmarshal(data []byte) error

type AtKdf

type AtKdf struct {
	KDF uint16
}

AT_KDF (RFC 9048 Section 3.2)

func (*AtKdf) Marshal

func (a *AtKdf) Marshal() ([]byte, error)

func (*AtKdf) Type

func (a *AtKdf) Type() AttributeType

func (*AtKdf) Unmarshal

func (a *AtKdf) Unmarshal(data []byte) error

type AtKdfInput

type AtKdfInput struct {
	NetworkName string
}

AT_KDF_INPUT (RFC 9048 Section 3.1)

func (*AtKdfInput) Marshal

func (a *AtKdfInput) Marshal() ([]byte, error)

func (*AtKdfInput) Type

func (a *AtKdfInput) Type() AttributeType

func (*AtKdfInput) Unmarshal

func (a *AtKdfInput) Unmarshal(data []byte) error

type AtMac

type AtMac struct {
	MAC []byte // 16 bytes
}

AT_MAC (RFC 4187 Section 10.11)

func (*AtMac) Marshal

func (a *AtMac) Marshal() ([]byte, error)

func (*AtMac) Type

func (a *AtMac) Type() AttributeType

func (*AtMac) Unmarshal

func (a *AtMac) Unmarshal(data []byte) error

type AtNextPseudonym

type AtNextPseudonym struct {
	Pseudonym string
}

AT_NEXT_PSEUDONYM (RFC 4187 Section 10.10)

func (*AtNextPseudonym) Marshal

func (a *AtNextPseudonym) Marshal() ([]byte, error)

func (*AtNextPseudonym) Type

func (a *AtNextPseudonym) Type() AttributeType

func (*AtNextPseudonym) Unmarshal

func (a *AtNextPseudonym) Unmarshal(data []byte) error

type AtNextReauthId

type AtNextReauthId struct {
	Identity string
}

AT_NEXT_REAUTH_ID (RFC 4187 Section 10.11)

func (*AtNextReauthId) Marshal

func (a *AtNextReauthId) Marshal() ([]byte, error)

func (*AtNextReauthId) Type

func (a *AtNextReauthId) Type() AttributeType

func (*AtNextReauthId) Unmarshal

func (a *AtNextReauthId) Unmarshal(data []byte) error

type AtNonceMt

type AtNonceMt struct {
	NonceMt []byte // 16 bytes
}

AT_NONCE_MT (RFC 4186 Section 10.1)

func (*AtNonceMt) Marshal

func (a *AtNonceMt) Marshal() ([]byte, error)

func (*AtNonceMt) Type

func (a *AtNonceMt) Type() AttributeType

func (*AtNonceMt) Unmarshal

func (a *AtNonceMt) Unmarshal(data []byte) error

type AtNonceS

type AtNonceS struct {
	NonceS []byte // 16 bytes
}

AT_NONCE_S (RFC 4187 Section 10.18)

func (*AtNonceS) Marshal

func (a *AtNonceS) Marshal() ([]byte, error)

func (*AtNonceS) Type

func (a *AtNonceS) Type() AttributeType

func (*AtNonceS) Unmarshal

func (a *AtNonceS) Unmarshal(data []byte) error

type AtNotification

type AtNotification struct {
	S    bool
	P    bool
	Code uint16
}

AT_NOTIFICATION (RFC 4187 Section 10.19)

func (*AtNotification) Marshal

func (a *AtNotification) Marshal() ([]byte, error)

func (*AtNotification) Type

func (a *AtNotification) Type() AttributeType

func (*AtNotification) Unmarshal

func (a *AtNotification) Unmarshal(data []byte) error

type AtPadding

type AtPadding struct {
	Length int // Number of zero bytes
}

AT_PADDING (RFC 4187 Section 10.12)

func (*AtPadding) Marshal

func (a *AtPadding) Marshal() ([]byte, error)

func (*AtPadding) Type

func (a *AtPadding) Type() AttributeType

func (*AtPadding) Unmarshal

func (a *AtPadding) Unmarshal(data []byte) error

type AtPermanentIdReq

type AtPermanentIdReq struct {
}

AT_PERMANENT_ID_REQ (RFC 4187 Section 10.2)

func (*AtPermanentIdReq) Marshal

func (a *AtPermanentIdReq) Marshal() ([]byte, error)

func (*AtPermanentIdReq) Type

func (a *AtPermanentIdReq) Type() AttributeType

func (*AtPermanentIdReq) Unmarshal

func (a *AtPermanentIdReq) Unmarshal(data []byte) error

type AtRand

type AtRand struct {
	Rand []byte // 16 bytes
}

AT_RAND (RFC 4187 Section 10.6)

func (*AtRand) Marshal

func (a *AtRand) Marshal() ([]byte, error)

func (*AtRand) Type

func (a *AtRand) Type() AttributeType

func (*AtRand) Unmarshal

func (a *AtRand) Unmarshal(data []byte) error

type AtRes

type AtRes struct {
	Res []byte // Variable length
}

AT_RES (RFC 4187 Section 10.8)

func (*AtRes) Marshal

func (a *AtRes) Marshal() ([]byte, error)

func (*AtRes) Type

func (a *AtRes) Type() AttributeType

func (*AtRes) Unmarshal

func (a *AtRes) Unmarshal(data []byte) error

type AtResultInd

type AtResultInd struct {
}

AT_RESULT_IND (RFC 4187 Section 10.14)

func (*AtResultInd) Marshal

func (a *AtResultInd) Marshal() ([]byte, error)

func (*AtResultInd) Type

func (a *AtResultInd) Type() AttributeType

func (*AtResultInd) Unmarshal

func (a *AtResultInd) Unmarshal(data []byte) error

type AtSelectedVersion

type AtSelectedVersion struct {
	Version uint16
}

AT_SELECTED_VERSION (RFC 4186 Section 10.5)

func (*AtSelectedVersion) Marshal

func (a *AtSelectedVersion) Marshal() ([]byte, error)

func (*AtSelectedVersion) Type

func (a *AtSelectedVersion) Type() AttributeType

func (*AtSelectedVersion) Unmarshal

func (a *AtSelectedVersion) Unmarshal(data []byte) error

type AtVersionList

type AtVersionList struct {
	Versions []uint16
}

AT_VERSION_LIST (RFC 4186 Section 10.4)

func (*AtVersionList) Marshal

func (a *AtVersionList) Marshal() ([]byte, error)

func (*AtVersionList) Type

func (a *AtVersionList) Type() AttributeType

func (*AtVersionList) Unmarshal

func (a *AtVersionList) Unmarshal(data []byte) error

type Attribute

type Attribute interface {
	// Type returns the attribute type (e.g., AT_RAND).
	Type() AttributeType

	// Marshal serializes the attribute into a byte slice, including padding.
	Marshal() ([]byte, error)

	// Unmarshal parses the value part of the attribute.
	Unmarshal(data []byte) error
}

Attribute is the interface implemented by all EAP-AKA attributes.

func BuildKdfOfferAttributes

func BuildKdfOfferAttributes(values []uint16) ([]Attribute, error)

BuildKdfOfferAttributes builds a list of AT_KDF attributes from ordered values.

func BuildKdfReofferAttributes

func BuildKdfReofferAttributes(offer []uint16, selected uint16) ([]Attribute, error)

BuildKdfReofferAttributes builds a re-offer list after a peer selection. The selected value is added to the front and the full original list is retained.

func BuildKdfResponseAttributes

func BuildKdfResponseAttributes(selected uint16) ([]Attribute, error)

BuildKdfResponseAttributes builds a peer response with a single AT_KDF value.

type AttributeType

type AttributeType uint8

Attribute Types (RFC 4187 Section 10.15)

const (
	AT_RAND              AttributeType = 1   // RFC 4187 Section 10.6
	AT_AUTN              AttributeType = 2   // RFC 4187 Section 10.7
	AT_RES               AttributeType = 3   // RFC 4187 Section 10.8
	AT_AUTS              AttributeType = 4   // RFC 4187 Section 10.9
	AT_PADDING           AttributeType = 6   // RFC 4187 Section 10.12
	AT_NONCE_MT          AttributeType = 7   // RFC 4186 Section 10.1
	AT_PERMANENT_ID_REQ  AttributeType = 10  // RFC 4187 Section 10.2
	AT_MAC               AttributeType = 11  // RFC 4187 Section 10.15
	AT_NOTIFICATION      AttributeType = 12  // RFC 4187 Section 10.19
	AT_ANY_ID_REQ        AttributeType = 13  // RFC 4187 Section 10.3
	AT_IDENTITY          AttributeType = 14  // RFC 4187 Section 10.5
	AT_VERSION_LIST      AttributeType = 15  // RFC 4186 Section 10.4
	AT_SELECTED_VERSION  AttributeType = 16  // RFC 4186 Section 10.5
	AT_FULLAUTH_ID_REQ   AttributeType = 17  // RFC 4187 Section 10.4
	AT_COUNTER           AttributeType = 19  // RFC 4187 Section 10.16
	AT_COUNTER_TOO_SMALL AttributeType = 20  // RFC 4187 Section 10.17
	AT_NONCE_S           AttributeType = 21  // RFC 4187 Section 10.18
	AT_CLIENT_ERROR_CODE AttributeType = 22  // RFC 4187 Section 10.20
	AT_KDF_INPUT         AttributeType = 23  // RFC 9048 Section 3.1 (format)
	AT_KDF               AttributeType = 24  // RFC 9048 Section 3.2 (format)
	AT_IV                AttributeType = 129 // RFC 4187 Section 10.12
	AT_ENCR_DATA         AttributeType = 130 // RFC 4187 Section 10.12
	AT_NEXT_PSEUDONYM    AttributeType = 132 // RFC 4187 Section 10.10
	AT_NEXT_REAUTH_ID    AttributeType = 133 // RFC 4187 Section 10.11
	AT_CHECKCODE         AttributeType = 134 // RFC 4187 Section 10.13
	AT_RESULT_IND        AttributeType = 135 // RFC 4187 Section 10.14
	AT_BIDDING           AttributeType = 136 // RFC 9048 Section 4 (format)
)

type GenericAttribute

type GenericAttribute struct {
	AttrType AttributeType
	Data     []byte
}

GenericAttribute for unknown types

func (*GenericAttribute) Marshal

func (a *GenericAttribute) Marshal() ([]byte, error)

func (*GenericAttribute) Type

func (a *GenericAttribute) Type() AttributeType

func (*GenericAttribute) Unmarshal

func (a *GenericAttribute) Unmarshal(data []byte) error

type Packet

type Packet struct {
	// Code indicates the EAP Code (e.g., Request, Response).
	// See RFC 3748 Section 4.
	Code uint8

	// Identifier handles request/response matching.
	Identifier uint8

	// Type indicates the EAP Method Type.
	// Use TypeAKA (23) or TypeAKAPrime (50).
	// This field is ignored if Code is Success(3) or Failure(4).
	Type uint8

	// Subtype indicates the EAP-AKA Subtype (e.g., Challenge, Synchronization-Failure).
	// See RFC 4187 Section 11.
	Subtype uint8

	// Attributes contains the list of EAP-AKA attributes.
	Attributes []Attribute
}

Packet represents an EAP packet including EAP-AKA/AKA' specific data. It supports both EAP-Request/Response (with attributes) and EAP-Success/Failure (header only).

func Parse

func Parse(data []byte) (*Packet, error)

Parse parses an EAP packet from a byte slice.

Example
// Raw bytes example (EAP-Success: Code=3, ID=1, Len=4)
raw := []byte{0x03, 0x01, 0x00, 0x04}

pkt, _ := eapaka.Parse(raw)

switch pkt.Code {
case eapaka.CodeSuccess:
	fmt.Println("Auth Success")
case eapaka.CodeRequest:
	if pkt.Type == eapaka.TypeAKA {
		fmt.Println("AKA Request")
	}
}
Output:

Auth Success

func (*Packet) CalculateAndSetMac

func (p *Packet) CalculateAndSetMac(kAut []byte) error

CalculateAndSetMac calculates the MAC for the packet and updates the AT_MAC attribute. It requires the K_aut key.

func (*Packet) Marshal

func (p *Packet) Marshal() ([]byte, error)

Marshal serializes the EAP packet into a byte slice.

func (*Packet) VerifyMac

func (p *Packet) VerifyMac(kAut []byte) (bool, error)

VerifyMac verifies the MAC in the packet against the provided K_aut.

Jump to

Keyboard shortcuts

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