Merge pull request #2654 from Antiklesys/master
[RRG-proxmark3.git] / client / src / cmdlfawid.c
blob07504195a900728e4133427b0e50943dbe6d6987
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Low frequency AWID26/50 commands
17 // FSK2a, RF/50, 96 bits (complete)
18 //-----------------------------------------------------------------------------
19 #include "cmdlfawid.h" // AWID function declarations
20 #include <ctype.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "commonutil.h" // ARRAYLEN
24 #include "cmdparser.h" // command_t
25 #include "comms.h"
26 #include "graph.h"
27 #include "cmddata.h"
28 #include "ui.h" // PrintAndLog
29 #include "lfdemod.h" // parityTest
30 #include "cmdlf.h" // lf read
31 #include "protocols.h" // for T55xx config register definitions
32 #include "util_posix.h"
33 #include "cmdlft55xx.h" // verifywrite
34 #include "cliparser.h"
35 #include "cmdlfem4x05.h" // EM defines
37 static int CmdHelp(const char *Cmd);
39 static int sendPing(void) {
40 SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
41 SendCommandNG(CMD_PING, NULL, 0);
42 clearCommandBuffer();
43 PacketResponseNG resp;
44 if (WaitForResponseTimeout(CMD_PING, &resp, 1000) == false) {
45 return PM3_ETIMEOUT;
47 return PM3_SUCCESS;
50 static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, size_t bs_len, bool verbose) {
52 if (verbose) {
53 PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fc, cn);
56 if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
57 PrintAndLogEx(ERR, "Error with tag bitstream generation.");
58 return PM3_ESOFT;
61 lf_fsksim_t *payload = calloc(1, sizeof(lf_fsksim_t) + bs_len);
62 payload->fchigh = 10;
63 payload->fclow = 8;
64 payload->separator = 1;
65 payload->clock = 50;
66 memcpy(payload->data, bits, bs_len);
68 clearCommandBuffer();
69 SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + bs_len);
70 free(payload);
72 msleep(delay);
73 return sendPing();
76 static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
77 switch (*fmtlen) {
78 case 50:
79 if ((*fc & 0xFFFF) != *fc) {
80 *fc &= 0xFFFF;
81 PrintAndLogEx(INFO, "Facility-Code Truncated to 16-bits (AWID50): %u", *fc);
83 break;
84 case 37:
85 if ((*fc & 0x1FFF) != *fc) {
86 *fc &= 0x1FFF;
87 PrintAndLogEx(INFO, "Facility-Code Truncated to 13-bits (AWID37): %u", *fc);
89 if ((*cn & 0x3FFFF) != *cn) {
90 *cn &= 0x3FFFF;
91 PrintAndLogEx(INFO, "Card Number Truncated to 18-bits (AWID37): %u", *cn);
93 break;
94 case 34:
95 if ((*fc & 0xFF) != *fc) {
96 *fc &= 0xFF;
97 PrintAndLogEx(INFO, "Facility-Code Truncated to 8-bits (AWID34): %u", *fc);
99 if ((*cn & 0xFFFFFF) != *cn) {
100 *cn &= 0xFFFFFF;
101 PrintAndLogEx(INFO, "Card Number Truncated to 24-bits (AWID34): %u", *cn);
103 break;
104 case 26:
105 default:
106 *fmtlen = 26;
107 if ((*fc & 0xFF) != *fc) {
108 *fc &= 0xFF;
109 PrintAndLogEx(INFO, "Facility-Code Truncated to 8-bits (AWID26): %u", *fc);
111 if ((*cn & 0xFFFF) != *cn) {
112 *cn &= 0xFFFF;
113 PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (AWID26): %u", *cn);
115 break;
119 // this read loops on device side.
120 // uses the demod in lfops.c
121 static int CmdAWIDWatch(const char *Cmd) {
122 CLIParserContext *ctx;
123 CLIParserInit(&ctx, "lf awid watch",
124 "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.\n"
125 "Run until the button is pressed or another USB command is issued.",
126 "lf awid watch"
129 void *argtable[] = {
130 arg_param_begin,
131 arg_param_end
133 CLIExecWithReturn(ctx, Cmd, argtable, true);
134 CLIParserFree(ctx);
136 PrintAndLogEx(SUCCESS, "Watching for AWID cards - place tag on antenna");
137 PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " to stop reading cards");
138 clearCommandBuffer();
139 SendCommandNG(CMD_LF_AWID_WATCH, NULL, 0);
140 return lfsim_wait_check(CMD_LF_AWID_WATCH);
143 //by marshmellow
144 //AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
145 //print full AWID Prox ID and some bit format details if found
146 int demodAWID(bool verbose) {
147 (void) verbose; // unused so far
148 uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
149 if (bits == NULL) {
150 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID failed to allocate memory");
151 return PM3_EMALLOC;
154 size_t size = getFromGraphBuffer(bits);
155 if (size == 0) {
156 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID not enough samples");
157 free(bits);
158 return PM3_ENODATA;
160 //get binary from fsk wave
161 int waveIdx = 0;
162 int idx = detectAWID(bits, &size, &waveIdx);
163 if (idx <= 0) {
165 if (idx == -1)
166 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID not enough samples");
167 else if (idx == -2)
168 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID only noise found");
169 else if (idx == -3)
170 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID problem during FSK demod");
171 else if (idx == -4)
172 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID preamble not found");
173 else if (idx == -5)
174 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID size not correct, size %zu", size);
175 else
176 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID error demoding fsk %d", idx);
178 free(bits);
179 return PM3_ESOFT;
182 setDemodBuff(bits, size, idx);
183 setClockGrid(50, waveIdx + (idx * 50));
186 // Index map
187 // 0 10 20 30 40 50 60
188 // | | | | | | |
189 // 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
190 // -----------------------------------------------------------------------------
191 // 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
192 // 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
193 // |---26 bit---| |-----117----||-------------142-------------|
194 // b = format bit len, o = odd parity of last 3 bits
195 // f = facility code, c = card number
196 // w = wiegand parity
197 // (26 bit format shown)
199 //get raw ID before removing parities
200 uint32_t rawLo = bytebits_to_byte(bits + idx + 64, 32);
201 uint32_t rawHi = bytebits_to_byte(bits + idx + 32, 32);
202 uint32_t rawHi2 = bytebits_to_byte(bits + idx, 32);
204 size = removeParity(bits, idx + 8, 4, 1, 88);
205 if (size != 66) {
206 PrintAndLogEx(DEBUG, "DEBUG: Error - AWID at parity check-tag size does not match AWID format");
207 free(bits);
208 return PM3_ESOFT;
211 char binstr[68] = {0};
212 binarray_2_binstr(binstr, (char *)bits, size);
213 PrintAndLogEx(DEBUG, "no parity... %s", binstr);
215 // ok valid card found!
217 // Index map
218 // 0 10 20 30 40 50 60
219 // | | | | | | |
220 // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
221 // -----------------------------------------------------------------------------
222 // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
223 // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
224 // |26 bit| |-117--| |-----142------|
226 // 00110010 0 0000111110100000 00000000000100010010100010000111 1 000000000
227 // bbbbbbbb w ffffffffffffffff cccccccccccccccccccccccccccccccc w xxxxxxxxx
228 // |50 bit| |----4000------| |-----------2248975------------|
229 // b = format bit len, o = odd parity of last 3 bits
230 // f = facility code, c = card number
231 // w = wiegand parity
233 uint32_t fc = 0;
234 uint32_t cardnum = 0;
235 uint32_t code1 = 0;
236 uint32_t code2 = 0;
237 uint8_t fmtLen = bytebits_to_byte(bits, 8);
239 switch (fmtLen) {
240 case 26: {
241 fc = bytebits_to_byte(bits + 9, 8);
242 cardnum = bytebits_to_byte(bits + 17, 16);
243 code1 = bytebits_to_byte(bits + 8, fmtLen);
244 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);
245 break;
247 case 34: {
248 fc = bytebits_to_byte(bits + 9, 8);
249 cardnum = bytebits_to_byte(bits + 17, 24);
250 code1 = bytebits_to_byte(bits + 8, (fmtLen - 32));
251 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
252 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);
253 break;
255 case 36: {
256 fc = bytebits_to_byte(bits + 14, 11);
257 cardnum = bytebits_to_byte(bits + 25, 18);
258 code1 = bytebits_to_byte(bits + 8, (fmtLen - 32));
259 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
260 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);
261 break;
263 case 37: {
264 fc = bytebits_to_byte(bits + 9, 13);
265 cardnum = bytebits_to_byte(bits + 22, 18);
266 code1 = bytebits_to_byte(bits + 8, (fmtLen - 32));
267 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
268 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);
269 break;
271 // case 40:
272 // break;
273 case 50: {
274 fc = bytebits_to_byte(bits + 9, 16);
275 cardnum = bytebits_to_byte(bits + 25, 32);
276 code1 = bytebits_to_byte(bits + 8, (fmtLen - 32));
277 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
278 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);
279 break;
281 default:
282 if (fmtLen > 32) {
283 cardnum = bytebits_to_byte(bits + 8 + (fmtLen - 17), 16);
284 code1 = bytebits_to_byte(bits + 8, fmtLen - 32);
285 code2 = bytebits_to_byte(bits + 8 + (fmtLen - 32), 32);
286 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d") " -unknown- (%u) - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
287 } else {
288 cardnum = bytebits_to_byte(bits + 8 + (fmtLen - 17), 16);
289 code1 = bytebits_to_byte(bits + 8, fmtLen);
290 PrintAndLogEx(SUCCESS, "AWID - len: " _GREEN_("%d") " -unknown- (%u) - Wiegand: " _GREEN_("%x") ", Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
292 break;
294 free(bits);
296 PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %zu", idx, size);
297 PrintAndLogEx(DEBUG, "DEBUG: Printing DemodBuffer:");
298 if (g_debugMode) {
299 printDemodBuff(0, false, false, true);
300 printDemodBuff(0, false, false, false);
303 return PM3_SUCCESS;
306 static int CmdAWIDDemod(const char *Cmd) {
307 CLIParserContext *ctx;
308 CLIParserInit(&ctx, "lf awid demod",
309 "Try to find AWID Prox preamble, if found decode / descramble data",
310 "lf awid demod\n"
311 "lf awid demod --raw "
315 void *argtable[] = {
316 arg_param_begin,
317 arg_param_end
319 CLIExecWithReturn(ctx, Cmd, argtable, true);
320 CLIParserFree(ctx);
321 return demodAWID(true);
324 // this read is the "normal" read, which download lf signal and tries to demod here.
325 static int CmdAWIDReader(const char *Cmd) {
326 CLIParserContext *ctx;
327 CLIParserInit(&ctx, "lf awid reader",
328 "read a AWID Prox tag",
329 "lf awid reader -@ -> continuous reader mode"
332 void *argtable[] = {
333 arg_param_begin,
334 arg_lit0("@", NULL, "optional - continuous reader mode"),
335 arg_param_end
337 CLIExecWithReturn(ctx, Cmd, argtable, true);
338 bool cm = arg_get_lit(ctx, 1);
339 CLIParserFree(ctx);
341 if (cm) {
342 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
345 do {
346 lf_read(false, 12000);
347 demodAWID(!cm);
348 } while (cm && !kbd_enter_pressed());
350 return PM3_SUCCESS;
353 static int CmdAWIDClone(const char *Cmd) {
355 CLIParserContext *ctx;
356 CLIParserInit(&ctx, "lf awid clone",
357 "clone a AWID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag",
358 "lf awid clone --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag\n"
359 "lf awid clone --fmt 50 --fc 2001 --cn 13371337 -> encode long fmt for T55x7 tag\n"
360 "lf awid clone --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag\n"
361 "lf awid clone --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469"
364 void *argtable[] = {
365 arg_param_begin,
366 arg_u64_1(NULL, "fmt", "<dec>", "format length 26|34|37|50"),
367 arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
368 arg_u64_1(NULL, "cn", "<dec>", "16|32-bit value card number"),
369 arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
370 arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
371 arg_param_end
373 CLIExecWithReturn(ctx, Cmd, argtable, false);
375 uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
376 uint32_t fc = arg_get_u32_def(ctx, 2, 0);
377 uint32_t cn = arg_get_u32_def(ctx, 3, 0);
378 bool q5 = arg_get_lit(ctx, 4);
379 bool em = arg_get_lit(ctx, 5);
380 CLIParserFree(ctx);
382 if (q5 && em) {
383 PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
384 return PM3_EINVARG;
387 uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
388 char cardtype[16] = {"T55x7"};
389 // Q5
390 if (q5) {
391 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
392 blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
393 snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
396 // EM4305
397 if (em) {
398 PrintAndLogEx(WARNING, "Beware some EM4305 tags don't support FSK and datarate = RF/50, check your tag copy!");
399 blocks[0] = EM4305_AWID_CONFIG_BLOCK;
400 snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
403 verify_values(&fmtlen, &fc, &cn);
405 uint8_t *bits = calloc(96, sizeof(uint8_t));
407 if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
408 PrintAndLogEx(ERR, "Error with tag bitstream generation.");
409 free(bits);
410 return PM3_ESOFT;
413 blocks[1] = bytebits_to_byte(bits, 32);
414 blocks[2] = bytebits_to_byte(bits + 32, 32);
415 blocks[3] = bytebits_to_byte(bits + 64, 32);
417 // EM4305
418 if (em) {
419 // invert FSK data
420 for (uint8_t i = 1; i < ARRAYLEN(blocks) ; i++) {
421 blocks[i] = blocks[i] ^ 0xFFFFFFFF;
425 free(bits);
427 PrintAndLogEx(INFO, "Preparing to clone AWID %u to " _YELLOW_("%s") " with FC: " _GREEN_("%u") " CN: " _GREEN_("%u"), fmtlen, cardtype, fc, cn);
428 print_blocks(blocks, ARRAYLEN(blocks));
430 int res;
431 if (em) {
432 res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
433 } else {
434 res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
436 PrintAndLogEx(SUCCESS, "Done!");
437 PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid reader`") " to verify");
438 return res;
441 static int CmdAWIDSim(const char *Cmd) {
443 CLIParserContext *ctx;
444 CLIParserInit(&ctx, "lf awid sim",
445 "Enables simulation of AWID card with specified facility-code and card number.\n"
446 "Simulation runs until the button is pressed or another USB command is issued.",
447 "lf awid sim --fmt 26 --fc 123 --cn 1337\n"
448 "lf awid sim --fmt 50 --fc 2001 --cn 13371337"
451 void *argtable[] = {
452 arg_param_begin,
453 arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
454 arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
455 arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
456 arg_param_end
458 CLIExecWithReturn(ctx, Cmd, argtable, false);
460 uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
461 uint32_t fc = arg_get_u32_def(ctx, 2, 0);
462 uint32_t cn = arg_get_u32_def(ctx, 3, 0);
463 CLIParserFree(ctx);
465 uint8_t bs[96];
466 memset(bs, 0x00, sizeof(bs));
468 verify_values(&fmtlen, &fc, &cn);
470 if (getAWIDBits(fmtlen, fc, cn, bs) != PM3_SUCCESS) {
471 PrintAndLogEx(ERR, "Error with tag bitstream generation.");
472 return PM3_ESOFT;
475 PrintAndLogEx(SUCCESS, "Simulating "_YELLOW_("AWID %u") " -- FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fmtlen, fc, cn);
477 // AWID uses: FSK2a fcHigh: 10, fcLow: 8, clk: 50, invert: 1
478 // arg1 --- fcHigh<<8 + fcLow
479 // arg2 --- Inversion and clk setting
480 // 96 --- Bitstream length: 96-bits == 12 bytes
481 lf_fsksim_t *payload = calloc(1, sizeof(lf_fsksim_t) + sizeof(bs));
482 payload->fchigh = 10;
483 payload->fclow = 8;
484 payload->separator = 1;
485 payload->clock = 50;
486 memcpy(payload->data, bs, sizeof(bs));
488 clearCommandBuffer();
489 SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs));
490 free(payload);
492 return lfsim_wait_check(CMD_LF_FSK_SIMULATE);
495 static int CmdAWIDBrute(const char *Cmd) {
496 CLIParserContext *ctx;
497 CLIParserInit(&ctx, "lf awid brute",
498 "Enables bruteforce of AWID reader with specified facility-code.\n"
499 "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
500 "if cardnumber is not given, it starts with 1 and goes up to 65535",
501 "lf awid brute --fmt 26 --fc 224\n"
502 "lf awid brute --fmt 50 --fc 2001 --delay 2000\n"
503 "lf awid brute --fmt 50 --fc 2001 --cn 200 --delay 2000 -v"
506 void *argtable[] = {
507 arg_param_begin,
508 arg_u64_1(NULL, "fmt", "<dec>", "format length 26|50"),
509 arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
510 arg_u64_0(NULL, "cn", "<dec>", "optional - card number to start with, max 65535"),
511 arg_u64_0(NULL, "delay", "<dec>", "optional - delay betweens attempts in ms. Default 1000ms"),
512 arg_lit0("v", "verbose", "verbose output"),
513 arg_param_end
515 CLIExecWithReturn(ctx, Cmd, argtable, false);
517 uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
518 uint32_t fc = arg_get_u32_def(ctx, 2, 0);
519 uint32_t cn = arg_get_u32_def(ctx, 3, 0);
520 uint32_t delay = arg_get_u32_def(ctx, 4, 1000);
521 bool verbose = arg_get_lit(ctx, 5);
522 CLIParserFree(ctx);
524 // limit fc according to selected format
525 switch (fmtlen) {
526 case 50:
527 if ((fc & 0xFFFF) != fc) {
528 fc &= 0xFFFF;
529 PrintAndLogEx(INFO, "Facility-code truncated to 16-bits (AWID50): %u", fc);
531 break;
532 default:
533 if ((fc & 0xFF) != fc) {
534 fc &= 0xFF;
535 PrintAndLogEx(INFO, "Facility-code truncated to 8-bits (AWID26): %u", fc);
537 break;
541 // truncate card number
542 if ((cn & 0xFFFF) != cn) {
543 cn &= 0xFFFF;
544 PrintAndLogEx(INFO, "Card number truncated to 16-bits : %u", cn);
547 PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d reader", fmtlen);
548 PrintAndLogEx(SUCCESS, "Press " _GREEN_("pm3 button") " or " _GREEN_("<Enter>") " to abort simulation");
550 uint16_t up = cn;
551 uint16_t down = cn;
553 uint8_t bits[96];
554 size_t size = sizeof(bits);
555 memset(bits, 0x00, size);
557 // main loop
558 for (;;) {
560 if (!g_session.pm3_present) {
561 PrintAndLogEx(WARNING, "Device offline\n");
562 return PM3_ENODATA;
564 if (kbd_enter_pressed()) {
565 PrintAndLogEx(WARNING, "aborted via keyboard!");
566 return sendPing();
569 // Do one up
570 if (up < 0xFFFF) {
571 if (sendTry(fmtlen, fc, up++, delay, bits, size, verbose) != PM3_SUCCESS) {
572 return PM3_ESOFT;
576 // Do one down (if cardnumber is given)
577 if (cn > 1) {
578 if (down > 1) {
579 if (sendTry(fmtlen, fc, --down, delay, bits, size, verbose) != PM3_SUCCESS) {
580 return PM3_ESOFT;
585 return PM3_SUCCESS;
588 static command_t CommandTable[] = {
589 {"help", CmdHelp, AlwaysAvailable, "this help"},
590 {"brute", CmdAWIDBrute, IfPm3Lf, "bruteforce card number against reader"},
591 {"clone", CmdAWIDClone, IfPm3Lf, "clone AWID tag to T55x7, Q5/T5555 or EM4305/4469"},
592 {"demod", CmdAWIDDemod, AlwaysAvailable, "demodulate an AWID FSK tag from the GraphBuffer"},
593 {"reader", CmdAWIDReader, IfPm3Lf, "attempt to read and extract tag data"},
594 {"sim", CmdAWIDSim, IfPm3Lf, "simulate AWID tag"},
595 {"brute", CmdAWIDBrute, IfPm3Lf, "bruteforce card number against reader"},
596 {"watch", CmdAWIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
597 {NULL, NULL, NULL, NULL}
600 static int CmdHelp(const char *Cmd) {
601 (void)Cmd; // Cmd is not used so far
602 CmdsHelp(CommandTable);
603 return PM3_SUCCESS;
606 int CmdLFAWID(const char *Cmd) {
607 clearCommandBuffer();
608 return CmdsParse(CommandTable, Cmd);
611 //refactored by marshmellow
612 int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
614 // the return bits, preamble 0000 0001
615 bits[7] = 1;
617 uint8_t pre[66];
618 memset(pre, 0, sizeof(pre));
620 // add formatlength
621 num_to_bytebits(fmtlen, 8, pre);
623 // add facilitycode, cardnumber and wiegand parity bits
624 switch (fmtlen) {
625 case 26: {
626 uint8_t wiegand[24];
627 num_to_bytebits(fc, 8, wiegand);
628 num_to_bytebits(cn, 16, wiegand + 8);
629 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
630 break;
632 case 34: {
633 uint8_t wiegand[32];
634 num_to_bytebits(fc, 8, wiegand);
635 num_to_bytebits(cn, 24, wiegand + 8);
636 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
637 break;
639 case 37: {
640 uint8_t wiegand[31];
641 num_to_bytebits(fc, 13, wiegand);
642 num_to_bytebits(cn, 18, wiegand + 13);
643 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
644 break;
646 case 50: {
647 uint8_t wiegand[48];
648 num_to_bytebits(fc, 16, wiegand);
649 num_to_bytebits(cn, 32, wiegand + 16);
650 wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand));
651 break;
655 // add AWID 4bit parity
656 size_t bitLen = addParity(pre, bits + 8, 66, 4, 1);
658 if (bitLen != 88)
659 return PM3_ESOFT;
661 PrintAndLogEx(DEBUG, "awid raw bits:\n %s \n", sprint_bytebits_bin(bits, bitLen));
663 return PM3_SUCCESS;