Back to Proxmark3

arbitrary lf em commands

doc/md/em4x70/arbitrary_lf_em_commands.md

4.92374.7 KB
Original Source

arbitrary lf em commands

Goals:

  1. Improved logging of lf em commands and responses
  2. Greater certainty in command sequences
  3. Easier testing of new commands

Methodology

This is documenting the actual commands used by existing code. Phases include:

  • Document the existing command sequences
  • Document the existing logging APIs
  • Define small set of timing-sensitive functions as abstractions
  • Implement the abstractions
  • Add logging

The goal is to improve logging and debugging, and allow easily testing new LF commands.

EM4x70 (aka ID48, aka Megamos)

Only six command sequences currently used:

#define EM4X70_COMMAND_ID 0x01 #define EM4X70_COMMAND_UM1 0x02 #define EM4X70_COMMAND_AUTH 0x03 #define EM4X70_COMMAND_PIN 0x04 #define EM4X70_COMMAND_WRITE 0x05 #define EM4X70_COMMAND_UM2 0x07

ID Command

Wait for LIW (listen window), and start transmission at next LIW:

sourcebitscomment
tagLIWlisten window sync
reader0b00RM
reader0b001CMD
reader0b1command parity bit
tagHEADERHEADER (0b1111'1111'1111'0000)
tag32-bitsID (D31..D0)
tagLIWtag reverts to be ready for next command

UM1 Command

sourcebitscomment
tagLIWlisten window
reader0b00RM
reader0b010CMD
reader0b1command parity bit
tag16-bitsHEADER
tag32-bitsUM1 data
tagLIWtag reverts to be ready for next command

UM2 Command

sourcebitscomment
tagLIWlisten window
reader0b00RM
reader0b111CMD
reader0b1command parity bit
tag16-bitsHEADER
tag64-bitsUM2 data
tagLIWtag reverts to be ready for next command

Auth Command

sourcebitscomment
tagLIWlisten window
reader0b00RM
reader0b011CMD
reader0b0command parity bit
reader56-bitsRN
reader7-bitsTdiv == 0b0000000 (always zero)
reader28-bitsf(RN)
tag16-bitsHEADER
tag20-bitsg(RN)
tagLIWtag reverts to be ready for next command

Write Word

sourcebitscomment
tagLIWlisten window
reader0b00RM
reader0b101CMD
reader0b0command parity bit
reader4-bitsaddress/block to write
reader1-bitaddress/block parity bit
reader25-bits5x5 data w/ row and column parity
tagACKWait (TWA) for ACK ... time to wait before searching for ACK
tagACKWait (WEE) for ACK ... time to wait before searching for ACK
tagLIWtag reverts to be ready for next command

PIN Command

sourcebitscomment
tagLIWlisten window
reader0b00RM
reader0b100CMD
reader0b1command parity bit
reader32-bitsID of the tag
reader32-bitsPIN
tagACKWait (TWALB) for ACK ... time to wait before searching for ACK
tagHEADERDELAYED (TWEE) header ... time to wait before searching for header
tag32-bitsID of the tag
tagLIWtag reverts to be ready for next command

Abstraction required

Possible items to abstract:

  • bits to send: quantity of bits to be sent + storage containing those bits
  • bits to receive: expected bits to receive + storage to receive those bits
  • LIW: special-case handling to synchronize next command
  • ACK: special-case handling to wait for ACK
  • HEADER: special-case handling to wait for HEADER
  • DELAY: ticks to delay before processing next item

Special handling required for:

  • HEADER --> 12-bits of zero, 4-bits of one. Consider a timeout: if tag disappears, no pulse found, while sometimes expect long time before HEADER appears (as in SEND_PIN). Read of header may miss the first few bits during transition, so need to special-case handling of this detection.
  • LIW --> Timing-sensitive, syncs reader with tag ... reader must send during 32 period where chip's modulator is ON.
  • ACK --> This is currently a time-to-delay. Should this be a maximum time to wait for ACK? Currently, could sit waiting for long time if no tag present, as check_ack() has no timeout.
C
WaitTicks(EM4X70_T_TAG_TWA);
if (check_ack())
    WaitTicks(EM4X70_T_TAG_WEE);
    if (check_ack())
        return PM3_SUCCESS;