mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-09-21 15:26:35 +08:00
add: start to support Topaz tags
- hf 14a reader now exits gracefully in case of proprietary anticollision sequence - changed miller decoder to handle Topaz 8 data bits/no parity frames from reader - started to implement hf list topaz
This commit is contained in:
parent
9185099ed8
commit
ee1eadee0f
|
@ -1719,6 +1719,11 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
|||
memset(uid_ptr,0,10);
|
||||
}
|
||||
|
||||
// check for proprietary anticollision:
|
||||
if ((resp[0] & 0x1F) == 0) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
|
||||
// which case we need to make a cascade 2 request and select - this is a long UID
|
||||
// While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef struct {
|
|||
// DROP_FIRST_HALF,
|
||||
} state;
|
||||
uint16_t shiftReg;
|
||||
uint16_t bitCount;
|
||||
int16_t bitCount;
|
||||
uint16_t len;
|
||||
uint16_t byteCntMax;
|
||||
uint16_t posCnt;
|
||||
|
|
|
@ -141,6 +141,23 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||
{
|
||||
|
||||
switch(cmd[0]) {
|
||||
case TOPAZ_REQA :snprintf(exp, size, "REQA");break;
|
||||
case TOPAZ_WUPA :snprintf(exp, size, "WUPA");break;
|
||||
case TOPAZ_RID :snprintf(exp, size, "RID");break;
|
||||
case TOPAZ_RALL :snprintf(exp, size, "RALL");break;
|
||||
case TOPAZ_READ :snprintf(exp, size, "READ");break;
|
||||
case TOPAZ_WRITE_E :snprintf(exp, size, "WRITE-E");break;
|
||||
case TOPAZ_WRITE_NE :snprintf(exp, size, "WRITE-NE");break;
|
||||
default: snprintf(exp,size,"?"); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
06 00 = INITIATE
|
||||
0E xx = SELECT ID (xx = Chip-ID)
|
||||
|
@ -255,11 +272,18 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
uint16_t merge_topaz_reader_frames(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t *topaz_reader_command, uint16_t *data_len)
|
||||
{
|
||||
return tracepos;
|
||||
}
|
||||
|
||||
|
||||
uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
|
||||
{
|
||||
bool isResponse;
|
||||
uint16_t duration, data_len, parity_len;
|
||||
|
||||
uint8_t topaz_reader_command[9];
|
||||
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
|
||||
char explanation[30] = {0};
|
||||
|
||||
|
@ -290,29 +314,35 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
|||
uint8_t *parityBytes = trace + tracepos;
|
||||
tracepos += parity_len;
|
||||
|
||||
if (protocol == TOPAZ && !isResponse) {
|
||||
// topaz reader commands come in 1 or 9 separate frames with 8 Bits each.
|
||||
// merge them:
|
||||
tracepos = merge_topaz_reader_frames(tracepos, traceLen, trace, topaz_reader_command, &data_len);
|
||||
}
|
||||
|
||||
//Check the CRC status
|
||||
uint8_t crcStatus = 2;
|
||||
|
||||
if (data_len > 2) {
|
||||
uint8_t b1, b2;
|
||||
if(protocol == ICLASS)
|
||||
{
|
||||
crcStatus = iclass_CRC_check(isResponse, frame, data_len);
|
||||
|
||||
}else if (protocol == ISO_14443B)
|
||||
{
|
||||
crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
|
||||
}
|
||||
else if (protocol == ISO_14443A){//Iso 14443a
|
||||
|
||||
ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
|
||||
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
if(!(isResponse & (data_len < 6)))
|
||||
{
|
||||
switch (protocol) {
|
||||
case ICLASS:
|
||||
crcStatus = iclass_CRC_check(isResponse, frame, data_len);
|
||||
break;
|
||||
case ISO_14443B:
|
||||
case TOPAZ:
|
||||
crcStatus = iso14443B_CRC_check(isResponse, topaz_reader_command, data_len);
|
||||
break;
|
||||
case ISO_14443A:
|
||||
ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
if(!(isResponse & (data_len < 6))) {
|
||||
crcStatus = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//0 CRC-command, CRC not ok
|
||||
|
@ -361,12 +391,13 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
|||
|
||||
if(!isResponse)
|
||||
{
|
||||
if(protocol == ICLASS)
|
||||
annotateIclass(explanation,sizeof(explanation),frame,data_len);
|
||||
else if (protocol == ISO_14443A)
|
||||
annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
|
||||
else if(protocol == ISO_14443B)
|
||||
annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
|
||||
switch(protocol) {
|
||||
case ICLASS: annotateIclass(explanation,sizeof(explanation),frame,data_len); break;
|
||||
case ISO_14443A: annotateIso14443a(explanation,sizeof(explanation),frame,data_len); break;
|
||||
case ISO_14443B: annotateIso14443b(explanation,sizeof(explanation),frame,data_len); break;
|
||||
case TOPAZ: annotateTopaz(explanation,sizeof(explanation),frame,data_len); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
int num_lines = MIN((data_len - 1)/16 + 1, 16);
|
||||
|
@ -382,7 +413,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
|||
} else {
|
||||
PrintAndLog(" | | | %-64s| %s| %s",
|
||||
line[j],
|
||||
(j == num_lines-1)?crc:" ",
|
||||
(j == num_lines-1) ? crc : " ",
|
||||
(j == num_lines-1) ? explanation : "");
|
||||
}
|
||||
}
|
||||
|
@ -425,20 +456,17 @@ int CmdHFList(const char *Cmd)
|
|||
}
|
||||
if(!errors)
|
||||
{
|
||||
if(strcmp(type, "iclass") == 0)
|
||||
{
|
||||
if(strcmp(type, "iclass") == 0) {
|
||||
protocol = ICLASS;
|
||||
}else if(strcmp(type, "14a") == 0)
|
||||
{
|
||||
} else if(strcmp(type, "14a") == 0) {
|
||||
protocol = ISO_14443A;
|
||||
}
|
||||
else if(strcmp(type, "14b") == 0)
|
||||
{
|
||||
} else if(strcmp(type, "14b") == 0) {
|
||||
protocol = ISO_14443B;
|
||||
}else if(strcmp(type,"raw")== 0)
|
||||
{
|
||||
} else if(strcmp(type,"topaz")== 0) {
|
||||
protocol = TOPAZ;
|
||||
} else if(strcmp(type,"raw")== 0) {
|
||||
protocol = -1;//No crc, no annotations
|
||||
}else{
|
||||
} else {
|
||||
errors = true;
|
||||
}
|
||||
}
|
||||
|
@ -452,6 +480,7 @@ int CmdHFList(const char *Cmd)
|
|||
PrintAndLog(" 14a - interpret data as iso14443a communications");
|
||||
PrintAndLog(" 14b - interpret data as iso14443b communications");
|
||||
PrintAndLog(" iclass - interpret data as iclass communications");
|
||||
PrintAndLog(" topaz - interpret data as topaz communications");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("example: hf list 14a f");
|
||||
PrintAndLog("example: hf list iclass");
|
||||
|
|
|
@ -140,7 +140,7 @@ int CmdHF14AReader(const char *Cmd)
|
|||
iso14a_card_select_t card;
|
||||
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
|
||||
|
||||
uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
|
||||
uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
|
||||
|
||||
if(select_status == 0) {
|
||||
PrintAndLog("iso14443a card select failed");
|
||||
|
@ -152,6 +152,18 @@ int CmdHF14AReader(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if(select_status == 3) {
|
||||
PrintAndLog("Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
// disconnect
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
|
||||
|
|
|
@ -168,9 +168,20 @@ NXP/Philips CUSTOM COMMANDS
|
|||
#define ISO15693_READ_MULTI_SECSTATUS 0x2C
|
||||
|
||||
|
||||
#define ISO_14443A 0
|
||||
#define ICLASS 1
|
||||
#define ISO_14443B 2
|
||||
// Topaz command set:
|
||||
#define TOPAZ_REQA 0x26 // Request
|
||||
#define TOPAZ_WUPA 0x52 // WakeUp
|
||||
#define TOPAZ_RID 0x78 // Read ID
|
||||
#define TOPAZ_RALL 0x00 // Read All (all bytes)
|
||||
#define TOPAZ_READ 0x01 // Read (a single byte)
|
||||
#define TOPAZ_WRITE_E 0x53 // Write-with-erase (a single byte)
|
||||
#define TOPAZ_WRITE_NE 0x1a // Write-no-erase (a single byte)
|
||||
|
||||
|
||||
#define ISO_14443A 0
|
||||
#define ICLASS 1
|
||||
#define ISO_14443B 2
|
||||
#define TOPAZ 3
|
||||
|
||||
//-- Picopass fuses
|
||||
#define FUSE_FPERS 0x80
|
||||
|
|
Loading…
Reference in a new issue