]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfnedap.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 NEDAP tag commands 
   8 //----------------------------------------------------------------------------- 
  11 #include "cmdlfnedap.h" 
  12 static int CmdHelp(const char *Cmd
); 
  14 int usage_lf_nedap_clone(void){ 
  15         PrintAndLog("clone a NEDAP tag to a T55x7 tag."); 
  17         PrintAndLog("Usage: lf nedap clone [h] <Card-Number>"); 
  18         PrintAndLog("Options:"); 
  19         PrintAndLog("      h             : This help"); 
  20         PrintAndLog("      <Card Number> : 24-bit value card number"); 
  21 //      PrintAndLog("      Q5            : optional - clone to Q5 (T5555) instead of T55x7 chip"); 
  23         PrintAndLog("Sample: lf nedap clone 112233"); 
  27 int usage_lf_nedap_sim(void) { 
  28         PrintAndLog("Enables simulation of NEDAP card with specified card number."); 
  29         PrintAndLog("Simulation runs until the button is pressed or another USB command is issued."); 
  31         PrintAndLog("Usage:  lf nedap sim [h] <Card-Number>"); 
  32         PrintAndLog("Options:"); 
  33         PrintAndLog("      h               : This help"); 
  34         PrintAndLog("      <Card Number>   : 24-bit value card number"); 
  36         PrintAndLog("Sample: lf nedap sim 112233"); 
  40 int GetNedapBits(uint32_t cn
, uint8_t *nedapBits
) { 
  43         memset(pre
, 0x00, sizeof(pre
)); 
  45         // preamble  1111 1111 10 = 0XF8 
  46         num_to_bytebits(0xF8, 10, pre
); 
  48         // fixed tagtype code?  0010 1101 = 0x2D 
  49         num_to_bytebits(0x2D, 8, pre
+10); 
  51         // 46 encrypted bits - UNKNOWN ALGO 
  52         //    -- 16 bits checksum. Should be 4x4 checksum,  based on UID and 2 constant values. 
  53         //    -- 30 bits undocumented?   
  54         num_to_bytebits(cn
, 46, pre
+18); 
  56         //----from this part, the UID in clear text, with a 1bit ZERO as separator between bytes. 
  60         num_to_bytebits(cn
, 24, pre
+64); 
  69         // add paritybits       (bitsource, dest, sourcelen, paritylen, parityType (odd, even,) 
  70         addParity(pre
+64, pre
+64, 128, 8, 1); 
  72 //1111111110001011010000010110100011001001000010110101001101011001000110011010010000000000100001110001001000000001000101011100111 
  80 //GetParity( uint8_t *bits, uint8_t type, int length) 
  82 //NEDAP demod - ASK/Biphase (or Diphase),  RF/64 with preamble of 1111111110  (always a 128 bit data stream) 
  83 //print NEDAP Prox ID, encoding, encrypted ID,  
  85 int CmdLFNedapDemod(const char *Cmd
) { 
  86         //raw ask demod no start bit finding just get binary from wave 
  87         if (!ASKbiphaseDemod("0 64 0 0", FALSE
)) { 
  88                 if (g_debugMode
) PrintAndLog("Error NEDAP: ASKbiphaseDemod failed"); 
  91         size_t size 
= DemodBufferLen
; 
  92         int idx 
= NedapDemod(DemodBuffer
, &size
); 
  96                                 // PrintAndLog("DEBUG: Error - not enough samples"); 
  97                         // else if (idx == -1) 
  98                                 // PrintAndLog("DEBUG: Error - only noise found"); 
  99                         // else if (idx == -2) 
 100                                 // PrintAndLog("DEBUG: Error - problem during ASK/Biphase demod"); 
 102                                 PrintAndLog("DEBUG: Error - Size not correct: %d", size
); 
 104                                 PrintAndLog("DEBUG: Error - NEDAP preamble not found"); 
 106                                 PrintAndLog("DEBUG: Error - idx: %d",idx
); 
 112  preamble    enc tag type         encrypted uid                   P d    33    d    90    d    04    d    71    d    40    d    45    d    E7    P 
 113  1111111110 00101101000001011010001100100100001011010100110101100 1 0 00110011 0 10010000 0 00000100 0 01110001 0 01000000 0 01000101 0 11100111 1 
 114                                                                          uid2       uid1       uid0         I          I          R           R     
 115  1111111110 00101101000001011010001100100100001011010100110101100 1  
 127          I = Identical on all tags 
 129          UID2, UID1, UID0 == card number 
 132         //get raw ID before removing parities 
 133         uint32_t raw
[4] = {0,0,0,0}; 
 134         raw
[0] = bytebits_to_byte(DemodBuffer
+idx
+96,32); 
 135         raw
[1] = bytebits_to_byte(DemodBuffer
+idx
+64,32); 
 136         raw
[2] = bytebits_to_byte(DemodBuffer
+idx
+32,32); 
 137         raw
[3] = bytebits_to_byte(DemodBuffer
+idx
,32); 
 138         setDemodBuf(DemodBuffer
,128,idx
); 
 140         uint8_t firstParity 
= GetParity( DemodBuffer
, EVEN
, 63); 
 141         if ( firstParity 
!= DemodBuffer
[63]  ) { 
 142                 PrintAndLog("1st 64bit parity check failed:  %d|%d ", DemodBuffer
[63], firstParity
); 
 146         uint8_t secondParity 
= GetParity( DemodBuffer
+64, EVEN
, 63); 
 147         if ( secondParity 
!= DemodBuffer
[127]  ) { 
 148                 PrintAndLog("2st 64bit parity check failed:  %d|%d ", DemodBuffer
[127], secondParity
); 
 152         // ok valid card found! 
 154         uid 
=  bytebits_to_byte(DemodBuffer
+65, 8); 
 155         uid 
|= bytebits_to_byte(DemodBuffer
+74, 8) << 8; 
 156         uid 
|= bytebits_to_byte(DemodBuffer
+83, 8) << 16; 
 159         two 
=  bytebits_to_byte(DemodBuffer
+92, 8);  
 160         two 
|= bytebits_to_byte(DemodBuffer
+101, 8) << 8; 
 162         uint16_t chksum2 
= 0; 
 163         chksum2 
=  bytebits_to_byte(DemodBuffer
+110, 8); 
 164         chksum2 
|= bytebits_to_byte(DemodBuffer
+119, 8) << 8; 
 166         PrintAndLog("NEDAP ID Found - Raw: %08x%08x%08x%08x", raw
[3], raw
[2], raw
[1], raw
[0]); 
 167         PrintAndLog(" - UID: %06X", uid
); 
 168         PrintAndLog(" - i: %04X", two
); 
 169         PrintAndLog(" - Checksum2 %04X", chksum2
); 
 172                 PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx
, 128); 
 174                 PrintAndLog("BIN:\n%s", sprint_bin_break( DemodBuffer
, 128, 64) ); 
 181 lf t55xx wr b 0 d 00170082 
 184 lf t55 wr b 1 d FF8B4168 
 185 lf t55 wr b 2 d C90B5359 
 186 lf t55 wr b 3 d 19A40087 
 187 lf t55 wr b 4 d 120115CF 
 190 lf t55 wr b 1 d FF8B6B20 
 191 lf t55 wr b 2 d F19B84A3 
 192 lf t55 wr b 3 d 18058007 
 193 lf t55 wr b 4 d 1200857C 
 196 lf t55xx wr b 1 d ffbfa73e 
 197 lf t55xx wr b 2 d 4c0003ff 
 198 lf t55xx wr b 3 d ffbfa73e 
 199 lf t55xx wr b 4 d 4c0003ff 
 203 int CmdLFNedapRead(const char *Cmd
) { 
 205         getSamples("30000",false); 
 206         return CmdLFNedapDemod(""); 
 209 int CmdLFNedapClone(const char *Cmd) { 
 211         char cmdp = param_getchar(Cmd, 0); 
 212         if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_nedap_clone(); 
 214         uint32_t cardnumber=0, cn = 0; 
 218         memset(bs, 0x00, sizeof(bs)); 
 220         if (sscanf(Cmd, "%u", &cn ) != 1) return usage_lf_nedap_clone(); 
 222         cardnumber = (cn & 0x00FFFFFF); 
 224         if ( !GetNedapBits(cardnumber, bs)) { 
 225                 PrintAndLog("Error with tag bitstream generation."); 
 229         ((ASK/biphase   data rawdemod ab 0 64 1 0 
 230         //NEDAP - compat mode, ASK/Biphase, data rate 64, 4 data blocks 
 231         blocks[0] = T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 4<<T55x7_MAXBLOCK_SHIFT; 
 233         if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') 
 234                 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman) 
 235                 blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | 64<<T5555_BITRATE_SHIFT | 4<<T5555_MAXBLOCK_SHIFT; 
 237         blocks[1] = bytebits_to_byte(bs,32); 
 238         blocks[2] = bytebits_to_byte(bs+32,32); 
 239         blocks[3] = bytebits_to_byte(bs+64,32); 
 240         blocks[4] = bytebits_to_byte(bs+96,32); 
 242         PrintAndLog("Preparing to clone NEDAP to T55x7 with card number: %u", cardnumber); 
 243         PrintAndLog("Blk | Data "); 
 244         PrintAndLog("----+------------"); 
 245         for ( i = 0; i<5; ++i ) 
 246                 PrintAndLog(" %02d | %08" PRIx32, i, blocks[i]); 
 249         UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}}; 
 251         for ( i = 0; i<5; ++i ) { 
 252                 c.arg[0] = blocks[i]; 
 254                 clearCommandBuffer(); 
 256                 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ 
 257                         PrintAndLog("Error occurred, device did not respond during write operation."); 
 265 int CmdLFNedapSim(const char *Cmd
) { 
 267         char cmdp 
= param_getchar(Cmd
, 0); 
 268         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_nedap_sim(); 
 270         uint32_t cardnumber 
= 0, cn 
= 0; 
 273         size_t size 
= sizeof(bs
); 
 274         memset(bs
, 0x00, size
); 
 276         // NEDAP,  Bihase = 2, clock 64, inverted,  
 277         uint8_t encoding 
= 2, separator 
= 0, clk
=64, invert
=1; 
 279         arg1 
= clk 
<< 8 | encoding
; 
 280         arg2 
= invert 
<< 8 | separator
; 
 282         if (sscanf(Cmd
, "%u", &cn 
) != 1) return usage_lf_nedap_sim(); 
 283         cardnumber 
= (cn 
& 0x00FFFFFF); 
 285         if ( !GetNedapBits(cardnumber
, bs
)) { 
 286                 PrintAndLog("Error with tag bitstream generation."); 
 290         PrintAndLog("Simulating Nedap - CardNumber: %u", cardnumber 
); 
 292         UsbCommand c 
= {CMD_ASK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 293         memcpy(c
.d
.asBytes
, bs
, size
); 
 294         clearCommandBuffer(); 
 299 int CmdLFNedapChk(const char *Cmd
){ 
 301         uint8_t data
[256] = { 0x30, 0x16, 0x00, 0x71, 0x40, 0x21, 0xBE}; 
 303         param_gethex_ex(Cmd
, 0, data
, &len
); 
 305         len 
= ( len 
== 0 ) ? 5 : len
>>1; 
 307         PrintAndLog("Input: [%d] %s", len
, sprint_hex(data
, len
)); 
 309         //uint8_t last = GetParity(data, EVEN, 62); 
 310         //PrintAndLog("TEST PARITY::  %d | %d ", DemodBuffer[62], last); 
 312     uint8_t cl 
= 0x1D, ch 
= 0x1D, carry 
= 0; 
 313     uint8_t al
, bl
, temp
; 
 315         for (int i 
= 0; i 
< len
; ++i
){ 
 317         for (int j 
= 8; j 
> 0; --j
) { 
 320                         //printf("BL %02x | CH %02x \n", al, ch); 
 322             carry 
= (cl 
& 0x80) ? 1 : 0; 
 325             temp 
= (ch 
& 0x80) ? 1 : 0; 
 326             ch 
= (ch 
<< 1) | carry
; 
 329             carry 
= (al 
& 0x80) ? 1 : 0; 
 332             carry 
= (bl 
& 0x80) ? 1 : 0; 
 342         PrintAndLog("Nedap checksum: [ 0x21, 0xBE ] %x", ((ch 
<< 8) | cl
) ); 
 347 static command_t CommandTable
[] = { 
 348     {"help",    CmdHelp
,                1, "This help"}, 
 349         {"read",        CmdLFNedapRead
, 0, "Attempt to read and extract tag data"}, 
 350 //      {"clone",       CmdLFNedapClone,0, "<Card Number>  clone nedap tag"}, 
 351         {"sim",         CmdLFNedapSim
,  0, "<Card Number>  simulate nedap tag"}, 
 352         {"chk",         CmdLFNedapChk
,  1, "Calculate Nedap Checksum <uid bytes>"}, 
 353     {NULL
, NULL
, 0, NULL
} 
 356 int CmdLFNedap(const char *Cmd
) { 
 357         clearCommandBuffer(); 
 358     CmdsParse(CommandTable
, Cmd
); 
 362 int CmdHelp(const char *Cmd
) { 
 363     CmdsHelp(CommandTable
);