CHG: refactor CRC16 algos. This is a big change, most likely some parts broke, hard to test it all.
This commit is contained in:
@@ -110,7 +110,6 @@ CMDSRCS = crapto1/crapto1.c \
|
||||
crc.c \
|
||||
crc16.c \
|
||||
crc64.c \
|
||||
iso14443crc.c \
|
||||
legic_prng.c \
|
||||
iso15693tools.c \
|
||||
prng.c \
|
||||
@@ -191,7 +190,6 @@ CMDSRCS = crapto1/crapto1.c \
|
||||
reveng/poly.c \
|
||||
reveng/getopt.c \
|
||||
bucketsort.c
|
||||
# radixsort.c \
|
||||
|
||||
cpu_arch = $(shell uname -m)
|
||||
ifneq ($(findstring 86, $(cpu_arch)), )
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// Analyse bytes commands
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdanalyse.h"
|
||||
#include "iso15693tools.h"
|
||||
#include "util_posix.h" // msclock
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
@@ -287,7 +285,6 @@ int CmdAnalyseCRC(const char *Cmd) {
|
||||
init_table(CRC_FELICA);
|
||||
PrintAndLog("FeliCa | %X ", crc16_xmodem(data, len));
|
||||
|
||||
return 0;
|
||||
PrintAndLog("\nTests of reflection. Current methods in source code");
|
||||
PrintAndLog(" reflect(0x3e23L,3) is %04X == 0x3e26", reflect(0x3e23L,3) );
|
||||
PrintAndLog(" reflect8(0x80) is %02X == 0x01", reflect8(0x80));
|
||||
@@ -297,7 +294,7 @@ int CmdAnalyseCRC(const char *Cmd) {
|
||||
//
|
||||
uint8_t b1, b2;
|
||||
|
||||
PrintAndLog("\nTests with '123456789' string");
|
||||
printf("\n\nStandard test with 31 32 33 34 35 36 37 38 39 '123456789'\n\n");
|
||||
uint8_t dataStr[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };
|
||||
legic8 = CRC8Legic(dataStr, sizeof(dataStr));
|
||||
|
||||
@@ -310,52 +307,41 @@ int CmdAnalyseCRC(const char *Cmd) {
|
||||
printf("-------------------------------------\n");
|
||||
printf("CRC16 based\n\n");
|
||||
|
||||
init_table(CRC_DNP);
|
||||
PrintAndLog("DNP | %X (EA82 expected)", crc16_dnp(dataStr, sizeof(dataStr)));
|
||||
|
||||
init_table(CRC_CCITT);
|
||||
PrintAndLog("CCITT | %X (29B1 expected)", crc16_ccitt(dataStr, sizeof(dataStr)));
|
||||
|
||||
init_table(CRC_FELICA);
|
||||
PrintAndLog("FeliCa | %X (31C3 expected)", crc16_xmodem( dataStr, sizeof(dataStr)));
|
||||
//uint8_t poll[10] = { 0xb2,0x4d,0x06,0x00,0xff,0xff,0x00,0x00,0x09,0x21};
|
||||
uint8_t poll[] = {0xb2,0x4d,0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80,
|
||||
0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f};
|
||||
PrintAndLog("FeliCa | %X (B37F expected)", crc16_xmodem( poll+2, sizeof(poll)-4));
|
||||
PrintAndLog("FeliCa | %X (0000 expected)", crc16_xmodem( poll+2, sizeof(poll)-2));
|
||||
printf("-------------------------------------\n");
|
||||
printf("\n\n");
|
||||
// input from commandline
|
||||
PrintAndLog("CCITT | %X (29B1 expected)", crc(CRC_CCITT, dataStr, sizeof(dataStr)));
|
||||
|
||||
uint8_t poll[] = {0xb2,0x4d,0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80, 0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f};
|
||||
PrintAndLog("FeliCa | %X (B37F expected)", crc(CRC_FELICA, poll+2, sizeof(poll)-4));
|
||||
PrintAndLog("FeliCa | %X (0000 expected)", crc(CRC_FELICA, poll+2, sizeof(poll)-2));
|
||||
|
||||
uint8_t sel_corr[] = { 0x40, 0xe1, 0xe1, 0xff, 0xfe, 0x5f, 0x02, 0x3c, 0x43, 0x01};
|
||||
PrintAndLog("iCLASS | %04x (0143 expected)", crc(CRC_ICLASS, sel_corr, sizeof(sel_corr)-2));
|
||||
printf("---------------------------------------------------------------\n\n\n");
|
||||
|
||||
// ISO14443 crc A
|
||||
|
||||
// table test.
|
||||
init_table(CRC_14A);
|
||||
uint16_t crcA = crc16_a(dataStr, sizeof(dataStr));
|
||||
ComputeCrc14443(CRC_14443_A, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
compute_crc(CRC_14443_A, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
uint16_t crcAA = b1 << 8 | b2;
|
||||
printf("ISO14443 crc A | %04x == %04x (BF05 expected)\n", crcA, crcAA);
|
||||
printf("ISO14443 crc A | %04x or %04x (BF05 expected)\n", crcAA, crc(CRC_14443_A, dataStr, sizeof(dataStr)) );
|
||||
|
||||
// ISO14443 crc B
|
||||
init_table(CRC_14B);
|
||||
uint16_t crcB = crc16_x25(dataStr, sizeof(dataStr));
|
||||
ComputeCrc14443(CRC_14443_B, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
compute_crc(CRC_14443_B, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
uint16_t crcBB = b1 << 8 | b2;
|
||||
printf("ISO14443 crc B | %04x == %04x (906E expected)\n", crcB, crcBB);
|
||||
printf("ISO14443 crc B | %04x or %04x (906E expected)\n", crcBB, crc(CRC_14443_B, dataStr, sizeof(dataStr)) );
|
||||
|
||||
// ISO15693 crc (x.25)
|
||||
init_table(CRC_15);
|
||||
uint16_t x25 = crc16_x25(dataStr, sizeof(dataStr));
|
||||
uint16_t iso = Iso15693Crc(dataStr, sizeof(dataStr));
|
||||
printf("ISO15693 crc X25 | %04x == %04x (906E expected)\n", iso, x25 );
|
||||
compute_crc(CRC_15693, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
uint16_t crcCC = b1 << 8 | b2;
|
||||
printf("ISO15693 crc X25| %04x or %04x (906E expected)\n", crcCC, crc(CRC_15693, dataStr, sizeof(dataStr)) );
|
||||
|
||||
// ICLASS
|
||||
init_table(CRC_15_ICLASS);
|
||||
uint16_t iclass_new = crc16_iclass(dataStr, sizeof(dataStr));
|
||||
ComputeCrc14443(CRC_ICLASS, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
uint16_t crcCC = b1 << 8 | b2;
|
||||
printf("ICLASS crc | %04x == %04x \n", crcCC, iclass_new);
|
||||
compute_crc(CRC_ICLASS, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
uint16_t crcDD = b1 << 8 | b2;
|
||||
printf("ICLASS crc | %04x or %04x\n", crcDD, crc(CRC_ICLASS, dataStr, sizeof(dataStr)) );
|
||||
|
||||
// FeliCa
|
||||
compute_crc(CRC_FELICA, dataStr, sizeof(dataStr), &b1, &b2);
|
||||
uint16_t crcEE = b1 << 8 | b2;
|
||||
printf("FeliCa | %04x or %04x (31C3 expected)\n", crcEE, crc(CRC_FELICA, dataStr, sizeof(dataStr)));
|
||||
|
||||
free(data);
|
||||
return 0;
|
||||
@@ -468,113 +454,72 @@ int CmdAnalyseTEASelfTest(const char *Cmd){
|
||||
|
||||
int CmdAnalyseA(const char *Cmd){
|
||||
|
||||
uint8_t syncBit = 99;
|
||||
// The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
|
||||
// Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
|
||||
// we therefore look for a ...xx1111 11111111 00x11111xxxxxx... pattern
|
||||
// (12 '1's followed by 2 '0's, eventually followed by another '0', followed by 5 '1's)
|
||||
# define SYNC_16BIT 0x4DB2
|
||||
#define FELICA_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000
|
||||
|
||||
PrintAndLog("ISO 15693 - x25 - Residue %04x ( %0xF0B8 expected) ", ISO15_CRC_CHECK);
|
||||
|
||||
uint8_t b1, b2;
|
||||
|
||||
// 14 a
|
||||
uint8_t halt[] = {0x50 , 0x00, 0x57, 0xcd }; //halt w crc
|
||||
uint8_t atqs[] = {0x09, 0x78, 0x00, 0x92, 0x02, 0x54, 0x13, 0x02, 0x04, 0x2d, 0xe8 }; // atqs w crc
|
||||
ComputeCrc14443(CRC_14443_A, halt, sizeof(halt), &b1, &b2);
|
||||
printf("14a crc halt == 0 [%s]\n", (b1==0 && b2==0) ? "YES": "NO" );
|
||||
ComputeCrc14443(CRC_14443_A, atqs, sizeof(atqs), &b1, &b2);
|
||||
printf("14a crc ATQS == 0 [%s]\n", (b1==0 && b2==0) ? "YES": "NO" );
|
||||
uint32_t shiftReg = SYNC_16BIT;
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 0)));
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 1)));
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 2)));
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 3)));
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 4)));
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 5)));
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 6)));
|
||||
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 7)));
|
||||
|
||||
// 14b
|
||||
uint8_t u14b[] = {0x05,0x00,0x08,0x39,0x73};
|
||||
ComputeCrc14443(CRC_14443_B, u14b, sizeof(u14b), &b1, &b2);
|
||||
printf("14b crc u14b == 0 [%s] %02x %02x\n", (b1==0 && b2==0) ? "YES": "NO" , b1,b2);
|
||||
ComputeCrc14443(CRC_14443_B, u14b, sizeof(u14b)-2, &b1, &b2);
|
||||
printf("14b crc u14b == 0 [%s] %02x %02x\n", (b1==0 && b2==0) ? "YES": "NO" , b1,b2);
|
||||
for ( uint8_t i=0; i<32; i++){
|
||||
if ((shiftReg & (SYNC_16BIT >> 0)) == SYNC_16BIT >> 0) syncBit = 7;
|
||||
else if ((shiftReg & (SYNC_16BIT >> 1)) == SYNC_16BIT >> 1) syncBit = 6;
|
||||
else if ((shiftReg & (SYNC_16BIT >> 2)) == SYNC_16BIT >> 2) syncBit = 5;
|
||||
else if ((shiftReg & (SYNC_16BIT >> 3)) == SYNC_16BIT >> 3) syncBit = 4;
|
||||
else if ((shiftReg & (SYNC_16BIT >> 4)) == SYNC_16BIT >> 4) syncBit = 3;
|
||||
else if ((shiftReg & (SYNC_16BIT >> 5)) == SYNC_16BIT >> 5) syncBit = 2;
|
||||
else if ((shiftReg & (SYNC_16BIT >> 6)) == SYNC_16BIT >> 6) syncBit = 1;
|
||||
else if ((shiftReg & (SYNC_16BIT >> 7)) == SYNC_16BIT >> 7) syncBit = 0;
|
||||
|
||||
printf("x25 or 14b command %04X == (3973)\n", crc16_x25(u14b, sizeof(u14b)-2));
|
||||
printf("x25 or 14b command %04X == (0)\n", crc16_x25(u14b, sizeof(u14b)));
|
||||
|
||||
printf("\n\n");
|
||||
printf("ShiftReg is [%04x] | SyncBit is [%u]\n", shiftReg, syncBit);
|
||||
shiftReg = shiftReg << 1 | ( shiftReg & 0x8000 ) >> 15;
|
||||
}
|
||||
/*
|
||||
pm3 --> da hex2bin 4db2 0100110110110010
|
||||
pm3 --> da hex2bin 926d9 10010010011011011001
|
||||
*/
|
||||
return 0;
|
||||
|
||||
time_t t;
|
||||
srand((unsigned) time(&t));
|
||||
uint64_t t1 = msclock();
|
||||
// test CRC-A etc
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
crc16_a(atqs, sizeof(atqs));
|
||||
atqs[1] = rand();
|
||||
atqs[2] = rand();
|
||||
atqs[3] = rand();
|
||||
atqs[4] = rand();
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks crc_a %" PRIu64 "\n", t1);
|
||||
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
ComputeCrc14443(CRC_14443_A, atqs, sizeof(atqs), &b1, &b2);
|
||||
atqs[1] = rand();
|
||||
atqs[2] = rand();
|
||||
atqs[3] = rand();
|
||||
atqs[4] = rand(); }
|
||||
t1 = msclock() - t1; printf("ticks curr CRC-a %" PRIu64 "\n", t1);
|
||||
|
||||
|
||||
// test ISO15693 crc
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
crc16_x25(atqs, sizeof(atqs));
|
||||
atqs[1] = rand();
|
||||
atqs[2] = rand();
|
||||
atqs[3] = rand();
|
||||
atqs[4] = rand();
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks x25 %" PRIu64 "\n", t1);
|
||||
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
Iso15693Crc(atqs, sizeof(atqs));
|
||||
atqs[1] = rand();
|
||||
atqs[2] = rand();
|
||||
atqs[3] = rand();
|
||||
atqs[4] = rand(); }
|
||||
t1 = msclock() - t1; printf("ticks curr iso15 (x25) %" PRIu64 "\n", t1);
|
||||
|
||||
//return 0;
|
||||
// 14443-A
|
||||
uint8_t u14_c[] = {0x09, 0x78, 0x00, 0x92, 0x02, 0x54, 0x13, 0x02, 0x04, 0x2d, 0xe8 }; // atqs w crc
|
||||
uint8_t u14_w[] = {0x09, 0x78, 0x00, 0x92, 0x02, 0x54, 0x13, 0x02, 0x04, 0x2d, 0xe7 }; // atqs w crc
|
||||
printf("14a check wrong crc | %s\n", (check_crc(CRC_14443_A, u14_w, sizeof(u14_w))) ? "YES": "NO" );
|
||||
printf("14a check correct crc | %s\n", (check_crc(CRC_14443_A, u14_c, sizeof(u14_c))) ? "YES": "NO" );
|
||||
|
||||
// 16bit test
|
||||
uint8_t md;
|
||||
uint32_t mb, mc;
|
||||
// 14443-B
|
||||
uint8_t u14b[] = {0x05,0x00,0x08,0x39,0x73};
|
||||
printf("14b check crc | %s\n", (check_crc(CRC_14443_B, u14b, sizeof(u14b))) ? "YES": "NO");
|
||||
|
||||
// reflect
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
mb = rand();
|
||||
reflect(mb, 16);
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks reflect %" PRIu64 "\n", t1);
|
||||
// 15693 test
|
||||
uint8_t u15_c[] = {0x05,0x00,0x08,0x39,0x73}; // correct
|
||||
uint8_t u15_w[] = {0x05,0x00,0x08,0x39,0x72}; // wrong
|
||||
printf("15 check wrong crc | %s\n", (check_crc(CRC_15693, u15_w, sizeof(u15_w))) ? "YES": "NO");
|
||||
printf("15 check correct crc | %s\n", (check_crc(CRC_15693, u15_c, sizeof(u15_c))) ? "YES": "NO");
|
||||
|
||||
// iCLASS test - wrong crc , swapped bytes.
|
||||
uint8_t iclass_w[] = { 0x40, 0xe1, 0xe1, 0xff, 0xfe, 0x5f, 0x02, 0x3c, 0x01, 0x43};
|
||||
uint8_t iclass_c[] = { 0x40, 0xe1, 0xe1, 0xff, 0xfe, 0x5f, 0x02, 0x3c, 0x43, 0x01};
|
||||
printf("iCLASS check wrong crc | %s\n", (check_crc(CRC_ICLASS, iclass_w, sizeof(iclass_w))) ? "YES": "NO");
|
||||
printf("iCLASS check correct crc | %s\n", (check_crc(CRC_ICLASS, iclass_c, sizeof(iclass_c))) ? "YES": "NO");
|
||||
|
||||
// reflect16
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
mc = rand();
|
||||
reflect16(mc);
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks reflect16 %" PRIu64 "\n", t1);
|
||||
//---------------------------------------------------------
|
||||
// FeliCa test
|
||||
uint8_t felica_w[] = {0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80, 0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7e};
|
||||
uint8_t felica_c[] = {0x12,0x01,0x01,0x2e,0x3d,0x17,0x26,0x47,0x80, 0x95,0x00,0xf1,0x00,0x00,0x00,0x01,0x43,0x00,0xb3,0x7f};
|
||||
printf("FeliCa check wrong crc | %s\n", (check_crc(CRC_FELICA, felica_w, sizeof(felica_w))) ? "YES": "NO");
|
||||
printf("FeliCa check correct crc | %s\n", (check_crc(CRC_FELICA, felica_c, sizeof(felica_c))) ? "YES": "NO");
|
||||
|
||||
// reflect
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
md = rand();
|
||||
reflect(md, 8);
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks reflect _8_ %" PRIu64 "\n", t1);
|
||||
|
||||
// reflect8
|
||||
t1 = msclock();
|
||||
for (int foo=0; foo < 10000000; foo++) {
|
||||
md = rand();
|
||||
reflect8(md);
|
||||
}
|
||||
t1 = msclock() - t1; printf("ticks reflect8 %" PRIu64 "\n", t1);
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
/*
|
||||
@@ -876,19 +821,19 @@ int CmdAnalyseHid(const char *Cmd){
|
||||
|
||||
void generate4bNUID(uint8_t *uid, uint8_t *nuid){
|
||||
uint16_t crc;
|
||||
uint8_t first, second;
|
||||
uint8_t b1, b2;
|
||||
|
||||
ComputeCrc14443(CRC_14443_A, uid, 3, &first, &second);
|
||||
nuid[0] |= (second & 0xE0) | 0xF;
|
||||
nuid[1] = first;
|
||||
compute_crc(CRC_14443_A, uid, 3, &b1, &b2);
|
||||
nuid[0] |= (b2 & 0xE0) | 0xF;
|
||||
nuid[1] = b1;
|
||||
|
||||
crc = first;
|
||||
crc |= second << 8;
|
||||
crc = b1;
|
||||
crc |= b2 << 8;
|
||||
|
||||
UpdateCrc14443(uid[3], &crc);
|
||||
UpdateCrc14443(uid[4], &crc);
|
||||
UpdateCrc14443(uid[5], &crc);
|
||||
UpdateCrc14443(uid[6], &crc);
|
||||
crc = update_crc16(uid[3], crc);
|
||||
crc = update_crc16(uid[4], crc);
|
||||
crc = update_crc16(uid[5], crc);
|
||||
crc = update_crc16(uid[6], crc);
|
||||
|
||||
nuid[2] = (crc >> 8) & 0xFF ;
|
||||
nuid[3] = crc & 0xFF;
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
#include "ui.h" // PrintAndLog
|
||||
#include "util.h"
|
||||
#include "crc.h"
|
||||
#include "iso15693tools.h" //
|
||||
#include "iso14443crc.h" // crc 14a
|
||||
#include "crc16.h" // crc16 ccitt
|
||||
#include "tea.h"
|
||||
#include "legic_prng.h"
|
||||
#include "loclass/elite_crack.h"
|
||||
#include "mfkey.h" //nonce2key
|
||||
#include "util_posix.h" // msclock
|
||||
|
||||
|
||||
int usage_analyse_lcr(void);
|
||||
int usage_analyse_checksum(void);
|
||||
|
||||
@@ -420,42 +420,27 @@ void annotateFelica(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){
|
||||
* 2 : Not crc-command
|
||||
*/
|
||||
|
||||
uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
{
|
||||
uint8_t b1,b2;
|
||||
|
||||
if(len <= 2) return 2;
|
||||
|
||||
if(isResponse & (len < 6)) return 2;
|
||||
|
||||
ComputeCrc14443(CRC_14443_A, data, len-2, &b1, &b2);
|
||||
if (b1 != data[len-2] || b2 != data[len-1])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
uint8_t iso14443A_CRC_check(bool isResponse, uint8_t* d, uint8_t n) {
|
||||
if (n < 3) return 2;
|
||||
if (isResponse & (n < 6)) return 2;
|
||||
return check_crc(CRC_14443_A, d, n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief iso14443B_CRC_check Checks CRC in command or response
|
||||
* @param isResponse
|
||||
* @brief iso14443B_CRC_check Checks CRC
|
||||
* @param data
|
||||
* @param len
|
||||
* @return 0 : CRC-command, CRC not ok
|
||||
* 1 : CRC-command, CRC ok
|
||||
* 2 : Not crc-command
|
||||
*/
|
||||
uint8_t iso14443B_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
{
|
||||
uint8_t b1,b2;
|
||||
uint8_t iso14443B_CRC_check(uint8_t* d, uint8_t n) {
|
||||
return check_crc(CRC_14443_B, d, n);
|
||||
}
|
||||
|
||||
if(len <= 2) return 2;
|
||||
|
||||
ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
|
||||
if(b1 != data[len-2] || b2 != data[len-1])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
uint8_t iso15693_CRC_check(uint8_t* d, uint8_t n) {
|
||||
return check_crc(CRC_15693, d, n);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -467,13 +452,13 @@ uint8_t iso14443B_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
* 1 : CRC-command, CRC ok
|
||||
* 2 : Not crc-command
|
||||
*/
|
||||
uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
uint8_t iclass_CRC_check(bool isResponse, uint8_t* d, uint8_t n)
|
||||
{
|
||||
if(len < 4) return 2;//CRC commands (and responses) are all at least 4 bytes
|
||||
|
||||
uint8_t b1, b2;
|
||||
//CRC commands (and responses) are all at least 4 bytes
|
||||
if (n < 4) return 2;
|
||||
|
||||
//Commands to tag
|
||||
//Don't include the command byte
|
||||
if (!isResponse) {
|
||||
/**
|
||||
These commands should have CRC. Total length leftmost
|
||||
@@ -484,10 +469,8 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
4 PAGESEL
|
||||
**/
|
||||
//Covers three of them
|
||||
if(len == 4 || len == 12) {
|
||||
//Don't include the command byte
|
||||
ComputeCrc14443(CRC_ICLASS, (data+1), len-3, &b1, &b2);
|
||||
return b1 == data[len -2] && b2 == data[len-1];
|
||||
if (n == 4 || n == 12) {
|
||||
return check_crc( CRC_ICLASS, d+1, n-1);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
@@ -512,23 +495,9 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
In conclusion, without looking at the command; any response
|
||||
of length 10 or 34 should have CRC
|
||||
**/
|
||||
if(len != 10 && len != 34) return true;
|
||||
if (n != 10 && n != 34) return true;
|
||||
|
||||
ComputeCrc14443(CRC_ICLASS, data, len-2, &b1, &b2);
|
||||
return b1 == data[len -2] && b2 == data[len-1];
|
||||
}
|
||||
// CRC Iso15693Crc(data,datalen)
|
||||
uint8_t iso15693_CRC_check(bool isResponse, uint8_t* data, uint8_t len) {
|
||||
if ( len <= 3) return 2;
|
||||
|
||||
uint16_t crc = Iso15693Crc(data, len-2);
|
||||
uint8_t b1 = crc & 0xFF;
|
||||
uint8_t b2 = ((crc >> 8) & 0xFF);
|
||||
|
||||
if ( b1 != data[len-2] || b2 != data[len-1] )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return check_crc( CRC_ICLASS, d, n);
|
||||
}
|
||||
|
||||
bool is_last_record(uint16_t tracepos, uint8_t *trace, uint16_t traceLen)
|
||||
@@ -640,14 +609,14 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||
case ISO_14443B:
|
||||
case TOPAZ:
|
||||
case FELICA:
|
||||
crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
|
||||
crcStatus = iso14443B_CRC_check(frame, data_len);
|
||||
break;
|
||||
case ISO_14443A:
|
||||
case MFDES:
|
||||
crcStatus = iso14443A_CRC_check(isResponse, frame, data_len);
|
||||
break;
|
||||
case ISO_15693:
|
||||
crcStatus = iso15693_CRC_check(isResponse, frame, data_len);
|
||||
crcStatus = iso15693_CRC_check(frame, data_len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -914,9 +914,9 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
if (crc && datalen>0 && datalen<sizeof(data)-2) {
|
||||
uint8_t first, second;
|
||||
if (topazmode) {
|
||||
ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
|
||||
compute_crc(CRC_14443_B, data, datalen, &first, &second);
|
||||
} else {
|
||||
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
|
||||
compute_crc(CRC_14443_A, data, datalen, &first, &second);
|
||||
}
|
||||
data[datalen++] = first;
|
||||
data[datalen++] = second;
|
||||
|
||||
@@ -806,7 +806,6 @@ int srix4kValid(const char *Cmd){
|
||||
bool waitCmd14b(bool verbose) {
|
||||
|
||||
bool crc = false;
|
||||
uint8_t b1 = 0, b2 = 0;
|
||||
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
|
||||
uint8_t status = 0;
|
||||
uint16_t len = 0;
|
||||
@@ -823,8 +822,7 @@ bool waitCmd14b(bool verbose) {
|
||||
|
||||
if (verbose) {
|
||||
if ( len >= 3 ) {
|
||||
ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
|
||||
crc = ( data[len-2] == b1 && data[len-1] == b2);
|
||||
crc = check_crc(CRC_14443_B, data, len);
|
||||
|
||||
PrintAndLog("[LEN %u] %s[%02X %02X] %s",
|
||||
len,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "iso14443crc.h"
|
||||
#include "crc16.h"
|
||||
#include "proxmark3.h"
|
||||
#include "data.h"
|
||||
#include "graph.h"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||
// Modified 2010-2012 by <adrian -at- atrox.at>
|
||||
// Modified 2012 by <vsza at vsza.hu>
|
||||
// Modfified 2018 by <iceman>
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
@@ -28,8 +29,10 @@
|
||||
#define Logic1 Iso15693Logic1
|
||||
#define FrameEOF Iso15693FrameEOF
|
||||
|
||||
#define Crc(data, len) Iso15693Crc((data), (len))
|
||||
#define AddCrc(data, len) Iso15693AddCrc((data), (len))
|
||||
#define Crc(data, len) crc(CRC_15693, (data), (len))
|
||||
#define CheckCrc(data, len) check_crc(CRC_15693, (data), (len))
|
||||
#define AddCrc(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
|
||||
#define sprintUID(target, uid) Iso15693sprintUID((target), (uid))
|
||||
|
||||
// structure and database for uid -> tagtype lookups
|
||||
@@ -195,7 +198,8 @@ int getUID(uint8_t *buf) {
|
||||
c.d.asBytes[1] = ISO15_CMD_INVENTORY;
|
||||
c.d.asBytes[2] = 0; // mask length
|
||||
|
||||
c.arg[0] = AddCrc(c.d.asBytes, 3);
|
||||
AddCrc(c.d.asBytes, 3);
|
||||
c.arg[0] = 5; // len
|
||||
|
||||
uint8_t retry;
|
||||
|
||||
@@ -208,7 +212,7 @@ int getUID(uint8_t *buf) {
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
|
||||
uint8_t resplen = resp.arg[0];
|
||||
if (resplen >= 12 && ISO15_CRC_CHECK == Crc(resp.d.asBytes, 12)) {
|
||||
if (resplen >= 12 && CheckCrc(resp.d.asBytes, 12)) {
|
||||
memcpy(buf, resp.d.asBytes + 2, 8);
|
||||
return 1;
|
||||
}
|
||||
@@ -460,7 +464,7 @@ int CmdHF15Demod(const char *Cmd) {
|
||||
for (i = 0; i < k; i++)
|
||||
PrintAndLog("# %2d: %02x ", i, outBuf[i]);
|
||||
|
||||
PrintAndLog("CRC %04x", Iso15693Crc(outBuf, k - 2));
|
||||
PrintAndLog("CRC %04x", Crc(outBuf, k - 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -492,7 +496,6 @@ int CmdHF15Info(const char *Cmd) {
|
||||
uint8_t *recv;
|
||||
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
|
||||
uint8_t *req = c.d.asBytes;
|
||||
int reqlen = 0;
|
||||
char cmdbuf[100];
|
||||
char *cmd = cmdbuf;
|
||||
|
||||
@@ -501,8 +504,8 @@ int CmdHF15Info(const char *Cmd) {
|
||||
if ( !prepareHF15Cmd(&cmd, &c, ISO15_CMD_SYSINFO) )
|
||||
return 0;
|
||||
|
||||
reqlen = AddCrc(req, c.arg[0]);
|
||||
c.arg[0] = reqlen;
|
||||
AddCrc(req, c.arg[0]);
|
||||
c.arg[0] += 2;
|
||||
|
||||
//PrintAndLog("cmd %s", sprint_hex(c.d.asBytes, reqlen) );
|
||||
|
||||
@@ -686,7 +689,7 @@ int CmdHF15Dump(const char*Cmd) {
|
||||
|
||||
PrintAndLog("Reading memory from tag UID %s", sprintUID(NULL, uid));
|
||||
|
||||
int reqlen = 0, blocknum = 0;
|
||||
int blocknum = 0;
|
||||
uint8_t *recv = NULL;
|
||||
|
||||
// memory.
|
||||
@@ -707,8 +710,8 @@ int CmdHF15Dump(const char*Cmd) {
|
||||
for (int retry = 0; retry < 5; retry++) {
|
||||
|
||||
req[10] = blocknum;
|
||||
reqlen = AddCrc(req, 11);
|
||||
c.arg[0] = reqlen;
|
||||
AddCrc(req, 11);
|
||||
c.arg[0] = 13;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
@@ -723,7 +726,7 @@ int CmdHF15Dump(const char*Cmd) {
|
||||
|
||||
recv = resp.d.asBytes;
|
||||
|
||||
if ( ISO15_CRC_CHECK != Crc(recv, len) ) {
|
||||
if ( !CheckCrc(recv, len) ) {
|
||||
PrintAndLog("crc fail");
|
||||
continue;
|
||||
}
|
||||
@@ -827,9 +830,13 @@ int CmdHF15Raw(const char *Cmd) {
|
||||
PrintAndLog("Invalid char on input");
|
||||
return 0;
|
||||
}
|
||||
if (crc) datalen = AddCrc(data, datalen);
|
||||
|
||||
c.arg[0] = datalen;
|
||||
if (crc) {
|
||||
AddCrc(data, datalen);
|
||||
c.arg[0] = datalen+2;
|
||||
} else {
|
||||
c.arg[0] = datalen;
|
||||
}
|
||||
c.arg[1] = fast;
|
||||
c.arg[2] = reply;
|
||||
memcpy(c.d.asBytes, data, datalen);
|
||||
@@ -972,8 +979,8 @@ int CmdHF15Readmulti(const char *Cmd) {
|
||||
|
||||
req[reqlen++] = pagenum;
|
||||
req[reqlen++] = pagecount;
|
||||
reqlen = AddCrc(req, reqlen);
|
||||
c.arg[0] = reqlen;
|
||||
AddCrc(req, reqlen);
|
||||
c.arg[0] = reqlen+2;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
@@ -991,7 +998,7 @@ int CmdHF15Readmulti(const char *Cmd) {
|
||||
|
||||
recv = resp.d.asBytes;
|
||||
|
||||
if (ISO15_CRC_CHECK != Crc(recv, status)) {
|
||||
if (!CheckCrc(recv, status)) {
|
||||
PrintAndLog("CRC failed");
|
||||
return 2;
|
||||
}
|
||||
@@ -1051,9 +1058,9 @@ int CmdHF15Read(const char *Cmd) {
|
||||
|
||||
req[reqlen++] = (uint8_t)blocknum;
|
||||
|
||||
reqlen = AddCrc(req, reqlen);
|
||||
AddCrc(req, reqlen);
|
||||
|
||||
c.arg[0] = reqlen;
|
||||
c.arg[0] = reqlen+2;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
@@ -1071,7 +1078,7 @@ int CmdHF15Read(const char *Cmd) {
|
||||
|
||||
recv = resp.d.asBytes;
|
||||
|
||||
if (ISO15_CRC_CHECK != Crc(recv, status)) {
|
||||
if ( !CheckCrc(recv, status) ) {
|
||||
PrintAndLog("CRC failed");
|
||||
return 2;
|
||||
}
|
||||
@@ -1134,8 +1141,8 @@ int CmdHF15Write(const char *Cmd) {
|
||||
req[reqlen++]=temp & 0xff;
|
||||
cmd2+=2;
|
||||
}
|
||||
reqlen = AddCrc(req,reqlen);
|
||||
c.arg[0] = reqlen;
|
||||
AddCrc(req, reqlen);
|
||||
c.arg[0] = reqlen+2;
|
||||
|
||||
PrintAndLog("iso15693 writing to page %02d (0x&02X) | data ", pagenum, pagenum);
|
||||
|
||||
@@ -1155,7 +1162,7 @@ int CmdHF15Write(const char *Cmd) {
|
||||
|
||||
recv = resp.d.asBytes;
|
||||
|
||||
if (ISO15_CRC_CHECK != Crc(recv, status)) {
|
||||
if ( !CheckCrc(recv, status) ) {
|
||||
PrintAndLog("CRC failed");
|
||||
return 2;
|
||||
}
|
||||
@@ -1188,7 +1195,8 @@ int CmdHF15Select(const char *Cmd) {
|
||||
|
||||
//Select (usage: 2025+8bytes UID+2bytes ISO15693-CRC - can be used in addressed form only!) [NO NEED FOR OPTION FLAG]
|
||||
// len
|
||||
c.arg[0] = AddCrc(c.d.asBytes, 10);
|
||||
AddCrc(c.d.asBytes, 10);
|
||||
c.arg[0] = 12;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "cmdparser.h"
|
||||
#include "iso15693tools.h" // iso15 crc
|
||||
#include "crc16.h" // iso15 crc
|
||||
#include "cmdmain.h"
|
||||
#include "cmddata.h" // getsamples
|
||||
#include "loclass/fileutils.h" // savefileEML
|
||||
|
||||
@@ -23,7 +23,6 @@ int usage_hf_felica_sim(void) {
|
||||
PrintAndLog(" hf felica sim t 1 ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usage_hf_felica_sniff(void){
|
||||
PrintAndLog("It get data from the field and saves it into command buffer.");
|
||||
PrintAndLog("Buffer accessible from command 'hf list felica'");
|
||||
@@ -55,15 +54,13 @@ int usage_hf_felica_dumplite(void) {
|
||||
return 0;
|
||||
}
|
||||
int usage_hf_felica_raw(void){
|
||||
PrintAndLog("Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
|
||||
PrintAndLog("Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>");
|
||||
PrintAndLog(" -h this help");
|
||||
PrintAndLog(" -r do not read response");
|
||||
PrintAndLog(" -c calculate and append CRC");
|
||||
PrintAndLog(" -p leave the signal field ON after receive");
|
||||
PrintAndLog(" -a active signal field ON without select");
|
||||
PrintAndLog(" -s active signal field ON with select");
|
||||
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
|
||||
PrintAndLog(" -t timeout in ms");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -107,13 +104,13 @@ int CmdHFFelicaReader(const char *Cmd) {
|
||||
break;
|
||||
}
|
||||
case 0: {
|
||||
PrintAndLog("FeliCa Card found");
|
||||
PrintAndLog("FeliCa Card");
|
||||
|
||||
PrintAndLog("IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
|
||||
PrintAndLog(" - CODE %s", sprint_hex(card.code, sizeof(card.code)));
|
||||
PrintAndLog(" - NFCUID1 %s", sprint_hex(card.uid, sizeof(card.uid)));
|
||||
PrintAndLog(" - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid)));
|
||||
|
||||
PrintAndLog("PMm %s", sprint_hex(card.PMm, sizeof(card.PMm)));
|
||||
PrintAndLog("Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm)));
|
||||
PrintAndLog(" - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode)));
|
||||
PrintAndLog(" - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt)));
|
||||
|
||||
@@ -244,6 +241,7 @@ int CmdHFFelicaSimLite(const char *Cmd) {
|
||||
static void printSep() {
|
||||
PrintAndLog("------------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace,uint16_t tracelen) {
|
||||
if (tracepos+19 >= tracelen)
|
||||
return tracelen;
|
||||
@@ -417,8 +415,6 @@ int CmdHFFelicaCmdRaw(const char *cmd) {
|
||||
bool active = false;
|
||||
bool active_select = false;
|
||||
uint16_t numbits = 0;
|
||||
bool bTimeout = false;
|
||||
uint32_t timeout = 0;
|
||||
char buf[5]="";
|
||||
int i = 0;
|
||||
uint8_t data[USB_CMD_DATA_SIZE];
|
||||
@@ -459,14 +455,6 @@ int CmdHFFelicaCmdRaw(const char *cmd) {
|
||||
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
|
||||
i-=2;
|
||||
break;
|
||||
case 't':
|
||||
bTimeout = true;
|
||||
sscanf(cmd+i+2, "%d", &temp);
|
||||
timeout = temp;
|
||||
i+=3;
|
||||
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
|
||||
i-=2;
|
||||
break;
|
||||
default:
|
||||
return usage_hf_felica_raw();
|
||||
}
|
||||
@@ -496,35 +484,25 @@ int CmdHFFelicaCmdRaw(const char *cmd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (crc && datalen>0 && datalen<sizeof(data)-2) {
|
||||
uint8_t first, second;
|
||||
ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
|
||||
data[datalen++] = first;
|
||||
data[datalen++] = second;
|
||||
if (crc && datalen>0 && datalen < sizeof(data)-2) {
|
||||
uint8_t b1, b2;
|
||||
compute_crc(CRC_FELICA, data, datalen, &b1, &b2);
|
||||
data[datalen++] = b1;
|
||||
data[datalen++] = b2;
|
||||
}
|
||||
|
||||
if (active || active_select) {
|
||||
c.arg[0] |= ISO14A_CONNECT;
|
||||
c.arg[0] |= FELICA_CONNECT;
|
||||
if(active)
|
||||
c.arg[0] |= ISO14A_NO_SELECT;
|
||||
c.arg[0] |= FELICA_NO_SELECT;
|
||||
}
|
||||
|
||||
if (bTimeout){
|
||||
#define MAX_TIMEOUT 40542464 // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
|
||||
c.arg[0] |= ISO14A_SET_TIMEOUT;
|
||||
if(timeout > MAX_TIMEOUT) {
|
||||
timeout = MAX_TIMEOUT;
|
||||
PrintAndLog("Set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
|
||||
}
|
||||
c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
|
||||
}
|
||||
|
||||
if (power) {
|
||||
c.arg[0] |= ISO14A_NO_DISCONNECT;
|
||||
c.arg[0] |= FELICA_NO_DISCONNECT;
|
||||
}
|
||||
|
||||
if (datalen>0) {
|
||||
c.arg[0] |= ISO14A_RAW;
|
||||
if (datalen > 0) {
|
||||
c.arg[0] |= FELICA_RAW;
|
||||
}
|
||||
|
||||
// Max buffer is USB_CMD_DATA_SIZE
|
||||
|
||||
@@ -7,21 +7,8 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// High frequency Topaz (NFC Type 1) commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhftopaz.h"
|
||||
#include "cmdhf14a.h"
|
||||
#include "ui.h"
|
||||
#include "mifare.h"
|
||||
#include "proxmark3.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "protocols.h"
|
||||
#include "cmdhf.h"
|
||||
|
||||
#define TOPAZ_STATIC_MEMORY (0x0f * 8) // 15 blocks with 8 Bytes each
|
||||
|
||||
// a struct to describe a memory area which contains lock bits and the corresponding lockable memory area
|
||||
@@ -43,24 +30,18 @@ static struct {
|
||||
dynamic_lock_area_t *dynamic_lock_areas; // lock area descriptors
|
||||
} topaz_tag;
|
||||
|
||||
|
||||
static void topaz_switch_on_field(void)
|
||||
{
|
||||
static void topaz_switch_on_field(void) {
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, 0, 0}};
|
||||
SendCommand(&c);
|
||||
}
|
||||
|
||||
|
||||
static void topaz_switch_off_field(void)
|
||||
{
|
||||
static void topaz_switch_off_field(void) {
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
|
||||
SendCommand(&c);
|
||||
}
|
||||
|
||||
|
||||
// send a raw topaz command, returns the length of the response (0 in case of error)
|
||||
static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response)
|
||||
{
|
||||
static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response) {
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0}};
|
||||
memcpy(c.d.asBytes, cmd, len);
|
||||
SendCommand(&c);
|
||||
@@ -77,13 +58,12 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response)
|
||||
|
||||
|
||||
// calculate CRC bytes and send topaz command, returns the length of the response (0 in case of error)
|
||||
static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response)
|
||||
{
|
||||
static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) {
|
||||
if (len > 1) {
|
||||
uint8_t first, second;
|
||||
ComputeCrc14443(CRC_14443_B, cmd, len-2, &first, &second);
|
||||
cmd[len-2] = first;
|
||||
cmd[len-1] = second;
|
||||
uint8_t b1, b2;
|
||||
compute_crc(CRC_14443_B, cmd, len-2, &b1, &b2);
|
||||
cmd[len-2] = b1;
|
||||
cmd[len-1] = b2;
|
||||
}
|
||||
|
||||
return topaz_send_cmd_raw(cmd, len, response);
|
||||
@@ -91,8 +71,7 @@ static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response)
|
||||
|
||||
|
||||
// select a topaz tag. Send WUPA and RID.
|
||||
static int topaz_select(uint8_t *atqa, uint8_t *rid_response)
|
||||
{
|
||||
static int topaz_select(uint8_t *atqa, uint8_t *rid_response) {
|
||||
// ToDo: implement anticollision
|
||||
|
||||
uint8_t wupa_cmd[] = {TOPAZ_WUPA};
|
||||
@@ -115,8 +94,7 @@ static int topaz_select(uint8_t *atqa, uint8_t *rid_response)
|
||||
|
||||
|
||||
// read all of the static memory of a selected Topaz tag.
|
||||
static int topaz_rall(uint8_t *uid, uint8_t *response)
|
||||
{
|
||||
static int topaz_rall(uint8_t *uid, uint8_t *response) {
|
||||
uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
memcpy(&rall_cmd[3], uid, 4);
|
||||
@@ -141,16 +119,12 @@ static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data)
|
||||
topaz_switch_off_field();
|
||||
return -1; // READ8 failed
|
||||
}
|
||||
|
||||
memcpy(block_data, &read8_response[1], 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// read a segment (16 blocks = 128 Bytes) of a selected Topaz tag. Works only for tags with dynamic memory.
|
||||
static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data)
|
||||
{
|
||||
static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data) {
|
||||
uint8_t rseg_cmd[] = {TOPAZ_RSEG, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8_t rseg_response[131];
|
||||
|
||||
@@ -160,18 +134,13 @@ static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data
|
||||
topaz_switch_off_field();
|
||||
return -1; // RSEG failed
|
||||
}
|
||||
|
||||
memcpy(segment_data, &rseg_response[1], 128);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// search for the lock area descriptor for the lockable area including byteno
|
||||
static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno)
|
||||
{
|
||||
dynamic_lock_area_t *lock_area;
|
||||
|
||||
static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) {
|
||||
dynamic_lock_area_t *lock_area;
|
||||
lock_area = topaz_tag.dynamic_lock_areas;
|
||||
|
||||
while (lock_area != NULL) {
|
||||
@@ -181,14 +150,11 @@ static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno)
|
||||
return lock_area;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// check if a memory byte is locked.
|
||||
static bool topaz_byte_is_locked(uint16_t byteno)
|
||||
{
|
||||
static bool topaz_byte_is_locked(uint16_t byteno) {
|
||||
uint8_t *lockbits;
|
||||
uint16_t locked_bytes_per_bit;
|
||||
dynamic_lock_area_t *lock_area;
|
||||
@@ -217,9 +183,8 @@ static bool topaz_byte_is_locked(uint16_t byteno)
|
||||
|
||||
|
||||
// read and print the Capability Container
|
||||
static int topaz_print_CC(uint8_t *data)
|
||||
{
|
||||
if(data[0] != 0xe1) {
|
||||
static int topaz_print_CC(uint8_t *data) {
|
||||
if (data[0] != 0xe1) {
|
||||
topaz_tag.size = TOPAZ_STATIC_MEMORY;
|
||||
return -1; // no NDEF message
|
||||
}
|
||||
@@ -239,8 +204,7 @@ static int topaz_print_CC(uint8_t *data)
|
||||
|
||||
|
||||
// return type, length and value of a TLV, starting at memory position *TLV_ptr
|
||||
static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value)
|
||||
{
|
||||
static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) {
|
||||
*TLV_length = 0;
|
||||
*TLV_value = NULL;
|
||||
|
||||
@@ -274,8 +238,7 @@ static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length,
|
||||
// lock area TLVs contain no information on the start of the respective lockable area. Lockable areas
|
||||
// do not include the lock bits and reserved memory. We therefore need to adjust the start of the
|
||||
// respective lockable areas accordingly
|
||||
static void adjust_lock_areas(uint16_t block_start, uint16_t block_size)
|
||||
{
|
||||
static void adjust_lock_areas(uint16_t block_start, uint16_t block_size) {
|
||||
dynamic_lock_area_t *lock_area = topaz_tag.dynamic_lock_areas;
|
||||
while (lock_area != NULL) {
|
||||
if (lock_area->first_locked_byte <= block_start) {
|
||||
@@ -287,8 +250,7 @@ static void adjust_lock_areas(uint16_t block_start, uint16_t block_size)
|
||||
|
||||
|
||||
// read and print the lock area and reserved memory TLVs
|
||||
static void topaz_print_control_TLVs(uint8_t *memory)
|
||||
{
|
||||
static void topaz_print_control_TLVs(uint8_t *memory) {
|
||||
uint8_t *TLV_ptr = memory;
|
||||
uint8_t TLV_type = 0;
|
||||
uint16_t TLV_length;
|
||||
@@ -297,7 +259,7 @@ static void topaz_print_control_TLVs(uint8_t *memory)
|
||||
bool reserved_memory_control_TLV_present = false;
|
||||
uint16_t next_lockable_byte = 0x0f * 8; // first byte after static memory area
|
||||
|
||||
while(*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) {
|
||||
while (*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) {
|
||||
// all Lock Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV)
|
||||
get_TLV(&TLV_ptr, &TLV_type, &TLV_length, &TLV_value);
|
||||
if (TLV_type == 0x01) { // a Lock Control TLV
|
||||
@@ -360,32 +322,28 @@ static void topaz_print_control_TLVs(uint8_t *memory)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// read all of the dynamic memory
|
||||
static int topaz_read_dynamic_data(void)
|
||||
{
|
||||
static int topaz_read_dynamic_data(void){
|
||||
// first read the remaining block of segment 0
|
||||
if(topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) {
|
||||
if (topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) {
|
||||
PrintAndLog("Error while reading dynamic memory block %02x. Aborting...", 0x0f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// read the remaining segments
|
||||
uint8_t max_segment = topaz_tag.size / 128 - 1;
|
||||
for(uint8_t segment = 1; segment <= max_segment; segment++) {
|
||||
if(topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment-1)*128+8]) == -1) {
|
||||
for (uint8_t segment = 1; segment <= max_segment; segment++) {
|
||||
if (topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment-1)*128+8]) == -1) {
|
||||
PrintAndLog("Error while reading dynamic memory block %02x. Aborting...", 0x0f);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// read and print the dynamic memory
|
||||
static void topaz_print_dynamic_data(void)
|
||||
{
|
||||
static void topaz_print_dynamic_data(void) {
|
||||
if (topaz_tag.size > TOPAZ_STATIC_MEMORY) {
|
||||
PrintAndLog("Dynamic Data blocks:");
|
||||
if (topaz_read_dynamic_data() == 0) {
|
||||
@@ -405,22 +363,16 @@ static void topaz_print_dynamic_data(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void topaz_print_lifecycle_state(uint8_t *data)
|
||||
{
|
||||
static void topaz_print_lifecycle_state(uint8_t *data) {
|
||||
// to be done
|
||||
}
|
||||
|
||||
|
||||
static void topaz_print_NDEF(uint8_t *data)
|
||||
{
|
||||
static void topaz_print_NDEF(uint8_t *data) {
|
||||
// to be done.
|
||||
}
|
||||
|
||||
|
||||
// read a Topaz tag and print some usefull information
|
||||
int CmdHFTopazReader(const char *Cmd)
|
||||
{
|
||||
// read a Topaz tag and print some useful information
|
||||
int CmdHFTopazReader(const char *Cmd) {
|
||||
int status;
|
||||
uint8_t atqa[2];
|
||||
uint8_t rid_response[8];
|
||||
@@ -463,7 +415,7 @@ int CmdHFTopazReader(const char *Cmd)
|
||||
|
||||
status = topaz_rall(uid_echo, rall_response);
|
||||
|
||||
if(status == -1) {
|
||||
if (status == -1) {
|
||||
PrintAndLog("Error: tag didn't answer to RALL");
|
||||
topaz_switch_off_field();
|
||||
return -1;
|
||||
@@ -553,8 +505,7 @@ int CmdHFTopazList(const char *Cmd) {
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"reader", CmdHFTopazReader, 0, "Act like a Topaz reader"},
|
||||
{"sim", CmdHFTopazSim, 0, "<UID> -- Simulate Topaz tag"},
|
||||
|
||||
@@ -11,6 +11,20 @@
|
||||
#ifndef CMDHFTOPAZ_H__
|
||||
#define CMDHFTOPAZ_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf14a.h"
|
||||
#include "ui.h"
|
||||
#include "mifare.h"
|
||||
#include "proxmark3.h"
|
||||
#include "crc16.h"
|
||||
#include "protocols.h"
|
||||
#include "cmdhf.h"
|
||||
|
||||
extern int CmdHFTopaz(const char *Cmd);
|
||||
extern int CmdHFTopazReader(const char *Cmd);
|
||||
extern int CmdHFTopazSim(const char *Cmd);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "data.h"
|
||||
#include "util.h"
|
||||
#include "crapto1/crapto1.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "crc16.h"
|
||||
#include "protocols.h"
|
||||
#include "mifare.h"
|
||||
#include "mfkey.h"
|
||||
|
||||
@@ -227,21 +227,14 @@ static int l_CmdConsole(lua_State *L) {
|
||||
}
|
||||
|
||||
static int l_iso15693_crc(lua_State *L) {
|
||||
// uint16_t Iso15693Crc(uint8_t *v, int n);
|
||||
size_t size;
|
||||
const char *v = luaL_checklstring(L, 1, &size);
|
||||
// iceman, should be size / 2 ?!?
|
||||
uint16_t retval = Iso15693Crc((uint8_t *) v, size);
|
||||
lua_pushunsigned(L, retval);
|
||||
lua_pushunsigned(L, crc( CRC_15693, (uint8_t *) v, size));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_iso14443b_crc(lua_State *L) {
|
||||
/* void ComputeCrc14443(int CrcType,
|
||||
const unsigned char *Data, int Length,
|
||||
unsigned char *TransmitFirst,
|
||||
unsigned char *TransmitSecond)
|
||||
*/
|
||||
uint32_t tmp;
|
||||
unsigned char buf[USB_CMD_DATA_SIZE] = {0x00};
|
||||
size_t size = 0;
|
||||
@@ -253,7 +246,7 @@ static int l_iso14443b_crc(lua_State *L) {
|
||||
}
|
||||
|
||||
size /= 2;
|
||||
ComputeCrc14443(CRC_14443_B, buf, size, &buf[size], &buf[size+1]);
|
||||
compute_crc(CRC_14443_B, buf, size, &buf[size], &buf[size+1]);
|
||||
lua_pushlstring(L, (const char *)&buf, size+2);
|
||||
return 1;
|
||||
}
|
||||
@@ -397,6 +390,7 @@ static int l_crc16(lua_State *L) {
|
||||
size_t size;
|
||||
const char *p_str = luaL_checklstring(L, 1, &size);
|
||||
|
||||
//iceman tochange
|
||||
uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size);
|
||||
lua_pushunsigned(L, retval);
|
||||
return 1;
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include "cmdmain.h"
|
||||
#include "util.h"
|
||||
#include "mifarehost.h"
|
||||
#include "iso15693tools.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "crc.h"
|
||||
#include "crc16.h"
|
||||
#include "crc64.h"
|
||||
|
||||
@@ -729,6 +729,14 @@ void rol(uint8_t *data, const size_t len){
|
||||
data[len-1] = first;
|
||||
}
|
||||
|
||||
/*
|
||||
uint8_t pw_rev_A(uint8_t b) {
|
||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||
return b;
|
||||
}
|
||||
*/
|
||||
uint8_t reflect8(uint8_t b) {
|
||||
return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user