]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlffdx.c
   1 //----------------------------------------------------------------------------- 
   3 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   4 // at your option, any later version. See the LICENSE.txt file for the text of 
   6 //----------------------------------------------------------------------------- 
   7 // Low frequency Presco tag commands 
   8 //----------------------------------------------------------------------------- 
  13         FDX-B ISO11784/85 demod  (aka animal tag)  BIPHASE, inverted, rf/32,  with preamble of 00000000001 (128bits) 
  14         8 databits + 1 parity (1) 
  16         NATIONAL CODE, ICAR database 
  17         COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf 
  18         FLAG (animal/non-animal) 
  25         16 ccitt CRC chksum over 64bit ID CODE. 
  28         sample: 985121004515220  [ 37FF65B88EF94 ] 
  31 static int CmdHelp(const char *Cmd
); 
  33 int usage_lf_fdx_clone(void){ 
  34         PrintAndLog("clone a FDX-B Animal tag to a T55x7 tag."); 
  35         PrintAndLog("Usage: lf fdx clone [h] <country id> <animal id> <Q5>"); 
  36         PrintAndLog("Options:"); 
  37         PrintAndLog("      h            : This help"); 
  38         PrintAndLog("      <country id> : Country id"); 
  39         PrintAndLog("      <animal id>  : Animal id"); 
  44         PrintAndLog("      <Q5>        : specify write to Q5 (t5555 instead of t55x7)"); 
  46         PrintAndLog("Sample: lf fdx clone 999 112233"); 
  50 int usage_lf_fdx_sim(void) { 
  51         PrintAndLog("Enables simulation of FDX-B Animal tag"); 
  52         PrintAndLog("Simulation runs until the button is pressed or another USB command is issued."); 
  54         PrintAndLog("Usage:  lf fdx sim [h] <country id> <animal id>"); 
  55         PrintAndLog("Options:"); 
  56         PrintAndLog("      h            : This help"); 
  57         PrintAndLog("      <country id> : Country id"); 
  58         PrintAndLog("      <animal id>  : Animal id"); 
  60         PrintAndLog("Sample: lf fdx sim 999 112233"); 
  63 // clearing the topbit needed for the preambl detection.  
  64 static void verify_values(uint32_t countryid
, uint64_t animalid
){ 
  65         if ((animalid 
& 0x3FFFFFFFFF) != animalid
) { 
  66                 animalid 
&= 0x3FFFFFFFFF; 
  67                 PrintAndLog("Animal ID Truncated to 38bits: %"PRIx64
, animalid
); 
  69         if ( (countryid 
& 0x3ff) != countryid 
) { 
  71                 PrintAndLog("Country ID Truncated to 10bits: %03d", countryid
); 
  75 int getFDXBits(uint64_t national_id
, uint16_t country
, uint8_t isanimal
, uint8_t isextended
, uint32_t extended
, uint8_t *bits
) { 
  77     // add preamble ten 0x00 and one 0x01 
  78     memset(bits
, 0x00, 10); 
  82     // every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite 
  83         memset(bits
, 0x01, 128); 
  85     // add preamble ten 0x00 and one 0x01 
  86     memset(bits
, 0x00, 10); 
  89         num_to_bytebitsLSBF(0x00, 7, bits 
+ 66); 
  90         num_to_bytebitsLSBF(0x00 >> 7, 7, bits 
+ 74); 
  92         // add animal flag - OK 
  95         // add extended flag - OK 
  96         bits
[81] = isextended
; 
  98         // add national code 40bits - OK 
  99         num_to_bytebitsLSBF(national_id 
>> 0, 8, bits
+11); 
 100         num_to_bytebitsLSBF(national_id 
>> 8, 8, bits
+20); 
 101         num_to_bytebitsLSBF(national_id 
>> 16, 8, bits
+29); 
 102         num_to_bytebitsLSBF(national_id 
>> 24, 8, bits
+38); 
 103         num_to_bytebitsLSBF(national_id 
>> 32, 6, bits
+47); 
 105         // add country code - OK 
 106         num_to_bytebitsLSBF(country 
>> 0, 2, bits
+53); 
 107         num_to_bytebitsLSBF(country 
>> 2, 8, bits
+56); 
 111         for (uint8_t i
=0; i
<8; ++i
) 
 112                 raw
[i
] = bytebits_to_byte(bits 
+ 11 + i 
* 9, 8); 
 114         uint16_t crc 
= crc16_ccitt_kermit(raw
, 8); 
 115         num_to_bytebitsLSBF(crc 
>> 0, 8, bits
+83); 
 116         num_to_bytebitsLSBF(crc 
>> 8, 8, bits
+92); 
 118         // extended data - OK 
 119         num_to_bytebitsLSBF( extended 
>> 0 , 8, bits
+101); 
 120         num_to_bytebitsLSBF( extended 
>> 8 , 8, bits
+110); 
 121         num_to_bytebitsLSBF( extended 
>> 16, 8, bits
+119); 
 125 //see ASKDemod for what args are accepted 
 126 //almost the same demod as cmddata.c/CmdFDXBdemodBI  
 127 int CmdFdxDemod(const char *Cmd
) { 
 129         //Differential Biphase / di-phase (inverted biphase) 
 130         //get binary from ask wave 
 131         if (!ASKbiphaseDemod("0 32 1 0", FALSE
)) { 
 132                 if (g_debugMode
) PrintAndLog("DEBUG: Error - FDX-B ASKbiphaseDemod failed"); 
 135         size_t size 
= DemodBufferLen
; 
 136         int ans 
= FDXBdemodBI(DemodBuffer
, &size
); 
 140                                 PrintAndLog("DEBUG: Error - FDX-B too few bits found"); 
 142                                 PrintAndLog("DEBUG: Error - FDX-B preamble not found"); 
 144                                 PrintAndLog("DEBUG: Error - FDX-B Size not correct: %d", size
); 
 146                                 PrintAndLog("DEBUG: Error - FDX-B ans: %d", ans
); 
 151         setDemodBuf(DemodBuffer
, 128, ans
); 
 152         // remove marker bits (1's every 9th digit after preamble) (pType = 2) 
 153         size 
= removeParity(DemodBuffer
, 11, 9, 2, 117); 
 155                 if (g_debugMode
) PrintAndLog("DEBUG: Error - FDX-B error removeParity: %d", size
); 
 160         uint64_t NationalCode 
= ((uint64_t)(bytebits_to_byteLSBF(DemodBuffer
+32,6)) << 32) | bytebits_to_byteLSBF(DemodBuffer
,32); 
 161         uint16_t countryCode 
= bytebits_to_byteLSBF(DemodBuffer
+38,10); 
 162         uint8_t dataBlockBit 
= DemodBuffer
[48]; 
 163         uint32_t reservedCode 
= bytebits_to_byteLSBF(DemodBuffer
+49,14); 
 164         uint8_t animalBit 
= DemodBuffer
[63]; 
 165         uint32_t crc16 
= bytebits_to_byteLSBF(DemodBuffer
+64,16); 
 166         uint32_t extended 
= bytebits_to_byteLSBF(DemodBuffer
+80,24); 
 167         uint64_t rawid 
= ((uint64_t) 
 168                                                                 //bytebits_to_byte(DemodBuffer, 8) << 96) |  
 169                                                                 //bytebits_to_byte(DemodBuffer,32) << 64) | 
 170                                                                 bytebits_to_byte(DemodBuffer
,32) << 32) | 
 171                                                                 bytebits_to_byte(DemodBuffer
+32, 32); 
 173         num_to_bytes(rawid
, 8, raw
); 
 175         uint16_t calcCrc 
= crc16_ccitt_kermit(raw
, 8); 
 177         PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:  Raw : %s", sprint_hex(raw
, 8)); 
 178         PrintAndLog("Animal ID          %04u-%012llu", countryCode
, NationalCode
); 
 179         PrintAndLog("National Code      %012llu (0x%llX)", NationalCode
, NationalCode
); 
 180         PrintAndLog("Country Code       %04u", countryCode
); 
 181         PrintAndLog("Reserved/RFU       %u (0x04%X)", reservedCode
,  reservedCode
); 
 183         PrintAndLog("Animal Tag         %s", animalBit 
? "True" : "False");      
 184         PrintAndLog("Has extended data  %s [0x%X]", dataBlockBit 
? "True" : "False", extended
);  
 185         PrintAndLog("CRC-16             0x%04X - 0x%04X [%s]", crc16
, calcCrc
, (calcCrc 
== crc16
) ? "Ok" : "Failed"); 
 188                 PrintAndLog("Start marker %d;   Size %d", ans
, size
);    
 189                 char *bin 
= sprint_bin_break(DemodBuffer
, size
, 16); 
 190                 PrintAndLog("DEBUG bin stream:\n%s", bin
); 
 195 int CmdFdxRead(const char *Cmd
) { 
 197         getSamples("12000", TRUE
); 
 198         return CmdFdxDemod(Cmd
); 
 201 int CmdFdxClone(const char *Cmd
) { 
 203         uint32_t countryid 
= 0; 
 204         uint64_t animalid 
= 0; 
 205         uint32_t blocks
[5] = {T55x7_MODULATION_DIPHASE 
| T55x7_BITRATE_RF_32 
| 4<<T55x7_MAXBLOCK_SHIFT
, 0, 0, 0, 0}; 
 208         memset(bs
, 0, sizeof(bits
)); 
 210         char cmdp 
= param_getchar(Cmd
, 0); 
 211         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_fdx_clone(); 
 213         countryid 
= param_get32ex(Cmd
, 0, 0, 10); 
 214         animalid 
= param_get64ex(Cmd
, 1, 0, 10); 
 217         if (param_getchar(Cmd
, 1) == 'Q' || param_getchar(Cmd
, 1) == 'q') { 
 218                 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman) 
 219                 blocks
[0] = T5555_MODULATION_BIPHASE 
| T5555_INVERT_OUTPUT 
| 32<<T5555_BITRATE_SHIFT 
| 4<<T5555_MAXBLOCK_SHIFT
; 
 222         verify_values(countryid
, animalid
); 
 224         // getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits)  
 225         if ( !getFDXBits(animalid
, countryid
, 1, 0, 0, bs
)) { 
 226                 PrintAndLog("Error with tag bitstream generation."); 
 230         // convert from bit stream to block data 
 231         blocks
[1] = bytebits_to_byte(bs
,32); 
 232         blocks
[2] = bytebits_to_byte(bs
+32,32); 
 233         blocks
[3] = bytebits_to_byte(bs
+64,32); 
 234         blocks
[4] = bytebits_to_byte(bs
+96,32); 
 236         PrintAndLog("Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64
, countryid
, animalid
); 
 237         PrintAndLog("Blk | Data "); 
 238         PrintAndLog("----+------------"); 
 239         PrintAndLog(" 00 | 0x%08x", blocks
[0]); 
 240         PrintAndLog(" 01 | 0x%08x", blocks
[1]); 
 241         PrintAndLog(" 02 | 0x%08x", blocks
[2]); 
 242         PrintAndLog(" 03 | 0x%08x", blocks
[3]); 
 243         PrintAndLog(" 04 | 0x%08x", blocks
[4]); 
 246         UsbCommand c 
= {CMD_T55XX_WRITE_BLOCK
, {0,0,0}}; 
 248         for (int i 
= 4; i 
>= 0; --i
) { 
 249                 c
.arg
[0] = blocks
[i
]; 
 251                 clearCommandBuffer(); 
 253                 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1000)){ 
 254                         PrintAndLog("Error occurred, device did not respond during write operation."); 
 261 int CmdFdxSim(const char *Cmd
) { 
 262         uint32_t countryid 
= 0; 
 263         uint64_t animalid 
= 0; 
 265         char cmdp 
= param_getchar(Cmd
, 0); 
 266         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_fdx_sim(); 
 268         countryid 
= param_get32ex(Cmd
, 0, 0, 10); 
 269         animalid 
= param_get64ex(Cmd
, 1, 0, 10); 
 271         verify_values(countryid
, animalid
); 
 273         uint8_t clk 
= 32, encoding 
= 2, separator 
= 0, invert 
= 1; 
 276         arg1 
= clk 
<< 8 | encoding
; 
 277         arg2 
= invert 
<< 8 | separator
; 
 279         PrintAndLog("Simulating FDX-B animal ID: %04u-%"PRIu64
, countryid
, animalid
); 
 281         UsbCommand c 
= {CMD_ASK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 283          //getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits)  
 284         getFDXBits(animalid
, countryid
, 1, 0, 0, c
.d
.asBytes
); 
 285         clearCommandBuffer(); 
 290 static command_t CommandTable
[] = { 
 291     {"help",    CmdHelp
,        1, "This help"}, 
 292         {"demod",       CmdFdxDemod
,1, "Attempt extract tag data from graphbuf"}, 
 293         {"read",        CmdFdxRead
,     0, "Attempt to read and extract tag data"}, 
 294         {"clone",       CmdFdxClone
,0, "Clone animal ID tag to T55x7"}, 
 295         {"sim",         CmdFdxSim
,      0, "Animal ID tag simulator"}, 
 296     {NULL
, NULL
, 0, NULL
} 
 299 int CmdLFFdx(const char *Cmd
) { 
 300         clearCommandBuffer(); 
 301     CmdsParse(CommandTable
, Cmd
); 
 305 int CmdHelp(const char *Cmd
) { 
 306     CmdsHelp(CommandTable
);