Skip to content

Commit

Permalink
Merge pull request #2694 from klks/master
Browse files Browse the repository at this point in the history
Add annotations for FMCOS2.0 CPU Card
  • Loading branch information
iceman1001 authored Dec 20, 2024
2 parents e5bee8d + df3916c commit a87f5d8
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 0 deletions.
164 changes: 164 additions & 0 deletions client/src/cmdhflist.c
Original file line number Diff line number Diff line change
Expand Up @@ -2373,3 +2373,167 @@ uint64_t GetCrypto1ProbableKey(AuthData_t *ad) {
crypto1_destroy(revstate);
return key;
}

// FMCOS 2.0
void annotateFMCOS20(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {

if (cmdsize < 2)
return;

int pos = 0;
switch (cmd[0]) {
case 2:
case 3:
pos = 2;
break;
case 0:
pos = 1;
break;
default:
pos = 3;
break;
}
switch (cmd[pos]) {
case FMCOS20_CMD_EXTERNAL_AUTHENTICATION:
snprintf(exp, size, "EXT. AUTH");
break;
case FMCOS20_CMD_GET_CHALLENGE:
snprintf(exp, size, "GET CHALLENGE");
break;
case FMCOS20_CMD_INTERNAL_AUTHENTICATION:
snprintf(exp, size, "INT. AUTH");
break;
case FMCOS20_CMD_SELECT:
snprintf(exp, size, "SELECT");
break;
case FMCOS20_CMD_VERIFY_PIN:
snprintf(exp, size, "VERIFY PIN");
break;
case FMCOS20_CMD_READ_BINARY:
snprintf(exp, size, "READ BINARY");
break;
case FMCOS20_CMD_READ_RECORD:
snprintf(exp, size, "READ RECORD");
break;
case FMCOS20_CMD_UPDATE_BINARY:
snprintf(exp, size, "UPDATE BINARY");
break;
case FMCOS20_CMD_UPDATE_RECORD:
snprintf(exp, size, "UPDATE RECORD");
break;
case FMCOS20_CMD_APPEND_RECORD:
snprintf(exp, size, "APPEND RECORD");
break;
case FMCOS20_CMD_ERASE_DF:
snprintf(exp, size, "ERASE DF");
break;
case FMCOS20_CMD_WRITE_KEY:
snprintf(exp, size, "WRITE KEY");
break;
case FMCOS20_CMD_CREATE_FILE:
snprintf(exp, size, "CREATE FILE");
break;
case FMCOS20_CMD_CARD_BLOCK:
snprintf(exp, size, "CARD BLOCK");
break;
case FMCOS20_CMD_APP_UNBLOCK:
snprintf(exp, size, "APP UNBLOCK");
break;
case FMCOS20_CMD_APP_BLOCK:
if (cmd[pos+1] == 0)
snprintf(exp, size, "APP BLOCK (TEMP)");
else if(cmd[pos+1] == 1)
snprintf(exp, size, "APP BLOCK (PERM)");
else
snprintf(exp, size, "APP BLOCK");
break;
case FMCOS20_CMD_PIN_UNBLOCK:
snprintf(exp, size, "PIN UNBLOCK");
break;
case FMCOS20_CMD_CHANGE_PIN:
if (cmd[pos+1] == 0)
snprintf(exp, size, "RESET PIN");
else if (cmd[pos+1] == 1)
snprintf(exp, size, "CHANGE PIN");
break;
case FMCOS20_CMD_INITIALIZE_TRANSACTION:
if (cmd[pos+1] == 0)
snprintf(exp, size, "INIT. TRANSACTION (CREDIT)");
else if (cmd[pos+1] == 1)
snprintf(exp, size, "INIT. TRANSACTION (PURCHASE)");
else if (cmd[pos+1] == 2)
snprintf(exp, size, "INIT. TRANSACTION (CASH WITHDRAW)");
else if (cmd[pos+1] == 3)
snprintf(exp, size, "INIT. TRANSACTION (CAPP PURCHASE)");
else if (cmd[pos+1] == 4)
snprintf(exp, size, "INIT. TRANSACTION (OVERDRAFT)");
else if (cmd[pos+1] == 5)
snprintf(exp, size, "INIT. TRANSACTION (WITHDRAW)");
break;
case FMCOS20_CMD_CREDIT_LOAD:
snprintf(exp, size, "CREDIT LOAD");
break;
case FMCOS20_CMD_PURCHASE:
if(cmd[pos+1] == 0)
snprintf(exp, size, "PURCHASE");
else if (cmd[pos+1] == 1)
snprintf(exp, size, "CAPP PURCHASE / CASH WITHDRAW");
else if (cmd[pos+1] == 3)
snprintf(exp, size, "WITHDRAW");
break;
case FMCOS20_CMD_UPDATE_OVERDRAW_LIMIT:
snprintf(exp, size, "UPDATE OVERDRAFT");
break;
case FMCOS20_CMD_GET_TRANSACTION_PROOF:
snprintf(exp, size, "TRANSACTION RECORD");
break;
case FMCOS20_CMD_GET_BALANCE:
snprintf(exp, size, "GET BALANCE");
break;
case FMCOS20_CMD_INITIALIZE_GREY_LOCK_UNLOCK:
if (cmd[pos+1] == 8)
snprintf(exp, size, "INIT. GRAY LOCK");
else if (cmd[pos+1] == 9)
snprintf(exp, size, "INIT. GRAY UNLOCK");
break;
case FMCOS20_CMD_GREY_LOCK_UNLOCK:
if (cmd[pos+1] == 8)
snprintf(exp, size, "GRAY LOCK");
else if (cmd[pos+1] == 9)
snprintf(exp, size, "GRAY UNLOCK");
break;
case FMCOS20_CMD_DEBIT_UNLOCK:
snprintf(exp, size, "DEBIT UNLOCK");
break;
case FMCOS20_CMD_CALCULATE_ROM_CRC:
snprintf(exp, size, "CALC. ROM CRC");
break;
case FMCOS20_CMD_GET_RESPONSE:
snprintf(exp, size, "GET RESPONSE");
break;
case FMCOS20_CMD_UNBLOCK:
snprintf(exp, size, "UNBLOCK");
break;
case FMCOS20_CMD_PULL:
snprintf(exp, size, "PULL");
break;
case FMCOS20_CMD_CHARGE:
snprintf(exp, size, "CHARGE");
break;
case FMCOS20_CMD_WRITE_EEPROM:
snprintf(exp, size, "WRITE EEPROM");
break;
case FMCOS20_CMD_READ_EEPROM:
snprintf(exp, size, "READ EEPROM");
break;
case FMCOS20_CMD_INITIALIZE_EEPROM:
snprintf(exp, size, "INIT. EEPROM");
break;
case FMCOS20_CMD_READ_ROM:
snprintf(exp, size, "READ ROM");
break;
default:
//snprintf(exp, size, "?");
break;
}
}
2 changes: 2 additions & 0 deletions client/src/cmdhflist.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,6 @@ bool NestedCheckKey(uint64_t key, AuthData_t *ad, uint8_t *cmd, uint8_t cmdsize,
bool CheckCrypto1Parity(const uint8_t *cmd_enc, uint8_t cmdsize, uint8_t *cmd, const uint8_t *parity_enc);
uint64_t GetCrypto1ProbableKey(AuthData_t *ad);

void annotateFMCOS20(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);

#endif // CMDHFLIST
10 changes: 10 additions & 0 deletions client/src/cmdtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
switch (protocol) {
case ISO_14443A:
case ISO_7816_4:
case PROTO_FMCOS20:
annotateIso14443a(explanation, sizeof(explanation), frame, data_len, hdr->isResponse);
break;
case PROTO_MIFARE:
Expand Down Expand Up @@ -836,6 +837,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
case SEOS:
annotateSeos(explanation, sizeof(explanation), frame, data_len);
break;
case PROTO_FMCOS20:
annotateFMCOS20(explanation, sizeof(explanation), frame, data_len);
break;
default:
break;
}
Expand Down Expand Up @@ -1310,6 +1314,7 @@ int CmdTraceList(const char *Cmd) {
"trace list -t thinfilm -> interpret as " _YELLOW_("Thinfilm") "\n"
"trace list -t topaz -> interpret as " _YELLOW_("Topaz") "\n"
"trace list -t mfp -> interpret as " _YELLOW_("MIFARE Plus") "\n"
"trace list -t fmcos20 -> interpret as " _YELLOW_("FMCOS 2.0") "\n"
"\n"
"trace list -t mf -f mfc_default_keys.dic -> use default dictionary file\n"
"trace list -t 14a --frame -> show frame delay times\n"
Expand Down Expand Up @@ -1377,6 +1382,7 @@ int CmdTraceList(const char *Cmd) {
else if (strcmp(type, "thinfilm") == 0) protocol = THINFILM;
else if (strcmp(type, "topaz") == 0) protocol = TOPAZ;
else if (strcmp(type, "mfp") == 0) protocol = PROTO_MFPLUS;
else if (strcmp(type, "fmcos20") == 0) protocol = PROTO_FMCOS20;
else if (strcmp(type, "") == 0) protocol = -1;
else {
PrintAndLogEx(FAILED, "Unknown protocol \"%s\"", type);
Expand Down Expand Up @@ -1460,6 +1466,10 @@ int CmdTraceList(const char *Cmd) {
PrintAndLogEx(INFO, _YELLOW_("Hitag 1 / Hitag 2 / Hitag S") " - Timings in ETU (8us)");
}

if (protocol == PROTO_FMCOS20) {
PrintAndLogEx(INFO, _YELLOW_("FMCOS 2.0 / CPU Card") " - Timings n/a");
}

if (protocol == FELICA) {
if (use_us)
PrintAndLogEx(INFO, _YELLOW_("ISO18092 / FeliCa") " - all times are in microseconds");
Expand Down
1 change: 1 addition & 0 deletions doc/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -12837,6 +12837,7 @@
"trace list -t thinfilm -> interpret as Thinfilm",
"trace list -t topaz -> interpret as Topaz",
"trace list -t mfp -> interpret as MIFARE Plus",
"trace list -t fmcos20 -> interpret as FMCOS 2.0",
"",
"trace list -t mf -f mfc_default_keys.dic -> use default dictionary file",
"trace list -t 14a --frame -> show frame delay times",
Expand Down
39 changes: 39 additions & 0 deletions include/protocols.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
#define PROTO_MFPLUS 17
#define PROTO_TEXKOM 18
#define PROTO_XEROX 19
#define PROTO_FMCOS20 20

// Picopass fuses
#define FUSE_FPERS 0x80
Expand Down Expand Up @@ -950,5 +951,43 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
// 0x0A = ACK
// 0x05 = NACK

//FMCOS2.0
#define FMCOS20_CMD_VERIFY_PIN 0x20
#define FMCOS20_CMD_EXTERNAL_AUTHENTICATION 0x82
#define FMCOS20_CMD_GET_CHALLENGE 0x84
#define FMCOS20_CMD_INTERNAL_AUTHENTICATION 0x88
#define FMCOS20_CMD_SELECT 0xA4
#define FMCOS20_CMD_READ_BINARY 0xB0
#define FMCOS20_CMD_READ_RECORD 0xB2
#define FMCOS20_CMD_GET_RESPONSE 0xC0
#define FMCOS20_CMD_UPDATE_BINARY 0xD6
#define FMCOS20_CMD_UPDATE_RECORD 0xDC
#define FMCOS20_CMD_APPEND_RECORD 0xE2
#define FMCOS20_CMD_CARD_BLOCK 0x16
#define FMCOS20_CMD_APP_UNBLOCK 0x18
#define FMCOS20_CMD_APP_BLOCK 0x1E
#define FMCOS20_CMD_PIN_UNBLOCK 0x24
#define FMCOS20_CMD_UNBLOCK 0x2C
#define FMCOS20_CMD_INITIALIZE_TRANSACTION 0x50
#define FMCOS20_CMD_CREDIT_LOAD 0x52
#define FMCOS20_CMD_PURCHASE 0x54
#define FMCOS20_CMD_UPDATE_OVERDRAW_LIMIT 0x58
#define FMCOS20_CMD_GET_TRANSACTION_PROOF 0x5A
#define FMCOS20_CMD_GET_BALANCE 0x5C
#define FMCOS20_CMD_CHANGE_PIN 0x5E
#define FMCOS20_CMD_ERASE_DF 0x0E
#define FMCOS20_CMD_PULL 0x30
#define FMCOS20_CMD_CHARGE 0x32
#define FMCOS20_CMD_WRITE_KEY 0xD4
#define FMCOS20_CMD_CREATE_FILE 0xE0
#define FMCOS20_CMD_WRITE_EEPROM 0x00
#define FMCOS20_CMD_READ_EEPROM 0x04
#define FMCOS20_CMD_INITIALIZE_EEPROM 0x02
#define FMCOS20_CMD_READ_ROM 0x0C
#define FMCOS20_CMD_INITIALIZE_GREY_LOCK_UNLOCK 0x7A
#define FMCOS20_CMD_GREY_LOCK_UNLOCK 0x7C
#define FMCOS20_CMD_DEBIT_UNLOCK 0x7E
#define FMCOS20_CMD_CALCULATE_ROM_CRC 0x0A

#endif
// PROTOCOLS_H

0 comments on commit a87f5d8

Please sign in to comment.