]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdlft55xx.c
include cmdlfviking.c in makefile and cmdlf
[proxmark3-svn] / client / cmdlft55xx.c
CommitLineData
54a942b0 1//-----------------------------------------------------------------------------\r
2//\r
3// This code is licensed to you under the terms of the GNU GPL, version 2 or,\r
4// at your option, any later version. See the LICENSE.txt file for the text of\r
5// the license.\r
6//-----------------------------------------------------------------------------\r
7// Low frequency T55xx commands\r
8//-----------------------------------------------------------------------------\r
9\r
10#include <stdio.h>\r
11#include <string.h>\r
12#include <inttypes.h>\r
224ce36e 13#include <time.h>\r
54a942b0 14#include "proxmark3.h"\r
15#include "ui.h"\r
16#include "graph.h"\r
13d77ef9 17#include "cmdmain.h"\r
54a942b0 18#include "cmdparser.h"\r
19#include "cmddata.h"\r
20#include "cmdlf.h"\r
21#include "cmdlft55xx.h"\r
13d77ef9 22#include "util.h"\r
23#include "data.h"\r
24#include "lfdemod.h"\r
25#include "../common/crc.h"\r
26#include "../common/iso14443crc.h"\r
27#include "cmdhf14a.h"\r
28\r
709665b5 29#define T55x7_CONFIGURATION_BLOCK 0x00\r
30#define T55x7_PAGE0 0x00\r
31#define T55x7_PAGE1 0x01\r
be2d41b7 32#define REGULAR_READ_MODE_BLOCK 0xFF\r
13d77ef9 33\r
34// Default configuration\r
f6650679 35t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00, .Q5 = FALSE };\r
13d77ef9 36\r
9f669cb2 37t55xx_conf_block_t Get_t55xx_Config(){\r
38 return config;\r
39}\r
40void Set_t55xx_Config(t55xx_conf_block_t conf){\r
41 config = conf;\r
42}\r
43\r
13d77ef9 44int usage_t55xx_config(){\r
f6650679 45 PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>] [Q5]");\r
be2d41b7 46 PrintAndLog("Options:");\r
13d77ef9 47 PrintAndLog(" h This help");\r
f6650679 48 PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate");\r
4ff341ef 49 PrintAndLog(" d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");\r
f6650679 50 PrintAndLog(" i [1] Invert data signal, defaults to normal");\r
51 PrintAndLog(" o [offset] Set offset, where data should start decode in bitstream");\r
52 PrintAndLog(" Q5 Set as Q5(T5555) chip instead of T55x7");\r
13d77ef9 53 PrintAndLog("");\r
54 PrintAndLog("Examples:");\r
55 PrintAndLog(" lf t55xx config d FSK - FSK demodulation");\r
56 PrintAndLog(" lf t55xx config d FSK i 1 - FSK demodulation, inverse data");\r
57 PrintAndLog(" lf t55xx config d FSK i 1 o 3 - FSK demodulation, inverse data, offset=3,start from position 3 to decode data");\r
58 PrintAndLog("");\r
59 return 0;\r
60}\r
61int usage_t55xx_read(){\r
0c8200f1 62 PrintAndLog("Usage: lf t55xx read [b <block>] [p <password>] <override_safety> <page1>");\r
be2d41b7 63 PrintAndLog("Options:");\r
0c8200f1 64 PrintAndLog(" b <block> - block number to read. Between 0-7");\r
65 PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");\r
66 PrintAndLog(" o - OPTIONAL override safety check");\r
67 PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");\r
f1b74c30 68 PrintAndLog(" ****WARNING****");\r
69 PrintAndLog(" Use of read with password on a tag not configured for a pwd");\r
70 PrintAndLog(" can damage the tag");\r
185e038c 71 PrintAndLog("");\r
13d77ef9 72 PrintAndLog("Examples:");\r
0c8200f1 73 PrintAndLog(" lf t55xx read b 0 - read data from block 0");\r
be2d41b7 74 PrintAndLog(" lf t55xx read b 0 p feedbeef - read data from block 0 password feedbeef");\r
75 PrintAndLog(" lf t55xx read b 0 p feedbeef o - read data from block 0 password feedbeef safety check");\r
13d77ef9 76 PrintAndLog("");\r
77 return 0;\r
78}\r
79int usage_t55xx_write(){\r
0c8200f1 80 PrintAndLog("Usage: lf t55xx wr [b <block>] [d <data>] [p <password>] [1]");\r
be2d41b7 81 PrintAndLog("Options:");\r
0c8200f1 82 PrintAndLog(" b <block> - block number to write. Between 0-7");\r
83 PrintAndLog(" d <data> - 4 bytes of data to write (8 hex characters)");\r
84 PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");\r
85 PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");\r
185e038c 86 PrintAndLog("");\r
13d77ef9 87 PrintAndLog("Examples:");\r
be2d41b7 88 PrintAndLog(" lf t55xx wr b 3 d 11223344 - write 11223344 to block 3");\r
89 PrintAndLog(" lf t55xx wr b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");\r
13d77ef9 90 PrintAndLog("");\r
91 return 0;\r
92}\r
93int usage_t55xx_trace() {\r
94 PrintAndLog("Usage: lf t55xx trace [1]");\r
be2d41b7 95 PrintAndLog("Options:");\r
0c8200f1 96 PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");\r
13d77ef9 97 PrintAndLog("");\r
98 PrintAndLog("Examples:");\r
99 PrintAndLog(" lf t55xx trace");\r
100 PrintAndLog(" lf t55xx trace 1");\r
101 PrintAndLog("");\r
102 return 0;\r
103}\r
104int usage_t55xx_info() {\r
105 PrintAndLog("Usage: lf t55xx info [1]");\r
be2d41b7 106 PrintAndLog("Options:");\r
0c8200f1 107 PrintAndLog(" [graph buffer data] - if set, use Graphbuffer otherwise read data from tag.");\r
13d77ef9 108 PrintAndLog("");\r
109 PrintAndLog("Examples:");\r
110 PrintAndLog(" lf t55xx info");\r
111 PrintAndLog(" lf t55xx info 1");\r
112 PrintAndLog("");\r
113 return 0;\r
114}\r
115int usage_t55xx_dump(){\r
be2d41b7 116 PrintAndLog("Usage: lf t55xx dump <password> [o]");\r
117 PrintAndLog("Options:");\r
0c8200f1 118 PrintAndLog(" <password> - OPTIONAL password 4bytes (8 hex symbols)");\r
119 PrintAndLog(" o - OPTIONAL override, force pwd read despite danger to card");\r
13d77ef9 120 PrintAndLog("");\r
121 PrintAndLog("Examples:");\r
122 PrintAndLog(" lf t55xx dump");\r
be2d41b7 123 PrintAndLog(" lf t55xx dump feedbeef o");\r
13d77ef9 124 PrintAndLog("");\r
125 return 0;\r
126}\r
127int usage_t55xx_detect(){\r
ab5ffe3b 128 PrintAndLog("Usage: lf t55xx detect [1] [p <password>]");\r
be2d41b7 129 PrintAndLog("Options:");\r
ab5ffe3b 130 PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag.");\r
131 PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");\r
13d77ef9 132 PrintAndLog("");\r
133 PrintAndLog("Examples:");\r
134 PrintAndLog(" lf t55xx detect");\r
135 PrintAndLog(" lf t55xx detect 1");\r
ab5ffe3b 136 PrintAndLog(" lf t55xx detect p 11223344");\r
13d77ef9 137 PrintAndLog("");\r
138 return 0;\r
139}\r
be2d41b7 140int usage_t55xx_wakup(){\r
141 PrintAndLog("Usage: lf t55xx wakeup [h] p <password>");\r
142 PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");\r
143 PrintAndLog("Options:");\r
144 PrintAndLog(" h - this help");\r
145 PrintAndLog(" p <password> - password 4bytes (8 hex symbols)");\r
146 PrintAndLog("");\r
147 PrintAndLog("Examples:");\r
148 PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");\r
149 return 0;\r
150}\r
54a942b0 151\r
152static int CmdHelp(const char *Cmd);\r
153\r
709665b5 154void printT5xxHeader(uint8_t page){\r
155 PrintAndLog("Reading Page %d:", page); \r
156 PrintAndLog("blk | hex data | binary");\r
157 PrintAndLog("----+----------+---------------------------------"); \r
158}\r
159\r
13d77ef9 160int CmdT55xxSetConfig(const char *Cmd) {\r
54a942b0 161\r
13d77ef9 162 uint8_t offset = 0;\r
13d77ef9 163 char modulation[5] = {0x00};\r
164 char tmp = 0x00;\r
165 uint8_t bitRate = 0;\r
166 uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};\r
8e99ec25 167 uint8_t cmdp = 0;\r
f6650679 168 config.Q5 = FALSE;\r
8e99ec25 169 bool errors = FALSE;\r
13d77ef9 170 while(param_getchar(Cmd, cmdp) != 0x00 && !errors)\r
171 {\r
172 tmp = param_getchar(Cmd, cmdp);\r
173 switch(tmp)\r
174 {\r
175 case 'h':\r
176 case 'H':\r
177 return usage_t55xx_config();\r
178 case 'b':\r
179 errors |= param_getdec(Cmd, cmdp+1, &bitRate);\r
180 if ( !errors){\r
181 uint8_t i = 0;\r
182 for (; i < 9; i++){\r
183 if (rates[i]==bitRate) {\r
184 config.bitrate = i;\r
185 break;\r
186 }\r
187 }\r
188 if (i==9) errors = TRUE;\r
189 }\r
190 cmdp+=2;\r
191 break;\r
192 case 'd':\r
193 param_getstr(Cmd, cmdp+1, modulation);\r
194 cmdp += 2;\r
54a942b0 195\r
2767fc02 196 if ( strcmp(modulation, "FSK" ) == 0) {\r
13d77ef9 197 config.modulation = DEMOD_FSK;\r
2767fc02 198 } else if ( strcmp(modulation, "FSK1" ) == 0) {\r
13d77ef9 199 config.modulation = DEMOD_FSK1;\r
2767fc02 200 config.inverted=1;\r
201 } else if ( strcmp(modulation, "FSK1a" ) == 0) {\r
13d77ef9 202 config.modulation = DEMOD_FSK1a;\r
2767fc02 203 config.inverted=0;\r
204 } else if ( strcmp(modulation, "FSK2" ) == 0) {\r
13d77ef9 205 config.modulation = DEMOD_FSK2;\r
2767fc02 206 config.inverted=0;\r
207 } else if ( strcmp(modulation, "FSK2a" ) == 0) {\r
13d77ef9 208 config.modulation = DEMOD_FSK2a;\r
2767fc02 209 config.inverted=1;\r
210 } else if ( strcmp(modulation, "ASK" ) == 0) {\r
13d77ef9 211 config.modulation = DEMOD_ASK;\r
2767fc02 212 } else if ( strcmp(modulation, "NRZ" ) == 0) {\r
13d77ef9 213 config.modulation = DEMOD_NRZ;\r
2767fc02 214 } else if ( strcmp(modulation, "PSK1" ) == 0) {\r
13d77ef9 215 config.modulation = DEMOD_PSK1;\r
2767fc02 216 } else if ( strcmp(modulation, "PSK2" ) == 0) {\r
13d77ef9 217 config.modulation = DEMOD_PSK2;\r
2767fc02 218 } else if ( strcmp(modulation, "PSK3" ) == 0) {\r
13d77ef9 219 config.modulation = DEMOD_PSK3;\r
2767fc02 220 } else if ( strcmp(modulation, "BIa" ) == 0) {\r
13d77ef9 221 config.modulation = DEMOD_BIa;\r
2767fc02 222 config.inverted=1;\r
223 } else if ( strcmp(modulation, "BI" ) == 0) {\r
13d77ef9 224 config.modulation = DEMOD_BI;\r
2767fc02 225 config.inverted=0;\r
226 } else {\r
13d77ef9 227 PrintAndLog("Unknown modulation '%s'", modulation);\r
228 errors = TRUE;\r
229 }\r
230 break;\r
231 case 'i':\r
232 config.inverted = param_getchar(Cmd,cmdp+1) == '1';\r
233 cmdp+=2;\r
234 break;\r
235 case 'o':\r
236 errors |= param_getdec(Cmd, cmdp+1, &offset);\r
237 if ( !errors )\r
238 config.offset = offset;\r
239 cmdp+=2;\r
240 break;\r
f6650679 241 case 'Q':\r
242 case 'q': \r
243 config.Q5 = TRUE;\r
244 cmdp++;\r
245 break;\r
13d77ef9 246 default:\r
247 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
248 errors = TRUE;\r
249 break;\r
250 }\r
251 }\r
54a942b0 252\r
13d77ef9 253 // No args\r
be2d41b7 254 if (cmdp == 0) return printConfiguration( config );\r
255\r
13d77ef9 256 //Validations\r
be2d41b7 257 if (errors) return usage_t55xx_config();\r
54a942b0 258\r
be2d41b7 259 config.block0 = 0;\r
260 return printConfiguration ( config );\r
261}\r
262\r
263int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){\r
264 //Password mode\r
265 if ( usepwd ) {\r
266 // try reading the config block and verify that PWD bit is set before doing this!\r
267 if ( !override ) {\r
709665b5 268 if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0 ) ) return 0;\r
be2d41b7 269 if ( !tryDetectModulation() ) {\r
270 PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");\r
271 return 0;\r
272 } else {\r
273 PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password..."); \r
274 usepwd = false;\r
275 page1 = false;\r
276 }\r
277 } else {\r
278 PrintAndLog("Safety Check Overriden - proceeding despite risk");\r
279 }\r
280 }\r
281\r
282 if (!AquireData(page1, block, usepwd, password) ) return 0;\r
283 if (!DecodeT55xxBlock()) return 0;\r
284\r
285 char blk[10]={0};\r
286 sprintf(blk,"%d", block);\r
287 printT55xxBlock(blk); \r
288 return 1;\r
13d77ef9 289}\r
54a942b0 290\r
13d77ef9 291int CmdT55xxReadBlock(const char *Cmd) {\r
be2d41b7 292 uint8_t block = REGULAR_READ_MODE_BLOCK;\r
293 uint32_t password = 0; //default to blank Block 7\r
294 bool usepwd = false;\r
295 bool override = false;\r
296 bool page1 = false;\r
8e99ec25 297 bool errors = false;\r
be2d41b7 298 uint8_t cmdp = 0;\r
8e99ec25 299 while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
300 switch(param_getchar(Cmd, cmdp)) {\r
301 case 'h':\r
302 case 'H':\r
303 return usage_t55xx_read();\r
304 case 'b':\r
305 case 'B':\r
306 errors |= param_getdec(Cmd, cmdp+1, &block);\r
be2d41b7 307 cmdp += 2;\r
8e99ec25 308 break;\r
309 case 'o':\r
310 case 'O':\r
be2d41b7 311 override = true;\r
8e99ec25 312 cmdp++;\r
313 break;\r
314 case 'p':\r
315 case 'P':\r
be2d41b7 316 password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
317 usepwd = true;\r
318 cmdp += 2;\r
8e99ec25 319 break;\r
be2d41b7 320 case '1':\r
321 page1 = true;\r
8e99ec25 322 cmdp++;\r
323 break;\r
324 default:\r
325 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
326 errors = true;\r
327 break;\r
328 }\r
329 }\r
330 if (errors) return usage_t55xx_read();\r
13d77ef9 331\r
be2d41b7 332 if (block > 7 && block != REGULAR_READ_MODE_BLOCK ) {\r
333 PrintAndLog("Block must be between 0 and 7");\r
334 return 0;\r
8e99ec25 335 }\r
709665b5 336\r
337 printT5xxHeader(page1);\r
be2d41b7 338 return T55xxReadBlock(block, page1, usepwd, override, password);\r
54a942b0 339}\r
340\r
13d77ef9 341bool DecodeT55xxBlock(){\r
342 \r
fef74fdc 343 char buf[30] = {0x00};\r
13d77ef9 344 char *cmdStr = buf;\r
345 int ans = 0;\r
346 uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};\r
13d77ef9 347 DemodBufferLen = 0x00;\r
54a942b0 348\r
13d77ef9 349 switch( config.modulation ){\r
350 case DEMOD_FSK:\r
224ce36e 351 snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );\r
13d77ef9 352 ans = FSKrawDemod(cmdStr, FALSE);\r
353 break;\r
354 case DEMOD_FSK1:\r
13d77ef9 355 case DEMOD_FSK1a:\r
224ce36e 356 snprintf(cmdStr, sizeof(buf),"%d %d 8 5", bitRate[config.bitrate], config.inverted );\r
13d77ef9 357 ans = FSKrawDemod(cmdStr, FALSE);\r
358 break;\r
359 case DEMOD_FSK2:\r
13d77ef9 360 case DEMOD_FSK2a:\r
224ce36e 361 snprintf(cmdStr, sizeof(buf),"%d %d 10 8", bitRate[config.bitrate], config.inverted );\r
13d77ef9 362 ans = FSKrawDemod(cmdStr, FALSE);\r
363 break;\r
364 case DEMOD_ASK:\r
db829602 365 snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted );\r
fef74fdc 366 ans = ASKDemod(cmdStr, FALSE, FALSE, 1);\r
13d77ef9 367 break;\r
368 case DEMOD_PSK1:\r
db829602 369 // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)\r
370 CmdLtrim("160");\r
371 snprintf(cmdStr, sizeof(buf),"%d %d 6", bitRate[config.bitrate], config.inverted );\r
13d77ef9 372 ans = PSKDemod(cmdStr, FALSE);\r
13d77ef9 373 break;\r
2767fc02 374 case DEMOD_PSK2: //inverted won't affect this\r
375 case DEMOD_PSK3: //not fully implemented\r
db829602 376 // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)\r
377 CmdLtrim("160");\r
378 snprintf(cmdStr, sizeof(buf),"%d 0 6", bitRate[config.bitrate] );\r
13d77ef9 379 ans = PSKDemod(cmdStr, FALSE);\r
380 psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
381 break;\r
382 case DEMOD_NRZ:\r
224ce36e 383 snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted );\r
13d77ef9 384 ans = NRZrawDemod(cmdStr, FALSE);\r
385 break;\r
386 case DEMOD_BI:\r
13d77ef9 387 case DEMOD_BIa:\r
db829602 388 snprintf(cmdStr, sizeof(buf),"0 %d %d 1", bitRate[config.bitrate], config.inverted );\r
13d77ef9 389 ans = ASKbiphaseDemod(cmdStr, FALSE);\r
390 break;\r
391 default:\r
392 return FALSE;\r
393 }\r
394 return (bool) ans;\r
395}\r
54a942b0 396\r
13d77ef9 397int CmdT55xxDetect(const char *Cmd){\r
ab5ffe3b 398 bool errors = FALSE;\r
399 bool useGB = FALSE;\r
400 bool usepwd = FALSE;\r
401 uint32_t password = 0;\r
402 uint8_t cmdp = 0;\r
54a942b0 403\r
ab5ffe3b 404 while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
405 switch(param_getchar(Cmd, cmdp)) {\r
406 case 'h':\r
407 case 'H':\r
408 return usage_t55xx_detect();\r
409 case 'p':\r
410 case 'P':\r
411 password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
412 usepwd = TRUE;\r
413 cmdp += 2;\r
414 break;\r
415 case '1':\r
416 // use Graphbuffer data\r
417 useGB = TRUE;\r
418 cmdp++;\r
419 break;\r
420 default:\r
421 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
422 errors = true;\r
423 break;\r
424 }\r
709665b5 425 }\r
ab5ffe3b 426 if (errors) return usage_t55xx_detect();\r
13d77ef9 427 \r
ab5ffe3b 428 if ( !useGB) {\r
429 if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password) )\r
430 return 0;\r
709665b5 431 }\r
ab5ffe3b 432 \r
13d77ef9 433 if ( !tryDetectModulation() )\r
434 PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");\r
435\r
be2d41b7 436 return 1;\r
54a942b0 437}\r
438\r
13d77ef9 439// detect configuration?\r
440bool tryDetectModulation(){\r
13d77ef9 441 uint8_t hits = 0;\r
442 t55xx_conf_block_t tests[15];\r
fef74fdc 443 int bitRate=0;\r
322f7eb1 444 uint8_t fc1 = 0, fc2 = 0, clk=0;\r
445 save_restoreGB(1);\r
709665b5 446\r
13d77ef9 447 if (GetFskClock("", FALSE, FALSE)){ \r
13d77ef9 448 fskClocks(&fc1, &fc2, &clk, FALSE);\r
f6650679 449 if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)){\r
13d77ef9 450 tests[hits].modulation = DEMOD_FSK;\r
451 if (fc1==8 && fc2 == 5)\r
452 tests[hits].modulation = DEMOD_FSK1a;\r
f6650679 453 else if (fc1==10 && fc2 == 8)\r
13d77ef9 454 tests[hits].modulation = DEMOD_FSK2;\r
fef74fdc 455 tests[hits].bitrate = bitRate;\r
13d77ef9 456 tests[hits].inverted = FALSE;\r
457 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
458 ++hits;\r
459 }\r
f6650679 460 if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
13d77ef9 461 tests[hits].modulation = DEMOD_FSK;\r
fef74fdc 462 if (fc1 == 8 && fc2 == 5)\r
13d77ef9 463 tests[hits].modulation = DEMOD_FSK1;\r
fef74fdc 464 else if (fc1 == 10 && fc2 == 8)\r
13d77ef9 465 tests[hits].modulation = DEMOD_FSK2a;\r
54a942b0 466\r
fef74fdc 467 tests[hits].bitrate = bitRate;\r
13d77ef9 468 tests[hits].inverted = TRUE;\r
469 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
470 ++hits;\r
471 }\r
472 } else {\r
322f7eb1 473 clk = GetAskClock("", FALSE, FALSE);\r
474 if (clk>0) {\r
db829602 475 if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
322f7eb1 476 tests[hits].modulation = DEMOD_ASK;\r
477 tests[hits].bitrate = bitRate;\r
478 tests[hits].inverted = FALSE;\r
479 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
480 ++hits;\r
481 }\r
db829602 482 if ( ASKDemod("0 1 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
322f7eb1 483 tests[hits].modulation = DEMOD_ASK;\r
484 tests[hits].bitrate = bitRate;\r
485 tests[hits].inverted = TRUE;\r
486 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
487 ++hits;\r
488 }\r
db829602 489 if ( ASKbiphaseDemod("0 0 0 2", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5) ) {\r
322f7eb1 490 tests[hits].modulation = DEMOD_BI;\r
491 tests[hits].bitrate = bitRate;\r
492 tests[hits].inverted = FALSE;\r
493 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
494 ++hits;\r
495 }\r
db829602 496 if ( ASKbiphaseDemod("0 0 1 2", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5) ) {\r
322f7eb1 497 tests[hits].modulation = DEMOD_BIa;\r
498 tests[hits].bitrate = bitRate;\r
499 tests[hits].inverted = TRUE;\r
500 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
501 ++hits;\r
502 }\r
13d77ef9 503 }\r
322f7eb1 504 //undo trim from ask\r
505 save_restoreGB(0);\r
506 clk = GetNrzClock("", FALSE, FALSE);\r
507 if (clk>0) {\r
f6650679 508 if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
322f7eb1 509 tests[hits].modulation = DEMOD_NRZ;\r
510 tests[hits].bitrate = bitRate;\r
511 tests[hits].inverted = FALSE;\r
512 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
513 ++hits;\r
514 }\r
54a942b0 515\r
f6650679 516 if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
322f7eb1 517 tests[hits].modulation = DEMOD_NRZ;\r
518 tests[hits].bitrate = bitRate;\r
519 tests[hits].inverted = TRUE;\r
520 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
521 ++hits;\r
522 }\r
13d77ef9 523 }\r
524 \r
322f7eb1 525 //undo trim from nrz\r
526 save_restoreGB(0);\r
db829602 527 // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)\r
528 CmdLtrim("160");\r
322f7eb1 529 clk = GetPskClock("", FALSE, FALSE);\r
530 if (clk>0) {\r
db829602 531 if ( PSKDemod("0 0 6", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
322f7eb1 532 tests[hits].modulation = DEMOD_PSK1;\r
fef74fdc 533 tests[hits].bitrate = bitRate;\r
13d77ef9 534 tests[hits].inverted = FALSE;\r
535 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
536 ++hits;\r
537 }\r
db829602 538 if ( PSKDemod("0 1 6", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
322f7eb1 539 tests[hits].modulation = DEMOD_PSK1;\r
fef74fdc 540 tests[hits].bitrate = bitRate;\r
322f7eb1 541 tests[hits].inverted = TRUE;\r
13d77ef9 542 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
543 ++hits;\r
544 }\r
322f7eb1 545 // PSK2 - needs a call to psk1TOpsk2.\r
db829602 546 if ( PSKDemod("0 0 6", FALSE)) {\r
322f7eb1 547 psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
f6650679 548 if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)){\r
322f7eb1 549 tests[hits].modulation = DEMOD_PSK2;\r
550 tests[hits].bitrate = bitRate;\r
551 tests[hits].inverted = FALSE;\r
552 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
553 ++hits;\r
554 }\r
555 } // inverse waves does not affect this demod\r
556 // PSK3 - needs a call to psk1TOpsk2.\r
db829602 557 if ( PSKDemod("0 0 6", FALSE)) {\r
322f7eb1 558 psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
f6650679 559 if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)){\r
322f7eb1 560 tests[hits].modulation = DEMOD_PSK3;\r
561 tests[hits].bitrate = bitRate;\r
562 tests[hits].inverted = FALSE;\r
563 tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);\r
564 ++hits;\r
565 }\r
566 } // inverse waves does not affect this demod\r
13d77ef9 567 }\r
6fe5c94b 568 } \r
569 save_restoreGB(0); \r
13d77ef9 570 if ( hits == 1) {\r
571 config.modulation = tests[0].modulation;\r
fef74fdc 572 config.bitrate = tests[0].bitrate;\r
13d77ef9 573 config.inverted = tests[0].inverted;\r
574 config.offset = tests[0].offset;\r
575 config.block0 = tests[0].block0;\r
576 printConfiguration( config );\r
577 return TRUE;\r
578 }\r
579 \r
580 if ( hits > 1) {\r
581 PrintAndLog("Found [%d] possible matches for modulation.",hits);\r
582 for(int i=0; i<hits; ++i){\r
583 PrintAndLog("--[%d]---------------", i+1);\r
584 printConfiguration( tests[i] );\r
585 }\r
586 }\r
587 return FALSE;\r
588}\r
589\r
590bool testModulation(uint8_t mode, uint8_t modread){\r
591 switch( mode ){\r
592 case DEMOD_FSK:\r
9f669cb2 593 if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return TRUE;\r
13d77ef9 594 break;\r
595 case DEMOD_ASK:\r
596 if (modread == DEMOD_ASK) return TRUE;\r
597 break;\r
598 case DEMOD_PSK1:\r
599 if (modread == DEMOD_PSK1) return TRUE;\r
600 break;\r
601 case DEMOD_PSK2:\r
602 if (modread == DEMOD_PSK2) return TRUE;\r
603 break;\r
604 case DEMOD_PSK3:\r
605 if (modread == DEMOD_PSK3) return TRUE;\r
606 break;\r
607 case DEMOD_NRZ:\r
608 if (modread == DEMOD_NRZ) return TRUE;\r
609 break;\r
610 case DEMOD_BI:\r
611 if (modread == DEMOD_BI) return TRUE;\r
612 break;\r
613 case DEMOD_BIa:\r
614 if (modread == DEMOD_BIa) return TRUE;\r
615 break; \r
616 default:\r
617 return FALSE;\r
618 }\r
619 return FALSE;\r
620}\r
621\r
f6650679 622bool testQ5Modulation(uint8_t mode, uint8_t modread){\r
623 switch( mode ){\r
13d77ef9 624 case DEMOD_FSK:\r
f6650679 625 if (modread >= 4 && modread <= 5) return TRUE;\r
13d77ef9 626 break;\r
627 case DEMOD_ASK:\r
f6650679 628 if (modread == 0) return TRUE;\r
13d77ef9 629 break;\r
630 case DEMOD_PSK1:\r
f6650679 631 if (modread == 1) return TRUE;\r
632 break;\r
13d77ef9 633 case DEMOD_PSK2:\r
f6650679 634 if (modread == 2) return TRUE;\r
635 break;\r
13d77ef9 636 case DEMOD_PSK3:\r
f6650679 637 if (modread == 3) return TRUE;\r
13d77ef9 638 break;\r
639 case DEMOD_NRZ:\r
f6650679 640 if (modread == 7) return TRUE;\r
641 break;\r
642 case DEMOD_BI:\r
643 if (modread == 6) return TRUE;\r
13d77ef9 644 break;\r
13d77ef9 645 default:\r
646 return FALSE;\r
647 }\r
648 return FALSE;\r
649}\r
650\r
f6650679 651bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){\r
652\r
653 if ( DemodBufferLen < 64 ) return FALSE;\r
654 uint8_t si = 0;\r
db829602 655 for (uint8_t idx = 28; idx < 64; idx++){\r
f6650679 656 si = idx;\r
db829602 657 if ( PackBits(si, 28, DemodBuffer) == 0x00 ) continue;\r
f6650679 658\r
659 uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key\r
660 uint8_t resv = PackBits(si, 8, DemodBuffer); si += 8;\r
661 // 2nibble must be zeroed.\r
f6650679 662 if (safer != 0x6) continue;\r
663 if ( resv > 0x00) continue;\r
664 //uint8_t pageSel = PackBits(si, 1, DemodBuffer); si += 1;\r
665 //uint8_t fastWrite = PackBits(si, 1, DemodBuffer); si += 1;\r
666 si += 1+1;\r
667 int bitRate = PackBits(si, 5, DemodBuffer)*2 + 2; si += 5; //bit rate\r
db829602 668 if (bitRate > 128 || bitRate < 8) continue;\r
f6650679 669\r
db829602 670 //uint8_t AOR = PackBits(si, 1, DemodBuffer); si += 1; \r
f6650679 671 //uint8_t PWD = PackBits(si, 1, DemodBuffer); si += 1; \r
672 //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2; //could check psk cr\r
673 //uint8_t inverse = PackBits(si, 1, DemodBuffer); si += 1;\r
db829602 674 si += 1+1+2+1;\r
675 uint8_t modread = PackBits(si, 3, DemodBuffer); si += 3;\r
676 uint8_t maxBlk = PackBits(si, 3, DemodBuffer); si += 3;\r
f6650679 677 //uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1;\r
db829602 678 if (maxBlk == 0) continue;\r
f6650679 679 //test modulation\r
680 if (!testQ5Modulation(mode, modread)) continue;\r
681 if (bitRate != clk) continue;\r
682 *fndBitRate = bitRate;\r
683 *offset = idx;\r
684\r
685 return TRUE;\r
686 }\r
687 return FALSE;\r
688}\r
689\r
690bool testBitRate(uint8_t readRate, uint8_t clk){\r
db829602 691 uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128};\r
f6650679 692 if (expected[readRate] == clk)\r
693 return true;\r
694\r
695 return false;\r
696}\r
697\r
698bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5){\r
13d77ef9 699\r
fef74fdc 700 if ( DemodBufferLen < 64 ) return FALSE;\r
13d77ef9 701 uint8_t si = 0;\r
db829602 702 for (uint8_t idx = 28; idx < 64; idx++){\r
13d77ef9 703 si = idx;\r
db829602 704 if ( PackBits(si, 28, DemodBuffer) == 0x00 ) continue;\r
13d77ef9 705\r
2767fc02 706 uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key\r
13d77ef9 707 uint8_t resv = PackBits(si, 4, DemodBuffer); si += 4; //was 7 & +=7+3 //should be only 4 bits if extended mode\r
708 // 2nibble must be zeroed.\r
709 // moved test to here, since this gets most faults first.\r
710 if ( resv > 0x00) continue;\r
711\r
2767fc02 712 uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //extended mode part of rate\r
db829602 713 int bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate\r
fef74fdc 714 if (bitRate > 7) continue;\r
13d77ef9 715 uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode\r
2767fc02 716 uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1; \r
717 //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr\r
718 uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode\r
13d77ef9 719 uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2;\r
720 \r
721 //if extended mode\r
722 bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? TRUE : FALSE;\r
723\r
724 if (!extMode){\r
725 if (nml01 || nml02 || xtRate) continue;\r
726 }\r
727 //test modulation\r
728 if (!testModulation(mode, modread)) continue;\r
f6650679 729 if (!testBitRate(bitRate, clk)) continue;\r
fef74fdc 730 *fndBitRate = bitRate;\r
2767fc02 731 *offset = idx;\r
f6650679 732 *Q5 = FALSE;\r
733 return TRUE;\r
734 }\r
735 if (testQ5(mode, offset, fndBitRate, clk)) {\r
736 *Q5 = TRUE;\r
13d77ef9 737 return TRUE;\r
738 }\r
739 return FALSE;\r
54a942b0 740}\r
741\r
224ce36e 742void printT55xxBlock(const char *blockNum){\r
13d77ef9 743 \r
744 uint8_t i = config.offset;\r
745 uint8_t endpos = 32 + i;\r
746 uint32_t blockData = 0;\r
747 uint8_t bits[64] = {0x00};\r
748\r
749 if ( !DemodBufferLen) return;\r
750\r
751 if ( endpos > DemodBufferLen){\r
752 PrintAndLog("The configured offset %d is too big. Possible offset: %d)", i, DemodBufferLen-32);\r
753 return;\r
754 }\r
755\r
756 for (; i < endpos; ++i)\r
757 bits[i - config.offset]=DemodBuffer[i];\r
93507a33 758\r
13d77ef9 759 blockData = PackBits(0, 32, bits);\r
db829602 760\r
be2d41b7 761 PrintAndLog(" %s | %08X | %s", blockNum, blockData, sprint_bin(bits,32));\r
13d77ef9 762}\r
763\r
764int special(const char *Cmd) {\r
765 uint32_t blockData = 0;\r
766 uint8_t bits[32] = {0x00};\r
767\r
be2d41b7 768 PrintAndLog("OFFSET | DATA | BINARY");\r
13d77ef9 769 PrintAndLog("----------------------------------------------------");\r
770 int i,j = 0;\r
771 for (; j < 64; ++j){\r
772 \r
773 for (i = 0; i < 32; ++i)\r
774 bits[i]=DemodBuffer[j+i];\r
775 \r
776 blockData = PackBits(0, 32, bits);\r
777 \r
be2d41b7 778 PrintAndLog(" %02d | 0x%08X | %s",j , blockData, sprint_bin(bits,32)); \r
13d77ef9 779 }\r
780 return 0;\r
781}\r
782\r
be2d41b7 783int printConfiguration( t55xx_conf_block_t b){\r
f6650679 784 PrintAndLog("Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");\r
13d77ef9 785 PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );\r
786 PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );\r
787 PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );\r
788 PrintAndLog("Offset : %d", b.offset);\r
789 PrintAndLog("Block0 : 0x%08X", b.block0);\r
790 PrintAndLog("");\r
be2d41b7 791 return 0;\r
13d77ef9 792}\r
793\r
be2d41b7 794int CmdT55xxWakeUp(const char *Cmd) {\r
795 uint32_t password = 0;\r
796 uint8_t cmdp = 0;\r
797 bool errors = true;\r
798 while(param_getchar(Cmd, cmdp) != 0x00) {\r
799 switch(param_getchar(Cmd, cmdp)) {\r
800 case 'h':\r
801 case 'H':\r
802 return usage_t55xx_wakup();\r
803 case 'p':\r
804 case 'P':\r
805 password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16);\r
806 cmdp += 2;\r
807 errors = false;\r
808 break;\r
809 default:\r
810 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
811 errors = true;\r
812 break;\r
813 }\r
13d77ef9 814 }\r
be2d41b7 815 if (errors) return usage_t55xx_wakup();\r
816\r
817 UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};\r
818 clearCommandBuffer();\r
819 SendCommand(&c);\r
820 PrintAndLog("Wake up command sent. Try read now");\r
821 return 0;\r
822}\r
823\r
824int CmdT55xxWriteBlock(const char *Cmd) {\r
825 uint8_t block = 0xFF; //default to invalid block\r
709665b5 826 uint32_t data = 0; //default to blank Block \r
827 uint32_t password = 0; //default to blank Block 7\r
be2d41b7 828 bool usepwd = false;\r
829 bool page1 = false; \r
830 bool gotdata = false;\r
831 bool errors = false;\r
832 uint8_t cmdp = 0;\r
833 while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
834 switch(param_getchar(Cmd, cmdp)) {\r
835 case 'h':\r
836 case 'H':\r
837 return usage_t55xx_write();\r
838 case 'b':\r
839 case 'B':\r
840 errors |= param_getdec(Cmd, cmdp+1, &block);\r
841 cmdp += 2;\r
842 break;\r
843 case 'd':\r
844 case 'D':\r
845 data = param_get32ex(Cmd, cmdp+1, 0, 16);\r
846 gotdata = true;\r
847 cmdp += 2;\r
848 break;\r
849 case 'p':\r
850 case 'P':\r
851 password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
852 usepwd = true;\r
853 cmdp += 2;\r
854 break;\r
855 case '1':\r
856 page1 = true;\r
857 cmdp++;\r
858 break;\r
859 default:\r
860 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
861 errors = true;\r
862 break;\r
863 }\r
13d77ef9 864 }\r
be2d41b7 865 if (errors || !gotdata) return usage_t55xx_write();\r
13d77ef9 866\r
867 if (block > 7) {\r
868 PrintAndLog("Block number must be between 0 and 7");\r
be2d41b7 869 return 0;\r
13d77ef9 870 }\r
871 \r
872 UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
976627d5 873 UsbCommand resp;\r
be2d41b7 874 c.d.asBytes[0] = (page1) ? 0x2 : 0; \r
13d77ef9 875\r
709665b5 876 char pwdStr[16] = {0};\r
877 snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);\r
878\r
879 PrintAndLog("Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "" );\r
13d77ef9 880\r
881 //Password mode\r
be2d41b7 882 if (usepwd) {\r
13d77ef9 883 c.arg[2] = password;\r
be2d41b7 884 c.d.asBytes[0] |= 0x1; \r
13d77ef9 885 }\r
40c5f342 886 clearCommandBuffer();\r
13d77ef9 887 SendCommand(&c);\r
976627d5
MHS
888 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){\r
889 PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");\r
be2d41b7 890 return 0;\r
976627d5 891 }\r
be2d41b7 892 return 1;\r
54a942b0 893}\r
894\r
be2d41b7 895int CmdT55xxReadTrace(const char *Cmd) {\r
13d77ef9 896 char cmdp = param_getchar(Cmd, 0);\r
be2d41b7 897 bool pwdmode = false;\r
898 uint32_t password = 0;\r
13d77ef9 899 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') \r
900 return usage_t55xx_trace();\r
901\r
902 if (strlen(Cmd)==0)\r
709665b5 903 if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password ) )\r
be2d41b7 904 return 0;\r
13d77ef9 905 \r
be2d41b7 906 if (!DecodeT55xxBlock()) return 0;\r
907\r
908 if ( !DemodBufferLen) return 0;\r
54a942b0 909\r
13d77ef9 910 RepaintGraphWindow();\r
911 uint8_t repeat = 0;\r
912 if (config.offset > 5) \r
913 repeat = 32;\r
914 uint8_t si = config.offset+repeat;\r
be2d41b7 915 uint32_t bl1 = PackBits(si, 32, DemodBuffer);\r
916 uint32_t bl2 = PackBits(si+32, 32, DemodBuffer);\r
13d77ef9 917 \r
224ce36e 918 uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8;\r
919 uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8;\r
920 uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5;\r
921 uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3;\r
922 uint32_t year = PackBits(si, 4, DemodBuffer); si += 4;\r
923 uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2;\r
924 uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14;\r
925 uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5;\r
13d77ef9 926 uint32_t dw = PackBits(si, 15, DemodBuffer); \r
927 \r
224ce36e 928 time_t t = time(NULL);\r
929 struct tm tm = *localtime(&t);\r
930 if ( year > tm.tm_year-110)\r
931 year += 2000;\r
932 else\r
933 year += 2010;\r
934\r
f6650679 935 if (config.Q5) PrintAndLog("*** Warning *** Info read off a Q5 will not work as expected");\r
224ce36e 936 if ( acl != 0xE0 ) {\r
937 PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");\r
be2d41b7 938 return 0;\r
224ce36e 939 }\r
13d77ef9 940 PrintAndLog("");\r
941 PrintAndLog("-- T55xx Trace Information ----------------------------------");\r
942 PrintAndLog("-------------------------------------------------------------");\r
943 PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl);\r
944 PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d) - %s", mfc, mfc, getTagInfo(mfc));\r
945 PrintAndLog(" CID : 0x%02X (%d) - %s", cid, cid, GetModelStrFromCID(cid));\r
946 PrintAndLog(" ICR IC Revision : %d",icr );\r
947 PrintAndLog(" Manufactured");\r
cc15a118 948 PrintAndLog(" Year/Quarter : %d/%d",year, quarter);\r
13d77ef9 949 PrintAndLog(" Lot ID : %d", lotid );\r
950 PrintAndLog(" Wafer number : %d", wafer);\r
951 PrintAndLog(" Die Number : %d", dw);\r
952 PrintAndLog("-------------------------------------------------------------");\r
953 PrintAndLog(" Raw Data - Page 1");\r
be2d41b7 954 PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) );\r
955 PrintAndLog(" Block 2 : 0x%08X %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );\r
13d77ef9 956 PrintAndLog("-------------------------------------------------------------");\r
54a942b0 957\r
13d77ef9 958 /*\r
959 TRACE - BLOCK O\r
960 Bits Definition HEX\r
961 1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0 \r
962 9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation\r
963 17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2 \r
964 22-24 ICR IC revision\r
965 25-28 YEAR (BCD encoded) 9 (= 2009)\r
966 29-30 QUARTER 1,2,3,4 \r
967 31-32 LOT ID\r
968 \r
969 TRACE - BLOCK 1\r
970 1-12 LOT ID \r
971 13-17 Wafer number\r
972 18-32 DW, die number sequential\r
973 */\r
974 \r
54a942b0 975 return 0;\r
976}\r
977\r
13d77ef9 978int CmdT55xxInfo(const char *Cmd){\r
979 /*\r
980 Page 0 Block 0 Configuration data.\r
981 Normal mode\r
982 Extended mode\r
983 */\r
be2d41b7 984 bool pwdmode = false;\r
985 uint32_t password = 0;\r
13d77ef9 986 char cmdp = param_getchar(Cmd, 0);\r
987\r
988 if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')\r
989 return usage_t55xx_info();\r
990 \r
991 if (strlen(Cmd)==0)\r
709665b5 992 if ( !AquireData( T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password ) )\r
be2d41b7 993 return 1;\r
fef74fdc 994\r
13d77ef9 995 if (!DecodeT55xxBlock()) return 1;\r
996\r
fef74fdc 997 if ( DemodBufferLen < 32) return 1;\r
13d77ef9 998\r
999 uint8_t si = config.offset;\r
1000 uint32_t bl0 = PackBits(si, 32, DemodBuffer);\r
1001 \r
1002 uint32_t safer = PackBits(si, 4, DemodBuffer); si += 4; \r
1003 uint32_t resv = PackBits(si, 7, DemodBuffer); si += 7;\r
1004 uint32_t dbr = PackBits(si, 3, DemodBuffer); si += 3;\r
1005 uint32_t extend = PackBits(si, 1, DemodBuffer); si += 1;\r
1006 uint32_t datamod = PackBits(si, 5, DemodBuffer); si += 5;\r
1007 uint32_t pskcf = PackBits(si, 2, DemodBuffer); si += 2;\r
1008 uint32_t aor = PackBits(si, 1, DemodBuffer); si += 1; \r
1009 uint32_t otp = PackBits(si, 1, DemodBuffer); si += 1; \r
1010 uint32_t maxblk = PackBits(si, 3, DemodBuffer); si += 3;\r
1011 uint32_t pwd = PackBits(si, 1, DemodBuffer); si += 1; \r
1012 uint32_t sst = PackBits(si, 1, DemodBuffer); si += 1; \r
1013 uint32_t fw = PackBits(si, 1, DemodBuffer); si += 1;\r
1014 uint32_t inv = PackBits(si, 1, DemodBuffer); si += 1; \r
1015 uint32_t por = PackBits(si, 1, DemodBuffer); si += 1;\r
db829602 1016 if (config.Q5) PrintAndLog("*** Warning *** Config Info read off a Q5 will not display as expected");\r
13d77ef9 1017 PrintAndLog("");\r
1018 PrintAndLog("-- T55xx Configuration & Tag Information --------------------");\r
1019 PrintAndLog("-------------------------------------------------------------");\r
1020 PrintAndLog(" Safer key : %s", GetSaferStr(safer));\r
1021 PrintAndLog(" reserved : %d", resv);\r
1022 PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr));\r
1023 PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No");\r
1024 PrintAndLog(" Modulation : %s", GetModulationStr(datamod));\r
1025 PrintAndLog(" PSK clock frequency : %d", pskcf);\r
1026 PrintAndLog(" AOR - Answer on Request : %s", (aor) ? "Yes":"No");\r
1027 PrintAndLog(" OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" );\r
1028 PrintAndLog(" Max block : %d", maxblk);\r
1029 PrintAndLog(" Password mode : %s", (pwd) ? "Yes":"No");\r
1030 PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No");\r
1031 PrintAndLog(" Fast Write : %s", (fw) ? "Yes":"No");\r
1032 PrintAndLog(" Inverse data : %s", (inv) ? "Yes":"No");\r
1033 PrintAndLog(" POR-Delay : %s", (por) ? "Yes":"No");\r
1034 PrintAndLog("-------------------------------------------------------------");\r
1035 PrintAndLog(" Raw Data - Page 0");\r
1036 PrintAndLog(" Block 0 : 0x%08X %s", bl0, sprint_bin(DemodBuffer+config.offset,32) );\r
1037 PrintAndLog("-------------------------------------------------------------");\r
1038 \r
1039 return 0;\r
1040}\r
1041\r
1042int CmdT55xxDump(const char *Cmd){\r
1043\r
be2d41b7 1044 uint32_t password = 0;\r
13d77ef9 1045 char cmdp = param_getchar(Cmd, 0);\r
be2d41b7 1046 bool override = false;\r
1047 if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump();\r
1048\r
1049 bool usepwd = ( strlen(Cmd) > 0); \r
1050 if ( usepwd ){\r
1051 password = param_get32ex(Cmd, 0, 0, 16);\r
1052 if (param_getchar(Cmd, 1) =='o' )\r
1053 override = true;\r
13d77ef9 1054 }\r
1055 \r
709665b5 1056 printT5xxHeader(0);\r
1057 for ( uint8_t i = 0; i <8; ++i)\r
be2d41b7 1058 T55xxReadBlock(i, 0, usepwd, override, password);\r
709665b5 1059\r
1060 printT5xxHeader(1);\r
1061 for ( uint8_t i = 0; i<4; i++)\r
be2d41b7 1062 T55xxReadBlock(i, 1, usepwd, override, password); \r
709665b5 1063\r
be2d41b7 1064 return 1;\r
13d77ef9 1065}\r
1066\r
be2d41b7 1067int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){\r
709665b5 1068 // arg0 bitmodes:\r
1069 // bit0 = pwdmode\r
1070 // bit1 = page to read from\r
be2d41b7 1071 uint8_t arg0 = (page<<1) | pwdmode;\r
1072 UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};\r
13d77ef9 1073\r
40c5f342 1074 clearCommandBuffer();\r
13d77ef9 1075 SendCommand(&c);\r
1076 if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
1077 PrintAndLog("command execution time out");\r
be2d41b7 1078 return 0;\r
13d77ef9 1079 }\r
1080\r
1081 uint8_t got[12000];\r
1082 GetFromBigBuf(got,sizeof(got),0);\r
1083 WaitForResponse(CMD_ACK,NULL);\r
be2d41b7 1084 setGraphBuf(got, sizeof(got));\r
1085 return 1;\r
13d77ef9 1086}\r
1087\r
1088char * GetBitRateStr(uint32_t id){\r
fef74fdc 1089 static char buf[25];\r
1090\r
13d77ef9 1091 char *retStr = buf;\r
1092 switch (id){\r
1093 case 0: \r
9795e535 1094 snprintf(retStr,sizeof(buf),"%d - RF/8",id);\r
13d77ef9 1095 break;\r
1096 case 1:\r
9795e535 1097 snprintf(retStr,sizeof(buf),"%d - RF/16",id);\r
13d77ef9 1098 break;\r
1099 case 2: \r
9795e535 1100 snprintf(retStr,sizeof(buf),"%d - RF/32",id);\r
13d77ef9 1101 break;\r
1102 case 3:\r
9795e535 1103 snprintf(retStr,sizeof(buf),"%d - RF/40",id);\r
13d77ef9 1104 break;\r
1105 case 4:\r
9795e535 1106 snprintf(retStr,sizeof(buf),"%d - RF/50",id);\r
13d77ef9 1107 break;\r
1108 case 5:\r
9795e535 1109 snprintf(retStr,sizeof(buf),"%d - RF/64",id);\r
13d77ef9 1110 break;\r
1111 case 6:\r
9795e535 1112 snprintf(retStr,sizeof(buf),"%d - RF/100",id);\r
13d77ef9 1113 break;\r
1114 case 7:\r
9795e535 1115 snprintf(retStr,sizeof(buf),"%d - RF/128",id);\r
13d77ef9 1116 break;\r
1117 default:\r
9795e535 1118 snprintf(retStr,sizeof(buf),"%d - (Unknown)",id);\r
13d77ef9 1119 break;\r
1120 }\r
1121\r
1122 return buf;\r
1123}\r
1124\r
1125char * GetSaferStr(uint32_t id){\r
1126 static char buf[40];\r
1127 char *retStr = buf;\r
1128 \r
9795e535 1129 snprintf(retStr,sizeof(buf),"%d",id);\r
13d77ef9 1130 if (id == 6) {\r
9795e535 1131 snprintf(retStr,sizeof(buf),"%d - passwd",id);\r
13d77ef9 1132 }\r
1133 if (id == 9 ){\r
9795e535 1134 snprintf(retStr,sizeof(buf),"%d - testmode",id);\r
13d77ef9 1135 }\r
1136 \r
1137 return buf;\r
1138}\r
9795e535 1139\r
13d77ef9 1140char * GetModulationStr( uint32_t id){\r
2767fc02 1141 static char buf[60];\r
13d77ef9 1142 char *retStr = buf;\r
1143 \r
1144 switch (id){\r
1145 case 0: \r
9795e535 1146 snprintf(retStr,sizeof(buf),"%d - DIRECT (ASK/NRZ)",id);\r
13d77ef9 1147 break;\r
1148 case 1:\r
9795e535 1149 snprintf(retStr,sizeof(buf),"%d - PSK 1 phase change when input changes",id);\r
13d77ef9 1150 break;\r
1151 case 2: \r
9795e535 1152 snprintf(retStr,sizeof(buf),"%d - PSK 2 phase change on bitclk if input high",id);\r
13d77ef9 1153 break;\r
1154 case 3:\r
9795e535 1155 snprintf(retStr,sizeof(buf),"%d - PSK 3 phase change on rising edge of input",id);\r
13d77ef9 1156 break;\r
1157 case 4:\r
9795e535 1158 snprintf(retStr,sizeof(buf),"%d - FSK 1 RF/8 RF/5",id);\r
13d77ef9 1159 break;\r
1160 case 5:\r
9795e535 1161 snprintf(retStr,sizeof(buf),"%d - FSK 2 RF/8 RF/10",id);\r
13d77ef9 1162 break;\r
1163 case 6:\r
9795e535 1164 snprintf(retStr,sizeof(buf),"%d - FSK 1a RF/5 RF/8",id);\r
13d77ef9 1165 break;\r
1166 case 7:\r
9795e535 1167 snprintf(retStr,sizeof(buf),"%d - FSK 2a RF/10 RF/8",id);\r
13d77ef9 1168 break;\r
1169 case 8:\r
cc15a118 1170 snprintf(retStr,sizeof(buf),"%d - Manchester",id);\r
13d77ef9 1171 break;\r
1172 case 16:\r
9795e535 1173 snprintf(retStr,sizeof(buf),"%d - Biphase",id);\r
13d77ef9 1174 break;\r
1175 case 0x18:\r
9795e535 1176 snprintf(retStr,sizeof(buf),"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id);\r
13d77ef9 1177 break;\r
1178 case 17:\r
9795e535 1179 snprintf(retStr,sizeof(buf),"%d - Reserved",id);\r
13d77ef9 1180 break;\r
1181 default:\r
9795e535 1182 snprintf(retStr,sizeof(buf),"0x%02X (Unknown)",id);\r
13d77ef9 1183 break;\r
1184 }\r
1185 return buf;\r
1186}\r
1187\r
1188char * GetModelStrFromCID(uint32_t cid){\r
1189 \r
1190 static char buf[10];\r
1191 char *retStr = buf;\r
1192 \r
224ce36e 1193 if (cid == 1) snprintf(retStr, sizeof(buf),"ATA5577M1");\r
1194 if (cid == 2) snprintf(retStr, sizeof(buf),"ATA5577M2"); \r
13d77ef9 1195 return buf;\r
1196}\r
1197\r
1198char * GetSelectedModulationStr( uint8_t id){\r
1199\r
9795e535 1200 static char buf[20];\r
13d77ef9 1201 char *retStr = buf;\r
1202\r
1203 switch (id){\r
1204 case DEMOD_FSK:\r
9795e535 1205 snprintf(retStr,sizeof(buf),"FSK");\r
13d77ef9 1206 break;\r
1207 case DEMOD_FSK1:\r
9795e535 1208 snprintf(retStr,sizeof(buf),"FSK1");\r
13d77ef9 1209 break;\r
1210 case DEMOD_FSK1a:\r
9795e535 1211 snprintf(retStr,sizeof(buf),"FSK1a");\r
13d77ef9 1212 break;\r
1213 case DEMOD_FSK2:\r
9795e535 1214 snprintf(retStr,sizeof(buf),"FSK2");\r
13d77ef9 1215 break;\r
1216 case DEMOD_FSK2a:\r
9795e535 1217 snprintf(retStr,sizeof(buf),"FSK2a");\r
13d77ef9 1218 break;\r
1219 case DEMOD_ASK: \r
9795e535 1220 snprintf(retStr,sizeof(buf),"ASK");\r
13d77ef9 1221 break;\r
1222 case DEMOD_NRZ:\r
9795e535 1223 snprintf(retStr,sizeof(buf),"DIRECT/NRZ");\r
13d77ef9 1224 break;\r
1225 case DEMOD_PSK1:\r
9795e535 1226 snprintf(retStr,sizeof(buf),"PSK1");\r
13d77ef9 1227 break;\r
1228 case DEMOD_PSK2:\r
9795e535 1229 snprintf(retStr,sizeof(buf),"PSK2");\r
13d77ef9 1230 break;\r
1231 case DEMOD_PSK3:\r
9795e535 1232 snprintf(retStr,sizeof(buf),"PSK3");\r
13d77ef9 1233 break;\r
1234 case DEMOD_BI:\r
9795e535 1235 snprintf(retStr,sizeof(buf),"BIPHASE");\r
13d77ef9 1236 break;\r
1237 case DEMOD_BIa:\r
9795e535 1238 snprintf(retStr,sizeof(buf),"BIPHASEa - (CDP)");\r
13d77ef9 1239 break;\r
1240 default:\r
9795e535 1241 snprintf(retStr,sizeof(buf),"(Unknown)");\r
13d77ef9 1242 break;\r
1243 }\r
1244 return buf;\r
1245}\r
1246\r
1247uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){\r
1248 \r
1249 int i = start;\r
1250 int j = len-1;\r
1251\r
1252 if (len > 32) return 0;\r
1253\r
1254 uint32_t tmp = 0;\r
1255 for (; j >= 0; --j, ++i)\r
1256 tmp |= bits[i] << j;\r
1257\r
1258 return tmp;\r
1259}\r
1260\r
66837a03 1261int CmdResetRead(const char *Cmd) {\r
1262 UsbCommand c = {CMD_T55XX_RESET_READ, {0,0,0}};\r
1263\r
1264 clearCommandBuffer();\r
1265 SendCommand(&c);\r
1266 if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
1267 PrintAndLog("command execution time out");\r
1268 return 0;\r
1269 }\r
1270\r
9f669cb2 1271 uint8_t got[BIGBUF_SIZE-1];\r
66837a03 1272 GetFromBigBuf(got,sizeof(got),0);\r
1273 WaitForResponse(CMD_ACK,NULL);\r
1274 setGraphBuf(got, sizeof(got));\r
1275 return 1;\r
1276}\r
1277\r
f6650679 1278int CmdT55xxWipe(const char *Cmd) {\r
1279 char writeData[20] = {0};\r
1280 char *ptrData = writeData;\r
709665b5 1281\r
f6650679 1282 PrintAndLog("\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n");\r
709665b5 1283\r
f6650679 1284 //try with the default password to reset block 0 (with a pwd should work even if pwd bit not set)\r
709665b5 1285 snprintf(ptrData,sizeof(writeData),"b 0 d 00088040 p 0");\r
1286\r
1287 if (!CmdT55xxWriteBlock(ptrData))\r
1288 PrintAndLog("Error writing blk 0");\r
1289\r
1290 for (uint8_t blk = 1; blk<8; blk++) {\r
f6650679 1291 snprintf(ptrData,sizeof(writeData),"b %d d 0", blk);\r
709665b5 1292 if (!CmdT55xxWriteBlock(ptrData))\r
f6650679 1293 PrintAndLog("Error writing blk %d", blk);\r
709665b5 1294\r
1295 memset(writeData, sizeof(writeData), 0x00);\r
f6650679 1296 }\r
1297 return 0;\r
1298}\r
1299\r
709665b5 1300static command_t CommandTable[] = {\r
66837a03 1301 {"help", CmdHelp, 1, "This help"},\r
1302 {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
709665b5 1303 {"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},\r
9f669cb2 1304 {"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},\r
66837a03 1305 {"resetread",CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},\r
9f669cb2 1306 {"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},\r
709665b5 1307 {"trace", CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},\r
1308 {"info", CmdT55xxInfo, 1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},\r
9f669cb2 1309 {"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},\r
66837a03 1310 {"special", special, 0, "Show block changes with 64 different offsets"},\r
1311 {"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},\r
f6650679 1312 {"wipe", CmdT55xxWipe, 0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},\r
54a942b0 1313 {NULL, NULL, 0, NULL}\r
1314};\r
1315\r
709665b5 1316int CmdLFT55XX(const char *Cmd) {\r
54a942b0 1317 CmdsParse(CommandTable, Cmd);\r
1318 return 0;\r
1319}\r
1320\r
709665b5 1321int CmdHelp(const char *Cmd) {\r
54a942b0 1322 CmdsHelp(CommandTable);\r
1323 return 0;\r
1324}\r
Impressum, Datenschutz