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" 
  26 static int CmdHelp(const char *Cmd
); 
  28 int CmdHF14BDemod(const char *Cmd
) 
  33   bool negateI
, negateQ
; 
  38   // As received, the samples are pairs, correlations against I and Q 
  39   // square waves. So estimate angle of initial carrier (or just 
  40   // quadrant, actually), and then do the demod. 
  42   // First, estimate where the tag starts modulating. 
  43   for (i 
= 0; i 
< GraphTraceLen
; i 
+= 2) { 
  44     if (abs(GraphBuffer
[i
]) + abs(GraphBuffer
[i 
+ 1]) > 40) { 
  48   if (i 
>= GraphTraceLen
) { 
  49     PrintAndLog("too weak to sync"); 
  52   PrintAndLog("out of weak at %d", i
); 
  55   // Now, estimate the phase in the initial modulation of the tag 
  58   for (; i 
< (outOfWeakAt 
+ 16); i 
+= 2) { 
  59     isum 
+= GraphBuffer
[i 
+ 0]; 
  60     qsum 
+= GraphBuffer
[i 
+ 1]; 
  65   // Turn the correlation pairs into soft decisions on the bit. 
  67   for (i 
= 0; i 
< GraphTraceLen 
/ 2; i
++) { 
  68     int si 
= GraphBuffer
[j
]; 
  69     int sq 
= GraphBuffer
[j 
+ 1]; 
  70     if (negateI
) si 
= -si
; 
  71     if (negateQ
) sq 
= -sq
; 
  72     GraphBuffer
[i
] = si 
+ sq
; 
  78   while (GraphBuffer
[i
] > 0 && i 
< GraphTraceLen
) 
  80   if (i 
>= GraphTraceLen
) goto demodError
; 
  83   while (GraphBuffer
[i
] < 0 && i 
< GraphTraceLen
) 
  85   if (i 
>= GraphTraceLen
) goto demodError
; 
  86   if ((i 
- iold
) > 23) goto demodError
; 
  88   PrintAndLog("make it to demod loop"); 
  92     while (GraphBuffer
[i
] >= 0 && i 
< GraphTraceLen
) 
  94     if (i 
>= GraphTraceLen
) goto demodError
; 
  95     if ((i 
- iold
) > 6) goto demodError
; 
  97     uint16_t shiftReg 
= 0; 
  98     if (i 
+ 20 >= GraphTraceLen
) goto demodError
; 
 100     for (j 
= 0; j 
< 10; j
++) { 
 101       int soft 
= GraphBuffer
[i
] + GraphBuffer
[i 
+ 1]; 
 103       if (abs(soft
) < (abs(isum
) + abs(qsum
)) / 20) { 
 104         PrintAndLog("weak bit"); 
 108       if(GraphBuffer
[i
] + GraphBuffer
[i
+1] >= 0) { 
 115     if ((shiftReg 
& 0x200) && !(shiftReg 
& 0x001)) 
 117       // valid data byte, start and stop bits okay 
 118       PrintAndLog("   %02x", (shiftReg 
>> 1) & 0xff); 
 119       data
[dataLen
++] = (shiftReg 
>> 1) & 0xff; 
 120       if (dataLen 
>= sizeof(data
)) { 
 123     } else if (shiftReg 
== 0x000) { 
 131   uint8_t first
, second
; 
 132   ComputeCrc14443(CRC_14443_B
, data
, dataLen
-2, &first
, &second
); 
 133   PrintAndLog("CRC: %02x %02x (%s)\n", first
, second
, 
 134     (first 
== data
[dataLen
-2] && second 
== data
[dataLen
-1]) ? 
 135       "ok" : "****FAIL****"); 
 137   RepaintGraphWindow(); 
 141   PrintAndLog("demod error"); 
 142   RepaintGraphWindow(); 
 146 int CmdHF14BList(const char *Cmd
) 
 148         PrintAndLog("Deprecated command, use 'hf list 14b' instead"); 
 152 int CmdHF14BRead(const char *Cmd
) 
 154   UsbCommand c 
= {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
 159 int CmdHF14Sim(const char *Cmd
) 
 161   UsbCommand c
={CMD_SIMULATE_TAG_ISO_14443
}; 
 166 int CmdHFSimlisten(const char *Cmd
) 
 168   UsbCommand c 
= {CMD_SIMULATE_TAG_HF_LISTEN
}; 
 173 int CmdHF14BSnoop(const char *Cmd
) 
 175   UsbCommand c 
= {CMD_SNOOP_ISO_14443
}; 
 180 /* New command to read the contents of a SRI512 tag 
 181  * SRI512 tags are ISO14443-B modulated memory tags, 
 182  * this command just dumps the contents of the memory 
 184 int CmdSri512Read(const char *Cmd
) 
 186   UsbCommand c 
= {CMD_READ_SRI512_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
 191 /* New command to read the contents of a SRIX4K tag 
 192  * SRIX4K tags are ISO14443-B modulated memory tags, 
 193  * this command just dumps the contents of the memory/ 
 195 int CmdSrix4kRead(const char *Cmd
) 
 197   UsbCommand c 
= {CMD_READ_SRIX4K_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
 202 int CmdHF14BCmdRaw (const char *cmd
) { 
 205     UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; // len,recv? 
 211     uint8_t data
[100] = {0x00}; 
 212     unsigned int datalen
=0, temp
; 
 216         PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>"); 
 217         PrintAndLog("       -r    do not read response"); 
 218         PrintAndLog("       -c    calculate and append CRC"); 
 219         PrintAndLog("       -p    leave the field on after receive"); 
 224     while (*cmd
==' ' || *cmd
=='\t') cmd
++; 
 226     while (cmd
[i
]!='\0') { 
 227         if (cmd
[i
]==' ' || cmd
[i
]=='\t') { i
++; continue; } 
 243                     PrintAndLog("Invalid option"); 
 249         if ((cmd
[i
]>='0' && cmd
[i
]<='9') || 
 250             (cmd
[i
]>='a' && cmd
[i
]<='f') || 
 251             (cmd
[i
]>='A' && cmd
[i
]<='F') ) { 
 252             buf
[strlen(buf
)+1]=0; 
 253             buf
[strlen(buf
)]=cmd
[i
]; 
 256             if (strlen(buf
)>=2) { 
 257                 sscanf(buf
,"%x",&temp
); 
 258                 data
[datalen
]=(uint8_t)(temp 
& 0xff); 
 264         PrintAndLog("Invalid char on input"); 
 269       PrintAndLog("Missing data input"); 
 274         uint8_t first
, second
; 
 275         ComputeCrc14443(CRC_14443_B
, data
, datalen
, &first
, &second
); 
 276         data
[datalen
++] = first
; 
 277         data
[datalen
++] = second
; 
 283     memcpy(c
.d
.asBytes
,data
,datalen
); 
 288         if (WaitForResponseTimeout(CMD_ACK
,&resp
,1000)) { 
 289             recv 
= resp
.d
.asBytes
; 
 290             PrintAndLog("received %i octets",resp
.arg
[0]); 
 293             hexout 
= (char *)malloc(resp
.arg
[0] * 3 + 1); 
 294             if (hexout 
!= NULL
) { 
 295                 uint8_t first
, second
; 
 296                 for (int i 
= 0; i 
< resp
.arg
[0]; i
++) { // data in hex 
 297                     sprintf(&hexout
[i 
* 3], "%02X ", recv
[i
]); 
 299                 PrintAndLog("%s", hexout
); 
 301                                 if (resp
.arg
[0] > 2) { 
 302                                         ComputeCrc14443(CRC_14443_B
, recv
, resp
.arg
[0]-2, &first
, &second
); 
 303                                         if(recv
[resp
.arg
[0]-2]==first 
&& recv
[resp
.arg
[0]-1]==second
) { 
 304                                                 PrintAndLog("CRC OK"); 
 306                                                 PrintAndLog("CRC failed"); 
 310                 PrintAndLog("malloc failed your client has low memory?"); 
 313             PrintAndLog("timeout while waiting for reply."); 
 319 int CmdHF14BWrite( const char *Cmd
){ 
 322  * For SRIX4K  blocks 00 - 7F 
 323  * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata 
 325  * For SR512  blocks 00 - 0F 
 326  * hf 14b raw -c -p 09 $sr512wblock $sr512wdata 
 328  * Special block FF =  otp_lock_reg block. 
 331         char cmdp 
= param_getchar(Cmd
, 0); 
 332         uint8_t blockno 
= -1; 
 333         uint8_t data
[4] = {0x00}; 
 334         bool isSrix4k 
= true; 
 337         if (strlen(Cmd
) < 1 || cmdp 
== 'h' || cmdp 
== 'H') { 
 338                 PrintAndLog("Usage:  hf 14b write <1|2> <BLOCK> <DATA>"); 
 339                 PrintAndLog("    [1 = SRIX4K]"); 
 340                 PrintAndLog("    [2 = SRI512]"); 
 341                 PrintAndLog("    [BLOCK number depends on tag, special block == FF]"); 
 342                 PrintAndLog("     sample: hf 14b write 1 7F 11223344"); 
 343                 PrintAndLog("           : hf 14b write 1 FF 11223344"); 
 344                 PrintAndLog("           : hf 14b write 2 15 11223344"); 
 345                 PrintAndLog("           : hf 14b write 2 FF 11223344"); 
 352         //blockno = param_get8(Cmd, 1); 
 354         if ( param_gethex(Cmd
,1, &blockno
, 2) ) { 
 355                 PrintAndLog("Block number must include 2 HEX symbols"); 
 360                 if ( blockno 
> 0x7f && blockno 
!= 0xff ){ 
 361                         PrintAndLog("Block number out of range"); 
 365                 if ( blockno 
> 0x0f && blockno 
!= 0xff ){ 
 366                         PrintAndLog("Block number out of range"); 
 371         if (param_gethex(Cmd
, 2, data
, 8)) { 
 372                 PrintAndLog("Data must include 8 HEX symbols"); 
 376         if ( blockno 
== 0xff) 
 377                 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512" , blockno
,  sprint_hex(data
,4) ); 
 379                 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512", blockno
,  sprint_hex(data
,4) ); 
 381         sprintf(str
, "-c 09 %02x %02x%02x%02x%02x", blockno
, data
[0], data
[1], data
[2], data
[3]); 
 387 static command_t CommandTable
[] =  
 389   {"help",        CmdHelp
,        1, "This help"}, 
 390   {"demod",       CmdHF14BDemod
,  1, "Demodulate ISO14443 Type B from tag"}, 
 391   {"list",        CmdHF14BList
,   0, "[Deprecated] List ISO 14443b history"}, 
 392   {"read",        CmdHF14BRead
,   0, "Read HF tag (ISO 14443)"}, 
 393   {"sim",         CmdHF14Sim
,     0, "Fake ISO 14443 tag"}, 
 394   {"simlisten",   CmdHFSimlisten
, 0, "Get HF samples as fake tag"}, 
 395   {"snoop",       CmdHF14BSnoop
,  0, "Eavesdrop ISO 14443"}, 
 396   {"sri512read",  CmdSri512Read
,  0, "Read contents of a SRI512 tag"}, 
 397   {"srix4kread",  CmdSrix4kRead
,  0, "Read contents of a SRIX4K tag"}, 
 398   {"raw",         CmdHF14BCmdRaw
, 0, "Send raw hex data to tag"}, 
 399   {"write",       CmdHF14BWrite
,  0, "Write data to a SRI512 | SRIX4K tag"}, 
 400   {NULL
, NULL
, 0, NULL
} 
 403 int CmdHF14B(const char *Cmd
) 
 405   CmdsParse(CommandTable
, Cmd
); 
 409 int CmdHelp(const char *Cmd
) 
 411   CmdsHelp(CommandTable
);