]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfem4x.c
   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 // Low frequency EM4x commands 
   9 //----------------------------------------------------------------------------- 
  14 //#include "proxusb.h" 
  15 #include "proxmark3.h" 
  18 #include "cmdparser.h" 
  21 #include "cmdlfem4x.h" 
  23 static int CmdHelp(const char *Cmd
); 
  25 /* Read the ID of an EM410x tag. 
  27  *   1111 1111 1           <-- standard non-repeatable header 
  28  *   XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID 
  30  *   CCCC                  <-- each bit here is parity for the 10 bits above in corresponding column 
  31  *   0                     <-- stop bit, end of tag 
  33 int CmdEM410xRead(const char *Cmd
) 
  35   int i
, j
, clock
, header
, rows
, bit
, hithigh
, hitlow
, first
, bit2idx
, high
, low
; 
  40   uint8_t BitStream
[MAX_GRAPH_TRACE_LEN
]; 
  43   /* Detect high and lows and clock */ 
  44   for (i 
= 0; i 
< GraphTraceLen
; i
++) 
  46     if (GraphBuffer
[i
] > high
) 
  47       high 
= GraphBuffer
[i
]; 
  48     else if (GraphBuffer
[i
] < low
) 
  53   clock 
= GetClock(Cmd
, high
, 0); 
  55   /* parity for our 4 columns */ 
  56   parity
[0] = parity
[1] = parity
[2] = parity
[3] = 0; 
  59   /* manchester demodulate */ 
  61   for (i 
= 0; i 
< (int)(GraphTraceLen 
/ clock
); i
++) 
  67     /* Find out if we hit both high and low peaks */ 
  68     for (j 
= 0; j 
< clock
; j
++) 
  70       if (GraphBuffer
[(i 
* clock
) + j
] == high
) 
  72       else if (GraphBuffer
[(i 
* clock
) + j
] == low
) 
  75       /* it doesn't count if it's the first part of our read 
  76        because it's really just trailing from the last sequence */ 
  77       if (first 
&& (hithigh 
|| hitlow
)) 
  82       if (hithigh 
&& hitlow
) 
  86     /* If we didn't hit both high and low peaks, we had a bit transition */ 
  87     if (!hithigh 
|| !hitlow
) 
  90     BitStream
[bit2idx
++] = bit
; 
  94   /* We go till 5 before the graph ends because we'll get that far below */ 
  95   for (i 
= 1; i 
< bit2idx 
- 5; i
++) 
  97     /* Step 2: We have our header but need our tag ID */ 
  98     if (header 
== 9 && rows 
< 10) 
 100       /* Confirm parity is correct */ 
 101       if ((BitStream
[i
] ^ BitStream
[i
+1] ^ BitStream
[i
+2] ^ BitStream
[i
+3]) == BitStream
[i
+4]) 
 103         /* Read another byte! */ 
 104         sprintf(id
+rows
, "%x", (8 * BitStream
[i
]) + (4 * BitStream
[i
+1]) + (2 * BitStream
[i
+2]) + (1 * BitStream
[i
+3])); 
 105         sprintf(id2
+rows
, "%x", (8 * BitStream
[i
+3]) + (4 * BitStream
[i
+2]) + (2 * BitStream
[i
+1]) + (1 * BitStream
[i
])); 
 108         /* Keep parity info */ 
 109         parity
[0] ^= BitStream
[i
]; 
 110         parity
[1] ^= BitStream
[i
+1]; 
 111         parity
[2] ^= BitStream
[i
+2]; 
 112         parity
[3] ^= BitStream
[i
+3]; 
 114         /* Move 4 bits ahead */ 
 118       /* Damn, something wrong! reset */ 
 121         PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows 
+ 1, i
); 
 123         /* Start back rows * 5 + 9 header bits, -1 to not start at same place */ 
 124         i 
-= 9 + (5 * rows
) - 5; 
 130     /* Step 3: Got our 40 bits! confirm column parity */ 
 133       /* We need to make sure our 4 bits of parity are correct and we have a stop bit */ 
 134       if (BitStream
[i
] == parity
[0] && BitStream
[i
+1] == parity
[1] && 
 135         BitStream
[i
+2] == parity
[2] && BitStream
[i
+3] == parity
[3] && 
 139         PrintAndLog("EM410x Tag ID: %s", id
); 
 140         PrintAndLog("Unique Tag ID: %s", id2
); 
 146       /* Crap! Incorrect parity or no stop bit, start all over */ 
 151         /* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */ 
 156     /* Step 1: get our header */ 
 159       /* Need 9 consecutive 1's */ 
 160       if (BitStream
[i
] == 1) 
 163       /* We don't have a header, not enough consecutive 1 bits */ 
 169   /* if we've already retested after flipping bits, return */ 
 173   /* if this didn't work, try flipping bits */ 
 174   for (i 
= 0; i 
< bit2idx
; i
++) 
 180 /* emulate an EM410X tag 
 182  *   1111 1111 1           <-- standard non-repeatable header 
 183  *   XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID 
 185  *   CCCC                  <-- each bit here is parity for the 10 bits above in corresponding column 
 186  *   0                     <-- stop bit, end of tag 
 188 int CmdEM410xSim(const char *Cmd
) 
 190   int i
, n
, j
, h
, binary
[4], parity
[4]; 
 192   /* clock is 64 in EM410x tags */ 
 195   /* clear our graph */ 
 198   /* write it out a few times */ 
 199   for (h 
= 0; h 
< 4; h
++) 
 201     /* write 9 start bits */ 
 202     for (i 
= 0; i 
< 9; i
++) 
 203       AppendGraph(0, clock
, 1); 
 205     /* for each hex char */ 
 206     parity
[0] = parity
[1] = parity
[2] = parity
[3] = 0; 
 207     for (i 
= 0; i 
< 10; i
++) 
 209       /* read each hex char */ 
 210       sscanf(&Cmd
[i
], "%1x", &n
); 
 211       for (j 
= 3; j 
>= 0; j
--, n
/= 2) 
 214       /* append each bit */ 
 215       AppendGraph(0, clock
, binary
[0]); 
 216       AppendGraph(0, clock
, binary
[1]); 
 217       AppendGraph(0, clock
, binary
[2]); 
 218       AppendGraph(0, clock
, binary
[3]); 
 220       /* append parity bit */ 
 221       AppendGraph(0, clock
, binary
[0] ^ binary
[1] ^ binary
[2] ^ binary
[3]); 
 223       /* keep track of column parity */ 
 224       parity
[0] ^= binary
[0]; 
 225       parity
[1] ^= binary
[1]; 
 226       parity
[2] ^= binary
[2]; 
 227       parity
[3] ^= binary
[3]; 
 231     AppendGraph(0, clock
, parity
[0]); 
 232     AppendGraph(0, clock
, parity
[1]); 
 233     AppendGraph(0, clock
, parity
[2]); 
 234     AppendGraph(0, clock
, parity
[3]); 
 237     AppendGraph(0, clock
, 0); 
 240   /* modulate that biatch */ 
 241   CmdManchesterMod(""); 
 244   RepaintGraphWindow(); 
 250 /* Function is equivalent of loread + losamples + em410xread 
 251  * looped until an EM410x tag is detected */ 
 252 int CmdEM410xWatch(const char *Cmd
) 
 254   int read_h 
= (*Cmd 
== 'h'); 
 257     CmdLFRead(read_h 
? "h" : ""); 
 258     // 2000 samples is OK for clock=64, but not clock=32.  Probably want 
 259                 //   8000 for clock=16.  Don't want to go too high since old HID driver 
 261                 // TBD: Auto-grow sample size based on detected sample rate.  IE: If the 
 262                 //   rate gets lower, then grow the number of samples 
 264     // Changed by martin, 4000 x 4 = 16000,  
 265     // see http://www.proxmark.org/forum/viewtopic.php?pid=7235#p7235 
 267  } while ( ! CmdEM410xRead("")); 
 271 /* Read the transmitted data of an EM4x50 tag 
 274  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 275  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 276  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 277  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 278  *  CCCCCCCC                         <- column parity bits 
 280  *  LW                               <- Listen Window 
 282  * This pattern repeats for every block of data being transmitted. 
 283  * Transmission starts with two Listen Windows (LW - a modulated 
 284  * pattern of 320 cycles each (32/32/128/64/64)). 
 286  * Note that this data may or may not be the UID. It is whatever data 
 287  * is stored in the blocks defined in the control word First and Last 
 288  * Word Read values. UID is stored in block 32. 
 290 int CmdEM4x50Read(const char *Cmd
) 
 292   int i
, j
, startblock
, skip
, block
, start
, end
, low
, high
; 
 293   bool complete
= false; 
 294   int tmpbuff
[MAX_GRAPH_TRACE_LEN 
/ 64]; 
 298   memset(tmpbuff
, 0, MAX_GRAPH_TRACE_LEN 
/ 64); 
 300   /* first get high and low values */ 
 301   for (i 
= 0; i 
< GraphTraceLen
; i
++) 
 303     if (GraphBuffer
[i
] > high
) 
 304       high 
= GraphBuffer
[i
]; 
 305     else if (GraphBuffer
[i
] < low
) 
 306       low 
= GraphBuffer
[i
]; 
 309   /* populate a buffer with pulse lengths */ 
 312   while (i 
< GraphTraceLen
) 
 314     // measure from low to low 
 315     while ((GraphBuffer
[i
] > low
) && (i
<GraphTraceLen
)) 
 318     while ((GraphBuffer
[i
] < high
) && (i
<GraphTraceLen
)) 
 320     while ((GraphBuffer
[i
] > low
) && (i
<GraphTraceLen
)) 
 322     if (j
>(MAX_GRAPH_TRACE_LEN
/64)) { 
 325     tmpbuff
[j
++]= i 
- start
; 
 328   /* look for data start - should be 2 pairs of LW (pulses of 192,128) */ 
 331   for (i
= 0; i 
< j 
- 4 ; ++i
) 
 334     if (tmpbuff
[i
] >= 190 && tmpbuff
[i
] <= 194) 
 335       if (tmpbuff
[i
+1] >= 126 && tmpbuff
[i
+1] <= 130) 
 336         if (tmpbuff
[i
+2] >= 190 && tmpbuff
[i
+2] <= 194) 
 337           if (tmpbuff
[i
+3] >= 126 && tmpbuff
[i
+3] <= 130) 
 345   /* skip over the remainder of the LW */ 
 346   skip 
+= tmpbuff
[i
+1]+tmpbuff
[i
+2]; 
 347   while (skip 
< MAX_GRAPH_TRACE_LEN 
&& GraphBuffer
[skip
] > low
) 
 351   /* now do it again to find the end */ 
 353   for (i 
+= 3; i 
< j 
- 4 ; ++i
) 
 356     if (tmpbuff
[i
] >= 190 && tmpbuff
[i
] <= 194) 
 357       if (tmpbuff
[i
+1] >= 126 && tmpbuff
[i
+1] <= 130) 
 358         if (tmpbuff
[i
+2] >= 190 && tmpbuff
[i
+2] <= 194) 
 359           if (tmpbuff
[i
+3] >= 126 && tmpbuff
[i
+3] <= 130) 
 367     PrintAndLog("Found data at sample: %i",skip
); 
 370     PrintAndLog("No data found!"); 
 371     PrintAndLog("Try again with more samples."); 
 377     PrintAndLog("*** Warning!"); 
 378     PrintAndLog("Partial data - no end found!"); 
 379     PrintAndLog("Try again with more samples."); 
 382   /* get rid of leading crap */ 
 383   sprintf(tmp
,"%i",skip
); 
 386   /* now work through remaining buffer printing out data blocks */ 
 391     PrintAndLog("Block %i:", block
); 
 392     // mandemod routine needs to be split so we can call it for data 
 393     // just print for now for debugging 
 394     CmdManchesterDemod("i 64"); 
 396     /* look for LW before start of next block */ 
 397     for ( ; i 
< j 
- 4 ; ++i
) 
 400       if (tmpbuff
[i
] >= 190 && tmpbuff
[i
] <= 194) 
 401         if (tmpbuff
[i
+1] >= 126 && tmpbuff
[i
+1] <= 130) 
 404     while (GraphBuffer
[skip
] > low
) 
 407     sprintf(tmp
,"%i",skip
); 
 415 int CmdEM410xWrite(const char *Cmd
) 
 417   uint64_t id 
= 0xFFFFFFFFFFFFFFFF; // invalid id value 
 418   int card 
= 0xFF; // invalid card value 
 419         unsigned int clock 
= 0; // invalid clock value 
 421         sscanf(Cmd
, "%" PRIx64 
" %d %d", &id
, &card
, &clock
); 
 424         if (id 
== 0xFFFFFFFFFFFFFFFF) { 
 425                 PrintAndLog("Error! ID is required.\n"); 
 428         if (id 
>= 0x10000000000) { 
 429                 PrintAndLog("Error! Given EM410x ID is longer than 40 bits.\n"); 
 435                 PrintAndLog("Error! Card type required.\n"); 
 439                 PrintAndLog("Error! Bad card type selected.\n"); 
 450                 // Allowed clock rates: 16, 32 and 64 
 451                 if ((clock 
!= 16) && (clock 
!= 32) && (clock 
!= 64)) { 
 452                         PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32 and 64.\n", clock
); 
 458                 PrintAndLog("Error! Clock rate is only supported on T55x7 tags.\n"); 
 463                 PrintAndLog("Writing %s tag with UID 0x%010" PRIx64 
" (clock rate: %d)", "T55x7", id
, clock
); 
 464                 // NOTE: We really should pass the clock in as a separate argument, but to 
 465                 //   provide for backwards-compatibility for older firmware, and to avoid 
 466                 //   having to add another argument to CMD_EM410X_WRITE_TAG, we just store 
 467                 //   the clock rate in bits 8-15 of the card value 
 468                 card 
= (card 
& 0xFF) | (((uint64_t)clock 
<< 8) & 0xFF00); 
 471                 PrintAndLog("Writing %s tag with UID 0x%010" PRIx64
, "T5555", id
, clock
); 
 473                 PrintAndLog("Error! Bad card type selected.\n"); 
 477   UsbCommand c 
= {CMD_EM410X_WRITE_TAG
, {card
, (uint32_t)(id 
>> 32), (uint32_t)id
}}; 
 483 int CmdReadWord(const char *Cmd
) 
 485   int Word 
= 16; //default to invalid word 
 488   sscanf(Cmd
, "%d", &Word
); 
 491     PrintAndLog("Word must be between 0 and 15"); 
 495   PrintAndLog("Reading word %d", Word
); 
 497   c
.cmd 
= CMD_EM4X_READ_WORD
; 
 498   c
.d
.asBytes
[0] = 0x0; //Normal mode 
 506 int CmdReadWordPWD(const char *Cmd
) 
 508   int Word 
= 16; //default to invalid word 
 509   int Password 
= 0xFFFFFFFF; //default to blank password 
 512   sscanf(Cmd
, "%d %x", &Word
, &Password
); 
 515     PrintAndLog("Word must be between 0 and 15"); 
 519   PrintAndLog("Reading word %d with password %08X", Word
, Password
); 
 521   c
.cmd 
= CMD_EM4X_READ_WORD
; 
 522   c
.d
.asBytes
[0] = 0x1; //Password mode 
 530 int CmdWriteWord(const char *Cmd
) 
 532   int Word 
= 16; //default to invalid block 
 533   int Data 
= 0xFFFFFFFF; //default to blank data 
 536   sscanf(Cmd
, "%x %d", &Data
, &Word
); 
 539     PrintAndLog("Word must be between 0 and 15"); 
 543   PrintAndLog("Writting word %d with data %08X", Word
, Data
); 
 545   c
.cmd 
= CMD_EM4X_WRITE_WORD
; 
 546   c
.d
.asBytes
[0] = 0x0; //Normal mode 
 554 int CmdWriteWordPWD(const char *Cmd
) 
 556   int Word 
= 8; //default to invalid word 
 557   int Data 
= 0xFFFFFFFF; //default to blank data 
 558   int Password 
= 0xFFFFFFFF; //default to blank password 
 561   sscanf(Cmd
, "%x %d %x", &Data
, &Word
, &Password
); 
 564     PrintAndLog("Word must be between 0 and 15"); 
 568   PrintAndLog("Writting word %d with data %08X and password %08X", Word
, Data
, Password
); 
 570   c
.cmd 
= CMD_EM4X_WRITE_WORD
; 
 571   c
.d
.asBytes
[0] = 0x1; //Password mode 
 581 static command_t CommandTable
[] = 
 583   {"help", CmdHelp
, 1, "This help"}, 
 584   {"em410xread", CmdEM410xRead
, 1, "[clock rate] -- Extract ID from EM410x tag"}, 
 585   {"em410xsim", CmdEM410xSim
, 0, "<UID> -- Simulate EM410x tag"}, 
 586   {"em410xwatch", CmdEM410xWatch
, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, 
 587   {"em410xwrite", CmdEM410xWrite
, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"}, 
 588   {"em4x50read", CmdEM4x50Read
, 1, "Extract data from EM4x50 tag"}, 
 589   {"readword", CmdReadWord
, 1, "<Word> -- Read EM4xxx word data"}, 
 590   {"readwordPWD", CmdReadWordPWD
, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"}, 
 591   {"writeword", CmdWriteWord
, 1, "<Data> <Word> -- Write EM4xxx word data"}, 
 592   {"writewordPWD", CmdWriteWordPWD
, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"}, 
 593   {NULL
, NULL
, 0, NULL
} 
 596 int CmdLFEM4X(const char *Cmd
) 
 598   CmdsParse(CommandTable
, Cmd
); 
 602 int CmdHelp(const char *Cmd
) 
 604   CmdsHelp(CommandTable
);