iclass

package
v0.167.0 Latest Latest
Warning

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

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

Documentation

Overview

Package iclass implements the iCLASS block cipher and the loclass key-recovery attack against HID iCLASS Elite / High Security readers.

Algorithm derivation: Garcia, de Koning Gans, Verdult, Meriac — "Dismantling iClass and iClass Elite", ESORICS 2012, LNCS vol. 7459. Meriac — "Heart of Darkness", 27C3 (2010). Swende — "Elite iClass Hacking", swende.se blog (2014).

License posture: clean-reimpl. Algorithm derived from the published academic papers above. No source code from iceman/proxmark3 (GPLv2) or holiman/loclass (GPLv2) was copied verbatim. Sub-primitive test vectors are public facts about the algorithm.

Index

Constants

View Source
const CaptureSize = 24

CaptureSize is the on-disk size of one Capture record.

Variables

View Source
var StandardMasterKeyAA0 = [8]byte{0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78}

StandardMasterKeyAA0 is the globally-shared iCLASS Standard Security debit (AA1) master key, published by Meriac at 27C3 (2010) and confirmed by independent researchers. Every Standard-Security-keyed card at every site uses this. Not a secret — it is ubiquitous public information.

Functions

func DiversifyKey

func DiversifyKey(csn [8]byte, keyStd [8]byte) ([8]byte, error)

DiversifyKey derives the per-card iCLASS key by computing hash0(DES_enc(key_std, csn)), where key_std is the standard-format master key. (García et al. §3 — "k = hash0(DES_enc(id, K))".)

func DoReaderMAC

func DoReaderMAC(ccNR [12]byte, divKey [8]byte) [4]byte

DoReaderMAC computes the 4-byte iCLASS reader MAC over the 12-byte challenge ccNR = CC(8) || NR(4), using the diversified key divKey.

Processing order: each input byte is fed LSB-first. Output bits are collected LSB-first into the 4-byte MAC. This matches the opt_doReaderMAC / doReaderMAC implementations in the reference code.

func Hash0

func Hash0(c uint64) [8]byte

Hash0 computes the iCLASS key diversification function hash0. Input c is the big-endian uint64 of an 8-byte DES-encrypted CSN. Output is the 8-byte diversified key. (Definition 11, García et al. ESORICS 2012.)

func Hash1

func Hash1(csn [8]byte) [8]byte

Hash1 computes the 8 keytable indices for a given CSN. Each output byte is in [0, 127] (high bit cleared).

func Hash2

func Hash2(kcus [8]byte) ([128]byte, error)

Hash2 derives the 128-byte iCLASS Elite high-security keytable from the 8-byte custom master key Kcus (in iClass internal format).

Layout: keytable[i*16..i*16+7] = y[i], keytable[i*16+8..i*16+15] = z[i].

func InvertHash2

func InvertHash2(first16 [16]byte) ([8]byte, error)

InvertHash2 recovers the 8-byte Kcus from the first 16 bytes of the Elite keytable (y[0] || z[0]).

From the paper: K_cus = ~DES_enc(permutekey_rev(z[0]), y[0])

func PermuteKey

func PermuteKey(key [8]byte) [8]byte

PermuteKey converts a key from NIST/standard DES format to iClass internal format by transposing the 8×8 bit matrix (row i of output = column i of input). permutekey() in the holiman/loclass reference.

func PermuteKeyRev

func PermuteKeyRev(key [8]byte) [8]byte

PermuteKeyRev converts a key from iClass internal format to NIST/standard DES format (inverse of PermuteKey). permutekey_rev() in the reference.

func Recover

func Recover(ctx context.Context, captures []Capture) ([8]byte, string, error)

Recover performs the loclass attack against the provided capture set and returns the 8-byte Kcus (iClass custom master key) together with a hex string representation.

The attack requires captures whose CSN Hash1 outputs collectively cover all keytable indices 0..15. With Swende-optimal CSN selection, 8 captures suffice; with arbitrary CSNs more may be needed. Iterates until all 16 positions are recovered or no progress is made.

ctx is checked periodically in the brute-force loop.

func WriteCaptures

func WriteCaptures(w io.Writer, caps []Capture) error

WriteCaptures writes all captures to w in binary format.

Types

type Capture

type Capture struct {
	CSN [8]byte
	CC  [8]byte // EPURSE (card challenge)
	NR  [4]byte // reader nonce
	MAC [4]byte // reader MAC over CC||NR
}

Capture holds one iCLASS reader-authentication exchange. Wire format (proxmark3 binary, 24 bytes): CSN(8) || CC(8) || NR(4) || MAC(4).

func GenerateCaptures

func GenerateCaptures(kcus [8]byte, n int, rng *rand.Rand) ([]Capture, error)

GenerateCaptures synthesises N authentication captures for the given Kcus. CSNs are chosen so that their Hash1 indices cover positions 0..15. CC is fixed at zero (as in the standard simulation). NR is random.

Returns an error if sufficient coverage cannot be achieved.

func ParseCaptures

func ParseCaptures(r io.Reader) ([]Capture, error)

ParseCaptures reads Capture records from an io.Reader until EOF.

func ParseCapturesFromFile

func ParseCapturesFromFile(path string) ([]Capture, error)

ParseCapturesFromFile reads a binary capture file and returns all records.

func ParseCapturesHex

func ParseCapturesHex(hexData string) ([]Capture, error)

ParseCapturesHex parses a sequence of captures from a hex string (pm3 text format or raw hex). Each capture is exactly 48 hex chars (24 bytes).

type State

type State struct {
	// contains filtered or unexported fields
}

State is the 40-bit iCLASS stream-cipher state, as defined in Definition 1 of García et al. ESORICS 2012. Components:

  • l, r: 8-bit left/right registers
  • b: 8-bit bottom register
  • t: 16-bit top register (LFSR)

func InitState

func InitState(k [8]byte) State

InitState returns the initial cipher state for the given 8-byte key, per Definition 6 of García et al. ESORICS 2012.

func (State) OutputBit

func (s State) OutputBit() uint8

OutputBit returns the cipher output bit from state s. The output is bit 2 of the r register (Definition 5, García et al.).

func (State) Successor

func (s State) Successor(k [8]byte, y uint8) State

Successor advances the cipher by one clock given key k and input bit y. (Definition 4, García et al. ESORICS 2012.)

Jump to

Keyboard shortcuts

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