1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com> 
   4 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   5 // at your option, any later version. See the LICENSE.txt file for the text of 
   7 //----------------------------------------------------------------------------- 
   8 // High frequency ISO14443B commands 
   9 //----------------------------------------------------------------------------- 
  16 #include "iso14443crc.h" 
  17 #include "proxmark3.h" 
  22 #include "cmdparser.h" 
  27 static int CmdHelp(const char *Cmd
); 
  29 int CmdHF14BDemod(const char *Cmd
) 
  34   bool negateI
, negateQ
; 
  39   // As received, the samples are pairs, correlations against I and Q 
  40   // square waves. So estimate angle of initial carrier (or just 
  41   // quadrant, actually), and then do the demod. 
  43   // First, estimate where the tag starts modulating. 
  44   for (i 
= 0; i 
< GraphTraceLen
; i 
+= 2) { 
  45     if (abs(GraphBuffer
[i
]) + abs(GraphBuffer
[i 
+ 1]) > 40) { 
  49   if (i 
>= GraphTraceLen
) { 
  50     PrintAndLog("too weak to sync"); 
  53   PrintAndLog("out of weak at %d", i
); 
  56   // Now, estimate the phase in the initial modulation of the tag 
  59   for (; i 
< (outOfWeakAt 
+ 16); i 
+= 2) { 
  60     isum 
+= GraphBuffer
[i 
+ 0]; 
  61     qsum 
+= GraphBuffer
[i 
+ 1]; 
  66   // Turn the correlation pairs into soft decisions on the bit. 
  68   for (i 
= 0; i 
< GraphTraceLen 
/ 2; i
++) { 
  69     int si 
= GraphBuffer
[j
]; 
  70     int sq 
= GraphBuffer
[j 
+ 1]; 
  71     if (negateI
) si 
= -si
; 
  72     if (negateQ
) sq 
= -sq
; 
  73     GraphBuffer
[i
] = si 
+ sq
; 
  79   while (GraphBuffer
[i
] > 0 && i 
< GraphTraceLen
) 
  81   if (i 
>= GraphTraceLen
) goto demodError
; 
  84   while (GraphBuffer
[i
] < 0 && i 
< GraphTraceLen
) 
  86   if (i 
>= GraphTraceLen
) goto demodError
; 
  87   if ((i 
- iold
) > 23) goto demodError
; 
  89   PrintAndLog("make it to demod loop"); 
  93     while (GraphBuffer
[i
] >= 0 && i 
< GraphTraceLen
) 
  95     if (i 
>= GraphTraceLen
) goto demodError
; 
  96     if ((i 
- iold
) > 6) goto demodError
; 
  98     uint16_t shiftReg 
= 0; 
  99     if (i 
+ 20 >= GraphTraceLen
) goto demodError
; 
 101     for (j 
= 0; j 
< 10; j
++) { 
 102       int soft 
= GraphBuffer
[i
] + GraphBuffer
[i 
+ 1]; 
 104       if (abs(soft
) < (abs(isum
) + abs(qsum
)) / 20) { 
 105         PrintAndLog("weak bit"); 
 109       if(GraphBuffer
[i
] + GraphBuffer
[i
+1] >= 0) { 
 116     if ((shiftReg 
& 0x200) && !(shiftReg 
& 0x001)) 
 118       // valid data byte, start and stop bits okay 
 119       PrintAndLog("   %02x", (shiftReg 
>> 1) & 0xff); 
 120       data
[dataLen
++] = (shiftReg 
>> 1) & 0xff; 
 121       if (dataLen 
>= sizeof(data
)) { 
 124     } else if (shiftReg 
== 0x000) { 
 132   uint8_t first
, second
; 
 133   ComputeCrc14443(CRC_14443_B
, data
, dataLen
-2, &first
, &second
); 
 134   PrintAndLog("CRC: %02x %02x (%s)\n", first
, second
, 
 135     (first 
== data
[dataLen
-2] && second 
== data
[dataLen
-1]) ? 
 136       "ok" : "****FAIL****"); 
 138   RepaintGraphWindow(); 
 142   PrintAndLog("demod error"); 
 143   RepaintGraphWindow(); 
 147 int CmdHF14BList(const char *Cmd
) 
 150   GetFromBigBuf(got
,sizeof(got
),0); 
 151   WaitForResponse(CMD_ACK
,NULL
); 
 153   PrintAndLog("recorded activity:"); 
 154   PrintAndLog(" time  :rssi: who bytes"); 
 155   PrintAndLog("---------+----+----+-----------"); 
 166     int timestamp 
= *((uint32_t *)(got
+i
)); 
 167     if(timestamp 
& 0x80000000) { 
 168       timestamp 
&= 0x7fffffff; 
 173     int metric 
= *((uint32_t *)(got
+i
+4)); 
 184     uint8_t *frame 
= (got
+i
+9); 
 186         // Break and stick with current result if buffer was not completely full 
 187         if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[2] == 0x44 && frame
[3] == 0x44) break;  
 189     char line
[1000] = ""; 
 191     for(j 
= 0; j 
< len
; j
++) { 
 192       sprintf(line
+(j
*3), "%02x  ", frame
[j
]); 
 198       ComputeCrc14443(CRC_14443_B
, frame
, len
-2, &b1
, &b2
); 
 199       if(b1 
!= frame
[len
-2] || b2 
!= frame
[len
-1]) { 
 200         crc 
= "**FAIL CRC**"; 
 208     char metricString
[100]; 
 210       sprintf(metricString
, "%3d", metric
); 
 212       strcpy(metricString
, "   "); 
 215     PrintAndLog(" +%7d: %s: %s %s %s", 
 216       (prev 
< 0 ? 0 : timestamp 
- prev
), 
 218       (isResponse 
? "TAG" : "   "), line
, crc
); 
 226 int CmdHF14BRead(const char *Cmd
) 
 228   UsbCommand c 
= {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
 233 int CmdHF14Sim(const char *Cmd
) 
 235   UsbCommand c
={CMD_SIMULATE_TAG_ISO_14443
}; 
 240 int CmdHFSimlisten(const char *Cmd
) 
 242   UsbCommand c 
= {CMD_SIMULATE_TAG_HF_LISTEN
}; 
 247 int CmdHF14BSnoop(const char *Cmd
) 
 249   UsbCommand c 
= {CMD_SNOOP_ISO_14443
}; 
 254 /* New command to read the contents of a SRI512 tag 
 255  * SRI512 tags are ISO14443-B modulated memory tags, 
 256  * this command just dumps the contents of the memory 
 258 int CmdSri512Read(const char *Cmd
) 
 260   UsbCommand c 
= {CMD_READ_SRI512_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
 265 /* New command to read the contents of a SRIX4K tag 
 266  * SRIX4K tags are ISO14443-B modulated memory tags, 
 267  * this command just dumps the contents of the memory/ 
 269 int CmdSrix4kRead(const char *Cmd
) 
 271   UsbCommand c 
= {CMD_READ_SRIX4K_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
 276 int CmdHF14BCmdRaw (const char *cmd
) { 
 279     UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; // len,recv? 
 286     unsigned int datalen
=0, temp
; 
 290         PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>"); 
 291         PrintAndLog("       -r    do not read response"); 
 292         PrintAndLog("       -c    calculate and append CRC"); 
 293         PrintAndLog("       -p    leave the field on after receive"); 
 298     while (*cmd
==' ' || *cmd
=='\t') cmd
++; 
 300     while (cmd
[i
]!='\0') { 
 301         if (cmd
[i
]==' ' || cmd
[i
]=='\t') { i
++; continue; } 
 317                     PrintAndLog("Invalid option"); 
 323         if ((cmd
[i
]>='0' && cmd
[i
]<='9') || 
 324             (cmd
[i
]>='a' && cmd
[i
]<='f') || 
 325             (cmd
[i
]>='A' && cmd
[i
]<='F') ) { 
 326             buf
[strlen(buf
)+1]=0; 
 327             buf
[strlen(buf
)]=cmd
[i
]; 
 330             if (strlen(buf
)>=2) { 
 331                 sscanf(buf
,"%x",&temp
); 
 332                 data
[datalen
]=(uint8_t)(temp 
& 0xff); 
 338         PrintAndLog("Invalid char on input"); 
 343       PrintAndLog("Missing data input"); 
 348         uint8_t first
, second
; 
 349         ComputeCrc14443(CRC_14443_B
, data
, datalen
, &first
, &second
); 
 350         data
[datalen
++] = first
; 
 351         data
[datalen
++] = second
; 
 357     memcpy(c
.d
.asBytes
,data
,datalen
); 
 362         if (WaitForResponseTimeout(CMD_ACK
,&resp
,1000)) { 
 363             recv 
= resp
.d
.asBytes
; 
 364             PrintAndLog("received %i octets",resp
.arg
[0]); 
 367             hexout 
= (char *)malloc(resp
.arg
[0] * 3 + 1); 
 368             if (hexout 
!= NULL
) { 
 369                 uint8_t first
, second
; 
 370                 for (int i 
= 0; i 
< resp
.arg
[0]; i
++) { // data in hex 
 371                     sprintf(&hexout
[i 
* 3], "%02X ", recv
[i
]); 
 373                 PrintAndLog("%s", hexout
); 
 375                 ComputeCrc14443(CRC_14443_B
, recv
, resp
.arg
[0]-2, &first
, &second
); 
 376                 if(recv
[resp
.arg
[0]-2]==first 
&& recv
[resp
.arg
[0]-1]==second
) { 
 377                     PrintAndLog("CRC OK"); 
 379                     PrintAndLog("CRC failed"); 
 382                 PrintAndLog("malloc failed your client has low memory?"); 
 385             PrintAndLog("timeout while waiting for reply."); 
 391 int CmdHF14BWrite( const char *Cmd
){ 
 394  * For SRIX4K  blocks 00 - 7F 
 395  * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata 
 397  * For SR512  blocks 00 - 0F 
 398  * hf 14b raw -c -p 09 $sr512wblock $sr512wdata 
 400  * Special block FF =  otp_lock_reg block. 
 403         char cmdp 
= param_getchar(Cmd
, 0); 
 404         uint8_t blockno 
= -1; 
 405         uint8_t data
[4] = {0x00}; 
 406         bool isSrix4k 
= true; 
 409         if (cmdp 
== 'h' || cmdp 
== 'H') { 
 410                 PrintAndLog("Usage:  hf 14b write <1|2> <BLOCK> <DATA>"); 
 412                 PrintAndLog("     sample: hf 14b write 1 127 11223344"); 
 413                 PrintAndLog("     sample: hf 14b write 1 255 11223344"); 
 414                 PrintAndLog("     sample: hf 14b write 2 15 11223344"); 
 415                 PrintAndLog("     sample: hf 14b write 2 255 11223344"); 
 419         if ( param_getchar(Cmd
, 0) == '2' ) 
 422         blockno 
= param_get8(Cmd
, 1); 
 425                 if ( blockno 
> 0x7f && blockno 
!= 0xff ){ 
 426                         PrintAndLog("Block number out of range"); 
 430                 if ( blockno 
> 0x0f && blockno 
!= 0xff ){ 
 431                         PrintAndLog("Block number out of range"); 
 436         if (param_gethex(Cmd
, 2, data
, 8)) { 
 437                 PrintAndLog("Data must include 8 HEX symbols"); 
 441         if ( blockno 
== 0xff) 
 442                 PrintAndLog("Writing to special block %02X [ %s]", blockno
,  sprint_hex(data
,4) ); 
 444                 PrintAndLog("Writing to block %02X [ %s]", blockno
,  sprint_hex(data
,4) ); 
 446         sprintf(str
, "-c -p 09 %02x %02x%02x%02x%02x", blockno
, data
[0], data
[1], data
[2], data
[3]); 
 451 static command_t CommandTable
[] =  
 453   {"help",        CmdHelp
,        1, "This help"}, 
 454   {"demod",       CmdHF14BDemod
,  1, "Demodulate ISO14443 Type B from tag"}, 
 455   {"list",        CmdHF14BList
,   0, "List ISO 14443 history"}, 
 456   {"read",        CmdHF14BRead
,   0, "Read HF tag (ISO 14443)"}, 
 457   {"sim",         CmdHF14Sim
,     0, "Fake ISO 14443 tag"}, 
 458   {"simlisten",   CmdHFSimlisten
, 0, "Get HF samples as fake tag"}, 
 459   {"snoop",       CmdHF14BSnoop
,  0, "Eavesdrop ISO 14443"}, 
 460   {"sri512read",  CmdSri512Read
,  0, "Read contents of a SRI512 tag"}, 
 461   {"srix4kread",  CmdSrix4kRead
,  0, "Read contents of a SRIX4K tag"}, 
 462   {"raw",         CmdHF14BCmdRaw
, 0, "Send raw hex data to tag"}, 
 463   {"write",       CmdHF14BWrite
,  0, "Write data to a SRI512 | SRIX4K tag"}, 
 464   {NULL
, NULL
, 0, NULL
} 
 467 int CmdHF14B(const char *Cmd
) 
 469   CmdsParse(CommandTable
, Cmd
); 
 473 int CmdHelp(const char *Cmd
) 
 475   CmdsHelp(CommandTable
);