textual
[RRG-proxmark3.git] / client / src / cmdlfawid.c
blobc346061e552cad42742c06d3767ed2079d0a4bbc
1 //-----------------------------------------------------------------------------
2 // Authored by Craig Young <cyoung@tripwire.com> based on cmdlfhid.c structure
3 //
4 // cmdlfhid.c is Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
5 //
6 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
7 // at your option, any later version. See the LICENSE.txt file for the text of
8 // the license.
9 //-----------------------------------------------------------------------------
10 // Low frequency AWID26/50 commands
11 // FSK2a, RF/50, 96 bits (complete)
12 //-----------------------------------------------------------------------------
13 #include "cmdlfawid.h" // AWID function declarations
14 #include <ctype.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "commonutil.h" // ARRAYLEN
18 #include "cmdparser.h" // command_t
19 #include "comms.h"
20 #include "graph.h"
21 #include "cmddata.h"
22 #include "ui.h" // PrintAndLog
23 #include "lfdemod.h" // parityTest
24 #include "cmdlf.h" // lf read
25 #include "protocols.h" // for T55xx config register definitions
26 #include "util_posix.h"
27 #include "cmdlft55xx.h" // verifywrite
28 #include "cliparser.h"
29 #include "cmdlfem4x05.h" // EM defines
31 static int CmdHelp(const char *Cmd);
33 static int sendPing(void) {
34 SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
35 SendCommandNG(CMD_PING, NULL, 0);
36 clearCommandBuffer();
37 PacketResponseNG resp;
38 if (!WaitForResponseTimeout(CMD_PING, &resp, 1000))
39 return PM3_ETIMEOUT;
40 return PM3_SUCCESS;
43 static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, size_t bs_len, bool verbose) {
45 if (verbose)
46 PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fc, cn);
48 if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
49 PrintAndLogEx(ERR, "Error with tag bitstream generation.");
50 return PM3_ESOFT;
53 lf_fsksim_t *payload = calloc(1, sizeof(lf_fsksim_t) + bs_len);
54 payload->fchigh = 10;
55 payload->fclow = 8;
56 payload->separator = 1;
57 payload->clock = 50;
58 memcpy(payload->data, bits, bs_len);
60 clearCommandBuffer();
61 SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + bs_len);
62 free(payload);
64 msleep(delay);
65 return sendPing();
68 static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
69 switch (*fmtlen) {
70 case 50:
71 if ((*fc & 0xFFFF) != *fc) {
72 *fc &= 0xFFFF;
73 PrintAndLogEx(INFO, "Facility-Code Truncated to 16-bits (AWID50): %u", *fc);
75 break;
76 case 37:
77 if ((*fc & 0x1FFF) != *fc) {
78 *fc &= 0x1FFF;
79 PrintAndLogEx(INFO, "Facility-Code Truncated to 13-bits (AWID37): %u", *fc);
81 if ((*cn & 0x3FFFF) != *cn) {
82 *cn &= 0x3FFFF;
83 PrintAndLogEx(INFO, "Card Number Truncated to 18-bits (AWID37): %u", *cn);
85 break;
86 case 34:
87 if ((*fc & 0xFF) != *fc) {
88 *fc &= 0xFF;
89 PrintAndLogEx(INFO, "Facility-Code Truncated to 8-bits (AWID34): %u", *fc);
91 if ((*cn & 0xFFFFFF) != *cn) {
92 *cn &= 0xFFFFFF;
93 PrintAndLogEx(INFO, "Card Number Truncated to 24-bits (AWID34): %u", *cn);
95 break;
96 case 26:
97 default:
98 *fmtlen = 26;
99 if ((*fc & 0xFF) != *fc) {
100 *fc &= 0xFF;
101 PrintAndLogEx(INFO, "Facility-Code Truncated to 8-bits (AWID26): %u", *fc);
103 if ((*cn & 0xFFFF) != *cn) {
104 *cn &= 0xFFFF;
105 PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (AWID26): %u", *cn);
107 break;
111 // this read loops on device side.
112 // uses the demod in lfops.c
113 static int CmdAWIDWatch(const char *Cmd) {
114 CLIParserContext *ctx;
115 CLIParserInit(&ctx, "lf awid watch",
116 "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.\n"
117 "Run until the button is pressed or another USB command is issued.",
118 "lf awid watch"
121 void *argtable[] = {
122 arg_param_begin,
123 arg_param_end
125 CLIExecWithReturn(ctx, Cmd, argtable, true);
126 CLIParserFree(ctx);
128 PrintAndLogEx(SUCCESS, "Watching for AWID cards - place tag on antenna");
129 PrintAndLogEx(INFO, "Press pm3-button to stop reading cards");
130 clearCommandBuffer();
131 SendCommandNG(CMD_LF_AWID_WATCH, NULL, 0);
132 return lfsim_wait_check(CMD_LF_AWID_WATCH);
135 //by marshmellow
136 //AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
137 //print full AWID Prox ID and some bit format details if found
138 int demodAWID(bool verbose) {
139 (void) verbose; // unused so far
140 uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
141 if (bits == NULL) {
142 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID failed to allocate memory");
143 return PM3_EMALLOC;
146 size_t size = getFromGraphBuf(bits);
147 if (size == 0) {
148 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID not enough samples");
149 free(bits);
150 return PM3_ENODATA;
152 //get binary from fsk wave
153 int waveIdx = 0;
154 int idx = detectAWID(bits, &size, &waveIdx);
155 if (idx <= 0) {
157 if (idx == -1)
158 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID not enough samples");
159 else if (idx == -2)
160 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID only noise found");
161 else if (idx == -3)
162 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID problem during FSK demod");
163 else if (idx == -4)
164 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID preamble not found");
165 else if (idx == -5)
166 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID size not correct, size %zu", size);
167 else
168 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID error demoding fsk %d", idx);
170 free(bits);
171 return PM3_ESOFT;
174 setDemodBuff(bits, size, idx);
175 setClockGrid(50, waveIdx + (idx * 50));
178 // Index map
179 // 0 10 20 30 40 50 60
180 // | | | | | | |
181 // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
182 // -----------------------------------------------------------------------------
183 // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
184 // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
185 // |---26 bit---| |-----117----||-------------142-------------|
186 // b = format bit len, o = odd parity of last 3 bits
187 // f = facility code, c = card number
188 // w = wiegand parity
189 // (26 bit format shown)
191 //get raw ID before removing parities
192 uint32_t rawLo = bytebits_to_byte(bits + idx + 64, 32);
193 uint32_t rawHi = bytebits_to_byte(bits + idx + 32, 32);
194 uint32_t rawHi2 = bytebits_to_byte(bits + idx, 32);
196 size = removeParity(bits, idx + 8, 4, 1, 88);
197 if (size != 66) {
198 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID at parity check-tag size does not match AWID format");
199 free(bits);
200 return PM3_ESOFT;
202 // ok valid card found!
204 // Index map
205 // 0 10 20 30 40 50 60
206 // | | | | | | |
207 // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
208 // -----------------------------------------------------------------------------
209 // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
210 // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
211 // |26 bit| |-117--| |-----142------|
213 // 00110010 0 0000111110100000 00000000000100010010100010000111 1 000000000
214 // bbbbbbbb w ffffffffffffffff cccccccccccccccccccccccccccccccc w xxxxxxxxx
215 // |50 bit| |----4000------| |-----------2248975------------|
216 // b = format bit len, o = odd parity of last 3 bits
217 // f = facility code, c = card number
218 // w = wiegand parity
220 uint32_t fc = 0;
221 uint32_t cardnum = 0;
222 uint32_t code1 = 0;
223 uint32_t code2 = 0;
224 uint8_t fmtLen = bytebits_to_byte(bits, 8);
226 switch (fmtLen) {
227 case 26:
228 fc = bytebits_to_byte(bits + 9, 8);
229 cardnum = bytebits_to_byte(bits + 17, 16);
230 code1 = bytebits_to_byte(bits + 8, fmtLen);
231 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d") " FC: " _GREEN_("%d") " Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x") ", Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
232 break;
233 case 34:
234 fc = bytebits_to_byte(bits + 9, 8);
235 cardnum = bytebits_to_byte(bits + 17, 24);
236 code1 = bytebits_to_byte(bits + 8, (fmtLen - 32));
237 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
238 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d") " FC: " _GREEN_("%d") " Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
239 break;
240 case 37:
241 fc = bytebits_to_byte(bits + 9, 13);
242 cardnum = bytebits_to_byte(bits + 22, 18);
243 code1 = bytebits_to_byte(bits + 8, (fmtLen - 32));
244 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
245 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d")" FC: " _GREEN_("%d")" Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
246 break;
247 // case 40:
248 // break;
249 case 50:
250 fc = bytebits_to_byte(bits + 9, 16);
251 cardnum = bytebits_to_byte(bits + 25, 32);
252 code1 = bytebits_to_byte(bits + 8, (fmtLen - 32));
253 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
254 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d") " FC: " _GREEN_("%d") " Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
255 break;
256 default:
257 if (fmtLen > 32) {
258 cardnum = bytebits_to_byte(bits + 8 + (fmtLen - 17), 16);
259 code1 = bytebits_to_byte(bits + 8, fmtLen - 32);
260 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
261 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d") " -unknown- (%u) - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
262 } else {
263 cardnum = bytebits_to_byte(bits + 8 + (fmtLen - 17), 16);
264 code1 = bytebits_to_byte(bits + 8, fmtLen);
265 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d") " -unknown- (%u) - Wiegand: " _GREEN_("%x") ", Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
267 break;
269 free(bits);
271 PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %zu Printing Demod Buffer:", idx, size);
272 if (g_debugMode) {
273 printDemodBuff(0, false, false, true);
274 printDemodBuff(0, false, false, false);
277 return PM3_SUCCESS;
280 static int CmdAWIDDemod(const char *Cmd) {
281 CLIParserContext *ctx;
282 CLIParserInit(&ctx, "lf awid demod",
283 "Try to find AWID Prox preamble, if found decode / descramble data",
284 "lf awid demod"
287 void *argtable[] = {
288 arg_param_begin,
289 arg_param_end
291 CLIExecWithReturn(ctx, Cmd, argtable, true);
292 CLIParserFree(ctx);
293 return demodAWID(true);
296 // this read is the "normal" read, which download lf signal and tries to demod here.
297 static int CmdAWIDReader(const char *Cmd) {
298 CLIParserContext *ctx;
299 CLIParserInit(&ctx, "lf awid reader",
300 "read a AWID Prox tag",
301 "lf awid reader -@ -> continuous reader mode"
304 void *argtable[] = {
305 arg_param_begin,
306 arg_lit0("@", NULL, "optional - continuous reader mode"),
307 arg_param_end
309 CLIExecWithReturn(ctx, Cmd, argtable, true);
310 bool cm = arg_get_lit(ctx, 1);
311 CLIParserFree(ctx);
313 if (cm) {
314 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
317 do {
318 lf_read(false, 12000);
319 demodAWID(!cm);
320 } while (cm && !kbd_enter_pressed());
322 return PM3_SUCCESS;
325 static int CmdAWIDClone(const char *Cmd) {
327 CLIParserContext *ctx;
328 CLIParserInit(&ctx, "lf awid clone",
329 "clone a AWID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag",
330 "lf awid clone --fmt 26 --fc 123 --cn 1337\n"
331 "lf awid clone --fmt 50 --fc 2001 --cn 13371337\n"
332 "lf awid clone --q5 --fmt 26 --fc 123 --cn 1337 -> encode for Q5/T5555 tag\n"
333 "lf awid clone --em --fmt 26 --fc 123 --cn 1337 -> encode for EM4305/4469"
336 void *argtable[] = {
337 arg_param_begin,
338 arg_u64_1(NULL, "fmt", "<dec>", "format length 26|34|37|50"),
339 arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
340 arg_u64_1(NULL, "cn", "<dec>", "16|32-bit value card number"),
341 arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
342 arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
343 arg_param_end
345 CLIExecWithReturn(ctx, Cmd, argtable, false);
347 uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
348 uint32_t fc = arg_get_u32_def(ctx, 2, 0);
349 uint32_t cn = arg_get_u32_def(ctx, 3, 0);
350 bool q5 = arg_get_lit(ctx, 4);
351 bool em = arg_get_lit(ctx, 5);
352 CLIParserFree(ctx);
354 if (q5 && em) {
355 PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
356 return PM3_EINVARG;
359 uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
360 char cardtype[16] = {"T55x7"};
361 // Q5
362 if (q5) {
363 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
364 blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
365 snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
368 // EM4305
369 if (em) {
370 blocks[0] = EM4305_AWID_CONFIG_BLOCK;
371 snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
374 verify_values(&fmtlen, &fc, &cn);
376 uint8_t *bits = calloc(96, sizeof(uint8_t));
378 if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
379 PrintAndLogEx(ERR, "Error with tag bitstream generation.");
380 free(bits);
381 return PM3_ESOFT;
384 blocks[1] = bytebits_to_byte(bits, 32);
385 blocks[2] = bytebits_to_byte(bits + 32, 32);
386 blocks[3] = bytebits_to_byte(bits + 64, 32);
388 free(bits);
390 PrintAndLogEx(INFO, "Preparing to clone AWID %u to " _YELLOW_("%s") " with FC: " _GREEN_("%u") " CN: " _GREEN_("%u"), fmtlen, cardtype, fc, cn);
391 print_blocks(blocks, ARRAYLEN(blocks));
393 int res;
394 if (em) {
395 res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
396 } else {
397 res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
399 PrintAndLogEx(SUCCESS, "Done");
400 PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid reader`") " to verify");
401 return res;
404 static int CmdAWIDSim(const char *Cmd) {
406 CLIParserContext *ctx;
407 CLIParserInit(&ctx, "lf awid sim",
408 "Enables simulation of AWID card with specified facility-code and card number.\n"
409 "Simulation runs until the button is pressed or another USB command is issued.",
410 "lf awid sim --fmt 26 --fc 123 --cn 1337\n"
411 "lf awid sim --fmt 50 --fc 2001 --cn 13371337"
414 void *argtable[] = {
415 arg_param_begin,
416 arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
417 arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
418 arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
419 arg_param_end
421 CLIExecWithReturn(ctx, Cmd, argtable, false);
423 uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
424 uint32_t fc = arg_get_u32_def(ctx, 2, 0);
425 uint32_t cn = arg_get_u32_def(ctx, 3, 0);
426 CLIParserFree(ctx);
428 uint8_t bs[96];
429 memset(bs, 0x00, sizeof(bs));
431 verify_values(&fmtlen, &fc, &cn);
433 if (getAWIDBits(fmtlen, fc, cn, bs) != PM3_SUCCESS) {
434 PrintAndLogEx(ERR, "Error with tag bitstream generation.");
435 return PM3_ESOFT;
438 PrintAndLogEx(SUCCESS, "Simulating "_YELLOW_("AWID %u") " -- FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fmtlen, fc, cn);
440 // AWID uses: FSK2a fcHigh: 10, fcLow: 8, clk: 50, invert: 1
441 // arg1 --- fcHigh<<8 + fcLow
442 // arg2 --- Inversion and clk setting
443 // 96 --- Bitstream length: 96-bits == 12 bytes
444 lf_fsksim_t *payload = calloc(1, sizeof(lf_fsksim_t) + sizeof(bs));
445 payload->fchigh = 10;
446 payload->fclow = 8;
447 payload->separator = 1;
448 payload->clock = 50;
449 memcpy(payload->data, bs, sizeof(bs));
451 clearCommandBuffer();
452 SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs));
453 free(payload);
455 return lfsim_wait_check(CMD_LF_FSK_SIMULATE);
458 static int CmdAWIDBrute(const char *Cmd) {
459 CLIParserContext *ctx;
460 CLIParserInit(&ctx, "lf awid brute",
461 "Enables bruteforce of AWID reader with specified facility-code.\n"
462 "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
463 "if cardnumber is not given, it starts with 1 and goes up to 65535",
464 "lf awid brute --fmt 26 --fc 224\n"
465 "lf awid brute --fmt 50 --fc 2001 --delay 2000\n"
466 "lf awid brute --fmt 50 --fc 2001 --cn 200 --delay 2000 -v"
469 void *argtable[] = {
470 arg_param_begin,
471 arg_u64_1(NULL, "fmt", "<dec>", "format length 26|50"),
472 arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
473 arg_u64_0(NULL, "cn", "<dec>", "optional - card number to start with, max 65535"),
474 arg_u64_0(NULL, "delay", "<dec>", "optional - delay betweens attempts in ms. Default 1000ms"),
475 arg_lit0("v", "verbose", "verbose logging, show all tries"),
476 arg_param_end
478 CLIExecWithReturn(ctx, Cmd, argtable, false);
480 uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
481 uint32_t fc = arg_get_u32_def(ctx, 2, 0);
482 uint32_t cn = arg_get_u32_def(ctx, 3, 0);
483 uint32_t delay = arg_get_u32_def(ctx, 4, 1000);
484 bool verbose = arg_get_lit(ctx, 5);
485 CLIParserFree(ctx);
487 // limit fc according to selected format
488 switch (fmtlen) {
489 case 50:
490 if ((fc & 0xFFFF) != fc) {
491 fc &= 0xFFFF;
492 PrintAndLogEx(INFO, "Facility-code truncated to 16-bits (AWID50): %u", fc);
494 break;
495 default:
496 if ((fc & 0xFF) != fc) {
497 fc &= 0xFF;
498 PrintAndLogEx(INFO, "Facility-code truncated to 8-bits (AWID26): %u", fc);
500 break;
504 // truncate card number
505 if ((cn & 0xFFFF) != cn) {
506 cn &= 0xFFFF;
507 PrintAndLogEx(INFO, "Card number truncated to 16-bits : %u", cn);
510 PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d reader", fmtlen);
511 PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or press Enter");
513 uint16_t up = cn;
514 uint16_t down = cn;
516 uint8_t bits[96];
517 size_t size = sizeof(bits);
518 memset(bits, 0x00, size);
520 // main loop
521 for (;;) {
523 if (!session.pm3_present) {
524 PrintAndLogEx(WARNING, "Device offline\n");
525 return PM3_ENODATA;
527 if (kbd_enter_pressed()) {
528 PrintAndLogEx(WARNING, "aborted via keyboard!");
529 return sendPing();
532 // Do one up
533 if (up < 0xFFFF) {
534 if (sendTry(fmtlen, fc, up++, delay, bits, size, verbose) != PM3_SUCCESS) {
535 return PM3_ESOFT;
539 // Do one down (if cardnumber is given)
540 if (cn > 1) {
541 if (down > 1) {
542 if (sendTry(fmtlen, fc, --down, delay, bits, size, verbose) != PM3_SUCCESS) {
543 return PM3_ESOFT;
548 return PM3_SUCCESS;
551 static command_t CommandTable[] = {
552 {"help", CmdHelp, AlwaysAvailable, "this help"},
553 {"demod", CmdAWIDDemod, AlwaysAvailable, "demodulate an AWID FSK tag from the GraphBuffer"},
554 {"reader", CmdAWIDReader, IfPm3Lf, "attempt to read and extract tag data"},
555 {"clone", CmdAWIDClone, IfPm3Lf, "clone AWID tag to T55x7 or Q5/T5555"},
556 {"sim", CmdAWIDSim, IfPm3Lf, "simulate AWID tag"},
557 {"brute", CmdAWIDBrute, IfPm3Lf, "bruteforce card number against reader"},
558 {"watch", CmdAWIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
559 {NULL, NULL, NULL, NULL}
562 static int CmdHelp(const char *Cmd) {
563 (void)Cmd; // Cmd is not used so far
564 CmdsHelp(CommandTable);
565 return PM3_SUCCESS;
568 int CmdLFAWID(const char *Cmd) {
569 clearCommandBuffer();
570 return CmdsParse(CommandTable, Cmd);
573 //refactored by marshmellow
574 int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
576 // the return bits, preamble 0000 0001
577 bits[7] = 1;
579 uint8_t pre[66];
580 memset(pre, 0, sizeof(pre));
582 // add formatlength
583 num_to_bytebits(fmtlen, 8, pre);
585 // add facilitycode, cardnumber and wiegand parity bits
586 switch (fmtlen) {
587 case 26: {
588 uint8_t wiegand[24];
589 num_to_bytebits(fc, 8, wiegand);
590 num_to_bytebits(cn, 16, wiegand + 8);
591 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
592 break;
594 case 34: {
595 uint8_t wiegand[32];
596 num_to_bytebits(fc, 8, wiegand);
597 num_to_bytebits(cn, 24, wiegand + 8);
598 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
599 break;
601 case 37: {
602 uint8_t wiegand[31];
603 num_to_bytebits(fc, 13, wiegand);
604 num_to_bytebits(cn, 18, wiegand + 13);
605 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
606 break;
608 case 50: {
609 uint8_t wiegand[48];
610 num_to_bytebits(fc, 16, wiegand);
611 num_to_bytebits(cn, 32, wiegand + 16);
612 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
613 break;
617 // add AWID 4bit parity
618 size_t bitLen = addParity(pre, bits + 8, 66, 4, 1);
620 if (bitLen != 88)
621 return PM3_ESOFT;
623 PrintAndLogEx(DEBUG, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen));
625 return PM3_SUCCESS;