added a compact tlv decoder for ATR historical bytes in 14a info

This commit is contained in:
iceman1001 2022-02-19 00:15:34 +01:00
commit 7310834b69
3 changed files with 90 additions and 15 deletions

View file

@ -3,16 +3,17 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Changed `hf 14a info` - added a ATR historical compact TLV decoder (@iceman1001)
- Added `hf mf value` - decode a value block (@iceman1001)
- Changed `hf mf nested`: removed option `--single` redundant with usage of `--tblk` (@doegox)
- Fixed `hf mf chk` single block mode (@doegox)
- Fixed `hf mf fchk/chk` internal logic to load keys (@doegox)
- Changed `hf mf *` printKeyTable: now display sector trailer info too (@doegox)
- Changed `hf mf chk` option `--blk` into `--tblk` (as for nested) (@doegox)
- Changed `hf mf nested` - removed option `--single` redundant with usage of `--tblk` (@doegox)
- Fixed `hf mf chk` - single block mode (@doegox)
- Fixed `hf mf fchk/chk` - internal logic to load keys (@doegox)
- Changed `hf mf *` - printKeyTable: now display sector trailer info too (@doegox)
- Changed `hf mf chk` - option `--blk` into `--tblk` (as for nested) (@doegox)
- Added new tool `mfd_multi_brute` - MIFARE DESfire / UL-C key recovery (@iceman1001)
- Fixed `hf emrtd info` segfault on some platforms (@doegox)
- Fixed `hf emrtd info` when offline (@doegox)
- Fixed `commands.json` generation (@doegox)
- Fixed `hf emrtd info` - segfault on some platforms (@doegox)
- Fixed `hf emrtd info` - when offline (@doegox)
- Fixed `commands.json` - generation (@doegox)
- Added new standalone mode `hf_legicsim` (@uhei)
- Changed `hf legic *` - now uses NG instead (@iceman1001)
- Added `hf legic view` - view contents of LEGIC Prime dump files (@iceman1001)

View file

@ -1638,6 +1638,78 @@ static void getTagLabel(uint8_t uid0, uint8_t uid1) {
}
}
static void get_compact_tlv(uint8_t* d, uint8_t n) {
d++;
n--;
while (n > 0) {
uint8_t tag = NIBBLE_HIGH(d[0]);
uint8_t len = NIBBLE_LOW(d[0]);
switch(tag) {
case 1:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Country code in (ISO 3166-1)", tag, len, sprint_hex_inrow(d + 1, len));
// iso3166 script in cmdlffdb.c is buggy, Åland, Australia not showing. getline issues
break;
case 2:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Issuer identification number (ISO 7812-1)", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 3:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Card service data byte", tag, len, sprint_hex_inrow(d + 1, len));
PrintAndLogEx(INFO, " %c....... Application selection: by full DF name", (d[1] & 0x80) ? '1' : '0');
PrintAndLogEx(INFO, " .%c...... Application selection: by partial DF name", (d[1] & 0x40) ? '1' : '0');
PrintAndLogEx(INFO, " ..%c..... BER-TLV data objects available in EF.DIR", (d[1] & 0x20) ? '1' : '0');
PrintAndLogEx(INFO, " ...%c.... BER-TLV data objects available in EF.ATR", (d[1] & 0x10) ? '1' : '0');
PrintAndLogEx(INFO, " ....%c... EF.DIR and EF.ATR access services: by READ BINARY command", (d[1] & 0x08) ? '1' : '0');
PrintAndLogEx(INFO, " .....%c.. EF.DIR and EF.ATR access services: by GET DATA command", (d[1] & 0x04) ? '1' : '0');
PrintAndLogEx(INFO, " ......%c. EF.DIR and EF.ATR access services: by GET RECORD(s) command", (d[1] & 0x02) ? '1' : '0');
PrintAndLogEx(INFO, " .......%c EF.DIR and EF.ATR access services: RFU", (d[1] & 0x01) ? '1' : '0');
break;
case 4:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Initial access data", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 5:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Card issuer data", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 6:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Pre-issuing data", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 7:
PrintAndLogEx(INFO, " %1x%1x " _YELLOW_("%s") " Card capabilities", tag, len, sprint_hex_inrow(d + 1, len));
PrintAndLogEx(INFO, " " _YELLOW_("%02X") " - Selection methods", d[1]);
PrintAndLogEx(INFO, " %c....... DF selection by full DF name", (d[1] & 0x80) ? '1' : '0');
PrintAndLogEx(INFO, " .%c...... DF selection by partial DF name", (d[1] & 0x40) ? '1' : '0');
PrintAndLogEx(INFO, " ..%c..... DF selection by path", (d[1] & 0x20) ? '1' : '0');
PrintAndLogEx(INFO, " ...%c.... DF selection by file identifier", (d[1] & 0x10) ? '1' : '0');
PrintAndLogEx(INFO, " ....%c... Implicit DF selection", (d[1] & 0x08) ? '1' : '0');
PrintAndLogEx(INFO, " .....%c.. Short EF identifier supported", (d[1] & 0x04) ? '1' : '0');
PrintAndLogEx(INFO, " ......%c. Record number supported", (d[1] & 0x02) ? '1' : '0');
PrintAndLogEx(INFO, " .......%c Record identifier supported", (d[1] & 0x01) ? '1' : '0');
if (len > 1) {
PrintAndLogEx(INFO, " " _YELLOW_("%02X") " - Data coding byte", d[2]);
}
if (len > 2) {
PrintAndLogEx(INFO, " " _YELLOW_("%02X") " - Command chaining, length fields and logical channels", d[3]);
}
break;
case 8:
PrintAndLogEx(INFO, " %1x%1x ... " _YELLOW_("%s") " Status indicator", tag, len, sprint_hex_inrow(d + 1, len));
break;
case 0xE:
PrintAndLogEx(INFO, " %1x%1x ... " _YELLOW_("%s") " Application identifier", tag, len, sprint_hex_inrow(d + 1, len));
break;
}
if (len > n)
break;
n -= (1 + len);
d += (1 + len);
}
}
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0);
@ -2034,10 +2106,12 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
}
} else {
if (card.ats[pos] == 0x80)
PrintAndLogEx(SUCCESS, " %s (compact TLV data object)", sprint_hex_inrow(card.ats + pos, calen));
else
if (card.ats[pos] == 0x80 || card.ats[pos] == 0x00) {
PrintAndLogEx(SUCCESS, " %s (compact TLV data object)", sprint_hex_inrow(&card.ats[pos], calen));
get_compact_tlv(card.ats + pos, calen);
} else {
PrintAndLogEx(SUCCESS, " %s", sprint_hex_inrow(card.ats + pos, calen));
}
PrintAndLogEx(NORMAL, "");
}

View file

@ -158,11 +158,11 @@ extern bool g_tearoff_enabled;
// Nibble logic
#ifndef NIBBLE_HIGH
# define NIBBLE_HIGH(b) ( (b & 0xF0) >> 4 )
# define NIBBLE_HIGH(b) ( ((b) & 0xF0) >> 4 )
#endif
#ifndef NIBBLE_LOW
# define NIBBLE_LOW(b) ( b & 0x0F )
# define NIBBLE_LOW(b) ((b) & 0x0F )
#endif
#ifndef CRUMB