diff --git a/client/cmdhflist.c b/client/cmdhflist.c index 7a46b5deb..589a81365 100644 --- a/client/cmdhflist.c +++ b/client/cmdhflist.c @@ -1095,6 +1095,49 @@ void annotateFelica(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { } } +void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { + switch (cmd[0]) { + case LTO_REQ_STANDARD: + snprintf(exp, size, "REQ Standard"); + break; + case LTO_SELECT: + snprintf(exp, size, "SELECT"); + break; + case LTO_SELECT_1: + snprintf(exp, size, "SELECT_1"); + break; + case LTO_REQ_ALL: + snprintf(exp, size, "REQ All"); + break; + case LTO_TEST_CMD_1: + snprintf(exp, size, "TEST CMD 1"); + break; + case LTO_TEST_CMD_2: + snprintf(exp, size, "TEST CMD 2"); + break; + case LTO_READWORD: + snprintf(exp, size, "READWORD"); + break; + case (LTO_READBLOCK & 0xF0): + snprintf(exp, size, "READBLOCK"); + break; + case LTO_READBLOCK_CONT: + snprintf(exp, size, "READBLOCK CONT"); + break; + case LTO_WRITEWORD: + snprintf(exp, size, "WRITEWORD"); + break; + case (LTO_WRITEBLOCK & 0xF0): + snprintf(exp, size, "WRITEBLOCK"); + break; + case LTO_HALT: + snprintf(exp, size, "HALT"); + break; + default: + break; + } +} + void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, uint8_t paritysize, bool isResponse) { if (!isResponse && cmdsize == 1) { switch (cmd[0]) { diff --git a/client/cmdhflist.h b/client/cmdhflist.h index 42ae6e83b..d13285bc4 100644 --- a/client/cmdhflist.h +++ b/client/cmdhflist.h @@ -48,6 +48,7 @@ void annotateIso14443b(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize); void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, uint8_t paritysize, bool isResponse); +void annotateLTO(char *explanation, size_t size, uint8_t *cmd, uint8_t cmdsize); bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, uint8_t *parity, bool isResponse, uint8_t *mfData, size_t *mfDataLen); bool NTParityChk(TAuthData *ad, uint32_t ntx); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 7e9b53548..51f5fad28 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -46,6 +46,7 @@ static int usage_trace_list() { PrintAndLogEx(NORMAL, " legic - interpret data as LEGIC communications"); PrintAndLogEx(NORMAL, " felica - interpret data as ISO18092 / FeliCa communications"); PrintAndLogEx(NORMAL, " hitag - interpret data as Hitag2 / HitagS communications"); + PrintAndLogEx(NORMAL, " lto - interpret data as LTO-CM communications"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " trace list 14a f"); @@ -264,6 +265,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr break; case ISO_14443A: case MFDES: + case LTO: crcStatus = iso14443A_CRC_check(isResponse, frame, data_len); break; case THINFILM: @@ -302,6 +304,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && protocol != PROTO_HITAG && protocol != THINFILM && protocol != FELICA + && protocol != LTO && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { @@ -378,6 +381,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr break; case FELICA: annotateFelica(explanation, sizeof(explanation), frame, data_len); + case LTO: + annotateLTO(explanation, sizeof(explanation), frame, data_len); break; default: break; @@ -589,6 +594,7 @@ int CmdTraceList(const char *Cmd) { else if (strcmp(type, "mf") == 0) protocol = PROTO_MIFARE; else if (strcmp(type, "hitag") == 0) protocol = PROTO_HITAG; else if (strcmp(type, "thinfilm") == 0) protocol = THINFILM; + else if (strcmp(type, "lto") == 0) protocol = LTO; else if (strcmp(type, "raw") == 0) protocol = -1; //No crc, no annotations else errors = true; @@ -651,7 +657,7 @@ int CmdTraceList(const char *Cmd) { } } else { PrintAndLogEx(NORMAL, "Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); - if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ) + if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ || protocol == LTO) PrintAndLogEx(NORMAL, "ISO14443A - All times are in carrier periods (1/13.56MHz)"); if (protocol == THINFILM) PrintAndLogEx(NORMAL, "Thinfilm - All times are in carrier periods (1/13.56MHz)"); diff --git a/include/protocols.h b/include/protocols.h index d04173557..857cb2a4a 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -307,6 +307,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define PROTO_MIFARE 9 #define PROTO_HITAG 10 #define THINFILM 11 +#define LTO 12 //-- Picopass fuses #define FUSE_FPERS 0x80