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 //----------------------------------------------------------------------------- 
  15 #include "iso14443crc.h" 
  16 #include "proxmark3.h" 
  21 #include "cmdparser.h" 
  30 static int CmdHelp(const char *Cmd
); 
  32 int CmdHF14BList(const char *Cmd
) { 
  37 int CmdHF14BSim(const char *Cmd
) 
  39         UsbCommand c 
= {CMD_SIMULATE_TAG_ISO_14443B
}; 
  45 int CmdHF14BSnoop(const char *Cmd
) 
  47         UsbCommand c 
= {CMD_SNOOP_ISO_14443B
}; 
  53 /* New command to read the contents of a SRI512 tag 
  54  * SRI512 tags are ISO14443-B modulated memory tags, 
  55  * this command just dumps the contents of the memory 
  57 int CmdSri512Read(const char *Cmd
) 
  59         UsbCommand c 
= {CMD_READ_SRI512_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
  65 /* New command to read the contents of a SRIX4K tag 
  66  * SRIX4K tags are ISO14443-B modulated memory tags, 
  67  * this command just dumps the contents of the memory/ 
  69 int CmdSrix4kRead(const char *Cmd
) { 
  70         UsbCommand c 
= {CMD_READ_SRIX4K_TAG
, {strtol(Cmd
, NULL
, 0), 0, 0}}; 
  76 static int rawCloseEx(bool silent
){ 
  78         UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; 
  81         if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1000)) { 
  82                 if ( !silent 
) PrintAndLog("Command time-out"); 
  87 static int rawClose() { 
  88         return rawCloseEx(false); 
  91 int HF14BCmdRaw(bool reply
, bool *crc
, bool power
, uint8_t *data
, uint8_t *datalen
, bool verbose
){ 
  94                 ComputeCrc14443(CRC_14443_B
, data
, *datalen
, data
+*datalen
, data
+*datalen
+1); 
  98         UsbCommand c 
= {CMD_ISO_14443B_COMMAND
, {0, 0, 0}}; // len,recv,power 
 102         memcpy(c
.d
.asBytes
, data
, *datalen
); 
 103         clearCommandBuffer(); 
 106         if (!reply
) return 1;  
 109         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 2000)) { 
 110                 if (verbose
) PrintAndLog("timeout while waiting for reply."); 
 114         *datalen 
= resp
.arg
[0]; 
 115         if (verbose
) PrintAndLog("received %u octets", *datalen
); 
 116         if(*datalen
<3) return 0; 
 118         memcpy(data
, resp
.d
.asBytes
, *datalen
); 
 120         uint8_t first 
= 0, second 
= 0; 
 121         ComputeCrc14443(CRC_14443_B
, data
, *datalen
-2, &first
, &second
); 
 122         *crc 
= ( data
[*datalen
-2] == first 
&& data
[*datalen
-1] == second
); 
 125                 PrintAndLog("[LEN %u] %s[%02X %02X] %s", 
 127                                 sprint_hex(data
, *datalen
-2), 
 136 int CmdHF14BCmdRaw (const char *Cmd
) { 
 143     uint8_t data
[USB_CMD_DATA_SIZE
] = {0x00}; 
 148                 PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>"); 
 149         PrintAndLog("       -r    do not read response"); 
 150         PrintAndLog("       -c    calculate and append CRC"); 
 151         PrintAndLog("       -p    leave the field on after receive"); 
 152                 PrintAndLog("       -s    active signal field ON with select"); 
 153                 PrintAndLog("       -ss   active signal field ON with select for SRx ST Microelectronics tags"); 
 158     while (*Cmd
==' ' || *Cmd
=='\t') Cmd
++; 
 160     while (Cmd
[i
]!='\0') { 
 161         if (Cmd
[i
]==' ' || Cmd
[i
]=='\t') { i
++; continue; } 
 179                                         if (Cmd
[i
+2]=='s' || Cmd
[i
+2]=='S') { 
 185                     PrintAndLog("Invalid option"); 
 191         if ((Cmd
[i
]>='0' && Cmd
[i
]<='9') || 
 192             (Cmd
[i
]>='a' && Cmd
[i
]<='f') || 
 193             (Cmd
[i
]>='A' && Cmd
[i
]<='F') ) { 
 194             buf
[strlen(buf
)+1]=0; 
 195             buf
[strlen(buf
)]=Cmd
[i
]; 
 198             if (strlen(buf
)>=2) { 
 199                 sscanf(buf
,"%x",&temp
); 
 200                 data
[datalen
++]=(uint8_t)(temp 
& 0xff); 
 202                                 memset(buf
, 0x00, sizeof(buf
)); 
 206         PrintAndLog("Invalid char on input"); 
 211       PrintAndLog("Missing data input"); 
 215         if (select
){ //auto select 14b tag 
 234                 if (HF14BCmdRaw(true, &crc2
, true, cmd2
, &cmdLen
, false)==0) return rawClose(); 
 236                 PrintAndLog("REQB   : %s", sprint_hex(cmd2
, cmdLen
)); 
 238                 if ( SRx 
&& (cmdLen 
!= 3 || !crc2
) ) return rawClose(); 
 239                 else if (cmd2
[0] != 0x50 || cmdLen 
!= 14 || !crc2
) return rawClose(); 
 251                         // UID from cmd2[1 - 4] 
 261                 if (HF14BCmdRaw(true, &crc2
, true, cmd2
, &cmdLen
, false)==0) return rawClose(); 
 262                 PrintAndLog("ATTRIB : %s", sprint_hex(cmd2
, cmdLen
)); 
 264                 if (cmdLen 
!= 3 || !crc2
) return rawClose();             
 265                 if (SRx 
&& cmd2
[0] != chipID
) return rawClose(); 
 268         return HF14BCmdRaw(reply
, &crc
, power
, data
, &datalen
, true); 
 271 // print full atqb info 
 272 static void print_atqb_resp(uint8_t *data
){ 
 273         //PrintAndLog ("           UID: %s", sprint_hex(data+1,4)); 
 274         PrintAndLog ("      App Data: %s", sprint_hex(data
+5,4)); 
 275         PrintAndLog ("      Protocol: %s", sprint_hex(data
+9,3)); 
 276         uint8_t BitRate 
= data
[9]; 
 277         if (!BitRate
) PrintAndLog ("      Bit Rate: 106 kbit/s only PICC <-> PCD"); 
 278         if (BitRate 
& 0x10)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC -> PCD supported"); 
 279         if (BitRate 
& 0x20)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC -> PCD supported");  
 280         if (BitRate 
& 0x40)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC -> PCD supported");  
 281         if (BitRate 
& 0x01)     PrintAndLog ("      Bit Rate: 212 kbit/s PICC <- PCD supported"); 
 282         if (BitRate 
& 0x02)     PrintAndLog ("      Bit Rate: 424 kbit/s PICC <- PCD supported");  
 283         if (BitRate 
& 0x04)     PrintAndLog ("      Bit Rate: 847 kbit/s PICC <- PCD supported");  
 284         if (BitRate 
& 0x80)     PrintAndLog ("                Same bit rate <-> required"); 
 286         uint16_t maxFrame 
= data
[10]>>4; 
 287         if (maxFrame 
< 5)               maxFrame 
= 8 * maxFrame 
+ 16; 
 288         else if (maxFrame 
== 5) maxFrame 
= 64; 
 289         else if (maxFrame 
== 6) maxFrame 
= 96; 
 290         else if (maxFrame 
== 7) maxFrame 
= 128; 
 291         else if (maxFrame 
== 8) maxFrame 
= 256; 
 294         PrintAndLog ("Max Frame Size: %u%s",maxFrame
, (maxFrame 
== 257) ? "+ RFU" : ""); 
 296         uint8_t protocolT 
= data
[10] & 0xF; 
 297         PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT
) ? "" : "not " ); 
 298         PrintAndLog ("Frame Wait Int: %u", data
[11]>>4); 
 299         PrintAndLog (" App Data Code: Application is %s",(data
[11]&4) ? "Standard" : "Proprietary"); 
 300         PrintAndLog (" Frame Options: NAD is %ssupported",(data
[11]&2) ? "" : "not "); 
 301         PrintAndLog (" Frame Options: CID is %ssupported",(data
[11]&1) ? "" : "not "); 
 302         PrintAndLog ("Max Buf Length: %u (MBLI) %s",data
[14]>>4, (data
[14] & 0xF0) ? "" : "not supported"); 
 307 // get SRx chip model (from UID) // from ST Microelectronics 
 308 char *get_ST_Chip_Model(uint8_t data
){ 
 309         static char model
[20]; 
 310         char *retStr 
= model
; 
 311         memset(model
,0, sizeof(model
)); 
 314                 case 0x0: sprintf(retStr
, "SRIX4K (Special)"); break; 
 315                 case 0x2: sprintf(retStr
, "SR176"); break; 
 316                 case 0x3: sprintf(retStr
, "SRIX4K"); break; 
 317                 case 0x4: sprintf(retStr
, "SRIX512"); break; 
 318                 case 0x6: sprintf(retStr
, "SRI512"); break; 
 319                 case 0x7: sprintf(retStr
, "SRI4K"); break; 
 320                 case 0xC: sprintf(retStr
, "SRT512"); break; 
 321                 default : sprintf(retStr
, "Unknown"); break; 
 326 int print_ST_Lock_info(uint8_t model
){ 
 327         //assume connection open and tag selected... 
 328         uint8_t data
[16] = {0x00}; 
 335         if (model 
== 0x2) { //SR176 has special command: 
 344         if (HF14BCmdRaw(true, &crc
, true, data
, &datalen
, false)==0) return rawClose(); 
 346         if (datalen 
!= resplen 
|| !crc
) return rawClose(); 
 348         PrintAndLog("Chip Write Protection Bits:"); 
 349         // now interpret the data 
 351                 case 0x0: //fall through (SRIX4K special) 
 352                 case 0x3: //fall through (SRIx4K) 
 356                         PrintAndLog("   raw: %s", sprint_bin(data
+3, 1)); 
 357                         PrintAndLog(" 07/08:%slocked", (data
[3] & 1) ? " not " : " " ); 
 358                         for (uint8_t i 
= 1; i
<8; i
++){ 
 359                                 PrintAndLog("    %02u:%slocked", blk1
, (data
[3] & (1 << i
)) ? " not " : " " ); 
 363                 case 0x4: //fall through (SRIX512) 
 364                 case 0x6: //fall through (SRI512) 
 365                 case 0xC: //             (SRT512) 
 366                         //need data[2] and data[3] 
 368                         PrintAndLog("   raw: %s", sprint_bin(data
+2, 2)); 
 369                         for (uint8_t b
=2; b
<4; b
++){ 
 370                                 for (uint8_t i
=0; i
<8; i
++){ 
 371                                         PrintAndLog("    %02u:%slocked", blk1
, (data
[b
] & (1 << i
)) ? " not " : " " ); 
 379                         PrintAndLog("   raw: %s", sprint_bin(data
+2, 1)); 
 380                         for (uint8_t i 
= 0; i
<8; i
++){ 
 381                                 PrintAndLog(" %02u/%02u:%slocked", blk1
, blk1
+1, (data
[2] & (1 << i
)) ? " " : " not " ); 
 391 // print UID info from SRx chips (ST Microelectronics) 
 392 static void print_st_general_info(uint8_t *data
){ 
 393         //uid = first 8 bytes in data 
 394         PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data
,8,8),8)); 
 395         PrintAndLog(" MFG: %02X, %s", data
[6], getTagInfo(data
[6])); 
 396         PrintAndLog("Chip: %02X, %s", data
[5]>>2, get_ST_Chip_Model(data
[5]>>2)); 
 400 // 14b get and print UID only (general info) 
 401 int HF14BStdReader(uint8_t *data
, uint8_t *datalen
){ 
 402         //05 00 00 = find one tag in field 
 403         //1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0]) 
 404         //a3 = ?  (resp 03 [e2 c2]) 
 405         //02 = ?  (resp 02 [6a d3]) 
 406         // 022b (resp 02 67 00 [29  5b]) 
 407         // 0200a40400 (resp 02 67 00 [29 5b]) 
 408         // 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b]) 
 409         // 0200a4040c07a0000002480200 (resp 02 67 00 [29 5b]) 
 410         // 0200a4040006a0000000010100 (resp 02 6a 82 [4b 4c]) 
 411         // 0200a4040c09d27600002545500200 (resp 02 67 00 [29 5b]) 
 412         // 0200a404000cd2760001354b414e4d30310000 (resp 02 6a 82 [4b 4c]) 
 413         // 0200a404000ca000000063504b43532d313500 (resp 02 6a 82 [4b 4c]) 
 414         // 0200a4040010a000000018300301000000000000000000 (resp 02 6a 82 [4b 4c]) 
 415         //03 = ?  (resp 03 [e3 c2]) 
 416         //c2 = ?  (resp c2 [66 15]) 
 417         //b2 = ?  (resp a3 [e9 67])              
 418         //a2 = ?  (resp 02 [6a d3]) 
 426         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 428         if (data
[0] != 0x50 || *datalen 
!= 14 || !crc
) return rawClose(); 
 430         PrintAndLog ("\n14443-3b tag found:"); 
 431         PrintAndLog ("           UID: %s", sprint_hex(data
+1,4)); 
 438         // UID from data[1 - 4] 
 450         if (HF14BCmdRaw(true, &crc2
, true, cmd2
, &cmdLen
, false)==0) return rawClose(); 
 452         if (cmdLen 
!= 3 || !crc2
) return rawClose(); 
 453         // add attrib responce to data 
 459 // 14b get and print Full Info (as much as we know) 
 460 int HF14BStdInfo(uint8_t *data
, uint8_t *datalen
){ 
 461         if (!HF14BStdReader(data
,datalen
)) return 0; 
 464         print_atqb_resp(data
); 
 468 // SRx get and print general info about SRx chip from UID 
 469 int HF14B_ST_Reader(uint8_t *data
, uint8_t *datalen
, bool closeCon
){ 
 477         // verbose on for now for testing - turn off when functional 
 478         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 480         if (*datalen 
!= 3 || !crc
) return rawClose(); 
 482         uint8_t chipID 
= data
[0]; 
 489         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 491         if (*datalen 
!= 3 || !crc 
|| data
[0] != chipID
) return rawClose(); 
 498         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)==0) return rawClose(); 
 500         if (*datalen 
!= 10 || !crc
) return rawClose(); 
 503         if (closeCon
) rawClose(); 
 505         PrintAndLog("\n14443-3b ST tag found:"); 
 506         print_st_general_info(data
); 
 510 // SRx get and print full info (needs more info...) 
 511 int HF14B_ST_Info(uint8_t *data
, uint8_t *datalen
){ 
 512         if (!HF14B_ST_Reader(data
, datalen
, false)) return 0; 
 514         //add locking bit information here. 
 515         if (print_ST_Lock_info(data
[5]>>2))  
 521 // test for other 14b type tags (mimic another reader - don't have tags to identify) 
 522 int HF14B_Other_Reader(uint8_t *data
, uint8_t *datalen
){ 
 531         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 532                 if (*datalen 
> 2 || !crc
) { 
 533                         PrintAndLog ("\n14443-3b tag found:"); 
 534                         PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:"); 
 535                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 545         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 547                         PrintAndLog ("\n14443-3b tag found:"); 
 548                         PrintAndLog ("Unknown tag type answered to a 0x0A command ans:"); 
 549                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 559         if (HF14BCmdRaw(true, &crc
, true, data
, datalen
, false)!=0) { 
 561                         PrintAndLog ("\n14443-3b tag found:"); 
 562                         PrintAndLog ("Unknown tag type answered to a 0x0C command ans:"); 
 563                         PrintAndLog ("%s",sprint_hex(data
,*datalen
)); 
 572 // get and print all info known about any known 14b tag 
 573 int HF14BInfo(bool verbose
){ 
 574         uint8_t data
[USB_CMD_DATA_SIZE
]; 
 577         // try std 14b (atqb) 
 578         if (HF14BStdInfo(data
, &datalen
)) return 1; 
 581         if (HF14B_ST_Info(data
, &datalen
)) return 1; 
 583         // try unknown 14b read commands (to be identified later) 
 584         //   could be read of calypso, CEPAS, moneo, or pico pass. 
 585         if (HF14B_Other_Reader(data
, &datalen
)) return 1; 
 587         if (verbose
) PrintAndLog("no 14443B tag found"); 
 591 // menu command to get and print all info known about any known 14b tag 
 592 int CmdHF14Binfo(const char *Cmd
){ 
 593         return HF14BInfo(true); 
 596 // get and print general info about all known 14b chips 
 597 int HF14BReader(bool verbose
){ 
 598         uint8_t data
[USB_CMD_DATA_SIZE
]; 
 601         // try std 14b (atqb) 
 602         if (HF14BStdReader(data
, &datalen
)) return 1; 
 605         if (HF14B_ST_Reader(data
, &datalen
, true)) return 1; 
 607         // try unknown 14b read commands (to be identified later) 
 608         //   could be read of calypso, CEPAS, moneo, or pico pass. 
 609         if (HF14B_Other_Reader(data
, &datalen
)) return 1; 
 611         if (verbose
) PrintAndLog("no 14443B tag found"); 
 615 // menu command to get and print general info about all known 14b chips 
 616 int CmdHF14BReader(const char *Cmd
){ 
 617         return HF14BReader(true); 
 620 int CmdSriWrite( const char *Cmd
){ 
 622  * For SRIX4K  blocks 00 - 7F 
 623  * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata 
 625  * For SR512  blocks 00 - 0F 
 626  * hf 14b raw -c -p 09 $sr512wblock $sr512wdata 
 628  * Special block FF =  otp_lock_reg block. 
 631         char cmdp 
= param_getchar(Cmd
, 0); 
 632         uint8_t blockno 
= -1; 
 633         uint8_t data
[4] = {0x00}; 
 634         bool isSrix4k 
= true; 
 637         if (strlen(Cmd
) < 1 || cmdp 
== 'h' || cmdp 
== 'H') { 
 638                 PrintAndLog("Usage:  hf 14b write <1|2> <BLOCK> <DATA>"); 
 639                 PrintAndLog("    [1 = SRIX4K]"); 
 640                 PrintAndLog("    [2 = SRI512]"); 
 641                 PrintAndLog("    [BLOCK number depends on tag, special block == FF]"); 
 642                 PrintAndLog("     sample: hf 14b write 1 7F 11223344"); 
 643                 PrintAndLog("           : hf 14b write 1 FF 11223344"); 
 644                 PrintAndLog("           : hf 14b write 2 15 11223344"); 
 645                 PrintAndLog("           : hf 14b write 2 FF 11223344"); 
 652         //blockno = param_get8(Cmd, 1); 
 654         if ( param_gethex(Cmd
,1, &blockno
, 2) ) { 
 655                 PrintAndLog("Block number must include 2 HEX symbols"); 
 660                 if ( blockno 
> 0x7f && blockno 
!= 0xff ){ 
 661                         PrintAndLog("Block number out of range"); 
 665                 if ( blockno 
> 0x0f && blockno 
!= 0xff ){ 
 666                         PrintAndLog("Block number out of range"); 
 671         if (param_gethex(Cmd
, 2, data
, 8)) { 
 672                 PrintAndLog("Data must include 8 HEX symbols"); 
 676         if ( blockno 
== 0xff) 
 677                 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512" , blockno
,  sprint_hex(data
,4) ); 
 679                 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k
)?"SRIX4K":"SRI512", blockno
,  sprint_hex(data
,4) ); 
 681         sprintf(str
, "-c 09 %02x %02x%02x%02x%02x", blockno
, data
[0], data
[1], data
[2], data
[3]); 
 687 uint32_t srix4kEncode(uint32_t value
) { 
 692 4 bytes                 : 00 1A 20 01 
 694         // only the lower crumbs. 
 695         uint8_t block 
= (value 
& 0xFF); 
 697         uint8_t valuebytes
[] = {0,0,0}; 
 699         num_to_bytes(value
, 3, valuebytes
); 
 702         // Crumb swapping of value. 
 703         uint8_t temp
[] = {0,0}; 
 704         temp
[0] = (CRUMB(value
, 22) << 4 | CRUMB(value
, 14 ) << 2 | CRUMB(value
, 6)) << 4; 
 705         temp
[0] |= CRUMB(value
, 20) << 4 | CRUMB(value
, 12 ) << 2 | CRUMB(value
, 4); 
 706         temp
[1] = (CRUMB(value
, 18) << 4 | CRUMB(value
, 10 ) << 2 | CRUMB(value
, 2)) << 4; 
 707         temp
[1] |= CRUMB(value
, 16) << 4 | CRUMB(value
, 8  ) << 2 | CRUMB(value
, 0); 
 710         uint32_t chksum 
= 0xFF - block
; 
 712         // chksum is reduced by each nibbles of value. 
 713         for (i 
= 0; i 
< 3; ++i
){ 
 714                 chksum 
-= NIBBLE_HIGH(valuebytes
[i
]); 
 715                 chksum 
-= NIBBLE_LOW(valuebytes
[i
]); 
 718         // base4 conversion and left shift twice 
 720         uint8_t base4
[] = {0,0,0,0};     
 722         base4
[i
--] = (chksum 
% 4 << 2); 
 726         // merge scambled and chksum parts 
 728                 ( NIBBLE_LOW ( base4
[0]) << 28 ) | 
 729                 ( NIBBLE_HIGH( temp
[0])  << 24 ) | 
 731                 ( NIBBLE_LOW ( base4
[1]) << 20 ) | 
 732                 ( NIBBLE_LOW ( temp
[0])  << 16 ) | 
 734                 ( NIBBLE_LOW ( base4
[2]) << 12 ) | 
 735                 ( NIBBLE_HIGH( temp
[1])  << 8 ) | 
 737                 ( NIBBLE_LOW ( base4
[3]) << 4 ) | 
 738                   NIBBLE_LOW ( temp
[1] ); 
 740         PrintAndLog("ICE encoded | %08X -> %08X", value
, encvalue
); 
 743 uint32_t srix4kDecode(uint32_t value
) { 
 745                 case 0xC04F42C5: return 0x003139; 
 746                 case 0xC1484807: return 0x002943; 
 747                 case 0xC0C60848: return 0x001A20; 
 751 uint32_t srix4kDecodeCounter(uint32_t num
) { 
 752         uint32_t value 
= ~num
; 
 757 uint32_t srix4kGetMagicbytes( uint64_t uid
, uint32_t block6
, uint32_t block18
, uint32_t block19 
){ 
 758 #define MASK 0xFFFFFFFF; 
 759         uint32_t uid32 
= uid 
& MASK
; 
 760         uint32_t counter 
= srix4kDecodeCounter(block6
); 
 761         uint32_t decodedBlock18 
= srix4kDecode(block18
); 
 762         uint32_t decodedBlock19 
= srix4kDecode(block19
); 
 763         uint32_t doubleBlock 
= (decodedBlock18 
<< 16 | decodedBlock19
) + 1; 
 765         uint32_t result 
= (uid32 
* doubleBlock 
* counter
) & MASK
; 
 766         PrintAndLog("Magic bytes | %08X", result
); 
 769 int srix4kValid(const char *Cmd
){ 
 771         uint64_t uid 
= 0xD00202501A4532F9; 
 772         uint32_t block6 
= 0xFFFFFFFF; 
 773         uint32_t block18 
= 0xC04F42C5; 
 774         uint32_t block19 
= 0xC1484807; 
 775         uint32_t block21 
= 0xD1BCABA4; 
 777         uint32_t test_b18 
= 0x00313918; 
 778         uint32_t test_b18_enc 
= srix4kEncode(test_b18
); 
 779         //uint32_t test_b18_dec = srix4kDecode(test_b18_enc); 
 780         PrintAndLog("ENCODE & CHECKSUM |  %08X -> %08X (%s)", test_b18
, test_b18_enc 
, ""); 
 782         uint32_t magic 
= srix4kGetMagicbytes(uid
, block6
, block18
, block19
); 
 783         PrintAndLog("BLOCK 21 |  %08X -> %08X (no XOR)", block21
, magic 
^ block21
); 
 787 int CmdteaSelfTest(const char *Cmd
){ 
 789         uint8_t v
[8], v_le
[8]; 
 790         memset(v
, 0x00, sizeof(v
)); 
 791         memset(v_le
, 0x00, sizeof(v_le
)); 
 792         uint8_t* v_ptr 
= v_le
; 
 794         uint8_t cmdlen 
= strlen(Cmd
); 
 795         cmdlen 
= ( sizeof(v
)<<2 < cmdlen 
) ? sizeof(v
)<<2 : cmdlen
; 
 797         if ( param_gethex(Cmd
, 0, v
, cmdlen
) > 0 ){ 
 798                 PrintAndLog("can't read hex chars, uneven? :: %u", cmdlen
); 
 802         SwapEndian64ex(v 
, 8, 4, v_ptr
); 
 805         uint8_t key
[16] = {0x55,0xFE,0xF6,0x30,0x62,0xBF,0x0B,0xC1,0xC9,0xB3,0x7C,0x34,0x97,0x3E,0x29,0xFB }; 
 807         uint8_t* key_ptr 
= keyle
; 
 808         SwapEndian64ex(key 
, sizeof(key
), 4, key_ptr
); 
 810         PrintAndLog("TEST LE enc| %s", sprint_hex(v_ptr
, 8)); 
 812         tea_decrypt(v_ptr
, key_ptr
);     
 813         PrintAndLog("TEST LE dec | %s", sprint_hex_ascii(v_ptr
, 8)); 
 815         tea_encrypt(v_ptr
, key_ptr
);     
 816         tea_encrypt(v_ptr
, key_ptr
); 
 817         PrintAndLog("TEST enc2 | %s", sprint_hex_ascii(v_ptr
, 8)); 
 822 static command_t CommandTable
[] = { 
 823         {"help",        CmdHelp
,        1, "This help"}, 
 824         {"info",        CmdHF14Binfo
,   0, "Find and print details about a 14443B tag"}, 
 825         {"list",        CmdHF14BList
,   0, "[Deprecated] List ISO 14443B history"}, 
 826         {"reader",      CmdHF14BReader
, 0, "Act as a 14443B reader to identify a tag"}, 
 827         {"sim",         CmdHF14BSim
,    0, "Fake ISO 14443B tag"}, 
 828         {"snoop",       CmdHF14BSnoop
,  0, "Eavesdrop ISO 14443B"}, 
 829         {"sri512read",  CmdSri512Read
,  0, "Read contents of a SRI512 tag"}, 
 830         {"srix4kread",  CmdSrix4kRead
,  0, "Read contents of a SRIX4K tag"}, 
 831         {"sriwrite",    CmdSriWrite
,    0, "Write data to a SRI512 | SRIX4K tag"}, 
 832         {"raw",         CmdHF14BCmdRaw
, 0, "Send raw hex data to tag"}, 
 833         //{"valid",     srix4kValid,    1, "srix4k checksum test"}, 
 834         {"valid",       CmdteaSelfTest
, 1, "tea test"}, 
 835         {NULL
, NULL
, 0, NULL
} 
 838 int CmdHF14B(const char *Cmd
) { 
 839         clearCommandBuffer(); 
 840         CmdsParse(CommandTable
, Cmd
); 
 844 int CmdHelp(const char *Cmd
) { 
 845         CmdsHelp(CommandTable
);