Improved 'hf list iclass' a bit, better understanding of the protocol and when to apply CRC checks

This commit is contained in:
Martin Holst Swende 2015-01-15 23:00:39 +01:00
parent d60418a05f
commit 49726b4088

View file

@ -123,14 +123,19 @@ NXP/Philips CUSTOM COMMANDS
40 = Long Range CMD (Standard ISO/TR7003:1990) 40 = Long Range CMD (Standard ISO/TR7003:1990)
*/ */
#define ICLASS_CMD_ACTALL 0x0A #define ICLASS_CMD_ACTALL 0x0A
#define ICLASS_CMD_READ_OR_IDENTIFY 0x0C #define ICLASS_CMD_READ_OR_IDENTIFY 0x0C
#define ICLASS_CMD_SELECT 0x81 #define ICLASS_CMD_SELECT 0x81
#define ICLASS_CMD_PAGESEL 0x84 #define ICLASS_CMD_PAGESEL 0x84
#define ICLASS_CMD_READCHECK 0x88 #define ICLASS_CMD_READCHECK_KD 0x88
#define ICLASS_CMD_CHECK 0x05 #define ICLASS_CMD_READCHECK_KC 0x18
#define ICLASS_CMD_SOF 0x0F #define ICLASS_CMD_CHECK 0x05
#define ICLASS_CMD_HALT 0x00 #define ICLASS_CMD_DETECT 0x0F
#define ICLASS_CMD_HALT 0x00
#define ICLASS_CMD_UPDATE 0x87
#define ICLASS_CMD_ACT 0x8E
#define ICLASS_CMD_READ4 0x06
#define ISO14443_CMD_REQA 0x26 #define ISO14443_CMD_REQA 0x26
#define ISO14443_CMD_READBLOCK 0x30 #define ISO14443_CMD_READBLOCK 0x30
@ -235,11 +240,15 @@ void annotateIclass(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
break; break;
} }
case ICLASS_CMD_SELECT: snprintf(exp,size,"SELECT"); break; case ICLASS_CMD_SELECT: snprintf(exp,size,"SELECT"); break;
case ICLASS_CMD_PAGESEL: snprintf(exp,size,"PAGESEL"); break; case ICLASS_CMD_PAGESEL: snprintf(exp,size,"PAGESEL(%d)", cmd[1]); break;
case ICLASS_CMD_READCHECK: snprintf(exp,size,"READCHECK"); break; case ICLASS_CMD_READCHECK_KC:snprintf(exp,size,"READCHECK[Kc](%d)", cmd[1]); break;
case ICLASS_CMD_READCHECK_KD:snprintf(exp,size,"READCHECK[Kd](%d)", cmd[1]); break;
case ICLASS_CMD_CHECK: snprintf(exp,size,"CHECK"); break; case ICLASS_CMD_CHECK: snprintf(exp,size,"CHECK"); break;
case ICLASS_CMD_SOF: snprintf(exp,size,"SOF"); break; case ICLASS_CMD_DETECT: snprintf(exp,size,"DETECT"); break;
case ICLASS_CMD_HALT: snprintf(exp,size,"HALT"); break; case ICLASS_CMD_HALT: snprintf(exp,size,"HALT"); break;
case ICLASS_CMD_UPDATE: snprintf(exp,size,"UPDATE(%d)",cmd[1]); break;
case ICLASS_CMD_ACT: snprintf(exp,size,"ACT"); break;
case ICLASS_CMD_READ4: snprintf(exp,size,"READ4(%d)",cmd[1]); break;
default: snprintf(exp,size,"?"); break; default: snprintf(exp,size,"?"); break;
} }
return; return;
@ -276,6 +285,66 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
} }
} }
} }
/**
* @brief iclass_CRC_Ok Checks CRC in command or response
* @param isResponse
* @param data
* @param len
* @return 0 : CRC-command, CRC not ok
* 1 : CRC-command, CRC ok
* 2 : Not crc-command
*/
uint8_t iclass_CRC_Ok(bool isResponse, uint8_t* data, uint8_t len)
{
if(len < 4) return 2;//CRC commands (and responses) are all at least 4 bytes
uint8_t b1, b2;
if(!isResponse)//Commands to tag
{
/**
These commands should have CRC. Total length leftmost
4 READ
4 READ4
12 UPDATE - unsecured, ends with CRC16
14 UPDATE - secured, ends with signature instead
4 PAGESEL
**/
if(len == 4 || len == 12)//Covers three of them
{
//Don't include the command byte
ComputeCrc14443(CRC_ICLASS, (data+1), len-3, &b1, &b2);
return b1 == data[len -2] && b2 == data[len-1];
}
return 2;
}else{
/**
These tag responses should have CRC. Total length leftmost
10 READ data[8] crc[2]
34 READ4 data[32]crc[2]
10 UPDATE data[8] crc[2]
10 SELECT csn[8] crc[2]
10 IDENTIFY asnb[8] crc[2]
10 PAGESEL block1[8] crc[2]
10 DETECT csn[8] crc[2]
These should not
4 CHECK chip_response[4]
8 READCHECK data[8]
1 ACTALL sof[1]
1 ACT sof[1]
In conclusion, without looking at the command; any response
of length 10 or 34 should have CRC
**/
if(len != 10 && len != 34) return true;
ComputeCrc14443(CRC_ICLASS, data, len-2, &b1, &b2);
return b1 == data[len -2] && b2 == data[len-1];
}
}
uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool showWaitCycles) uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool showWaitCycles)
{ {
@ -332,24 +401,14 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
} }
} }
//--- Draw the CRC column //--- Draw the CRC column
bool crcError = false; uint8_t crcStatus = 2;
if (data_len > 2) { if (data_len > 2) {
uint8_t b1, b2; uint8_t b1, b2;
if(iclass) if(iclass)
{ {
if(!isResponse && data_len == 4 ) { //The following commands have crc
// Rough guess that this is a command from the reader crcStatus = iclass_CRC_Ok(isResponse, frame, data_len);
// For iClass the command byte is not part of the CRC
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
} else {
// For other data.. CRC might not be applicable (UPDATE commands etc.)
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
}
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
crcError = true;
}
}else{//Iso 14443a }else{//Iso 14443a
@ -358,12 +417,15 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) { if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
if(!(isResponse & (data_len < 6))) if(!(isResponse & (data_len < 6)))
{ {
crcError = true; crcStatus = 0;
} }
} }
} }
} }
char *crc = crcError ? "!crc" :" "; //0 CRC-command, CRC not ok
//1 CRC-command, CRC ok
//2 Not crc-command
char *crc = (crcStatus == 0 ? "!crc" : (crcStatus == 1 ? " ok " : " "));
EndOfTransmissionTimestamp = timestamp + duration; EndOfTransmissionTimestamp = timestamp + duration;