1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
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.
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 Honeywell NexWatch tag commands
17 // PSK1 RF/16, RF/2, 128 bits long (known)
18 //-----------------------------------------------------------------------------
20 #include "cmdlfnexwatch.h"
21 #include <inttypes.h> // PRIu
23 #include <ctype.h> // tolower
24 #include <stdlib.h> // free, alloc
25 #include "commonutil.h" // ARRAYLEN
26 #include "cmdparser.h" // command_t
29 #include "cmddata.h" // preamblesearch
32 #include "protocols.h" // t55xx defines
33 #include "cmdlft55xx.h" // clone..
34 #include "cmdlfem4x05.h" //
35 #include "cliparser.h"
44 static int CmdHelp(const char *Cmd
);
46 // scramble parity (1234) -> (4231)
47 static uint8_t nexwatch_parity_swap(uint8_t parity
) {
48 uint8_t a
= (((parity
>> 3) & 1));
49 a
|= (((parity
>> 1) & 1) << 1);
50 a
|= (((parity
>> 2) & 1) << 2);
51 a
|= ((parity
& 1) << 3);
55 // from 32b hex id, 4b mode,
56 static uint8_t nexwatch_parity(const uint8_t hexid
[5]) {
58 for (uint8_t i
= 0; i
< 5; i
++) {
59 p
^= NIBBLE_HIGH(hexid
[i
]);
60 p
^= NIBBLE_LOW(hexid
[i
]);
62 return nexwatch_parity_swap(p
);
66 /// @param magic = 0xBE Quadrakey, 0x88 Nexkey, 0x86 Honeywell
67 /// @param id = descrambled id (printed card number)
68 /// @param parity = the parity based upon the scrambled raw id.
69 static uint8_t nexwatch_checksum(uint8_t magic
, uint32_t id
, uint8_t parity
) {
70 uint8_t a
= ((id
>> 24) & 0xFF);
71 a
-= ((id
>> 16) & 0xFF);
72 a
-= ((id
>> 8) & 0xFF);
75 a
-= (reflect8(parity
) >> 4);
79 // Scrambled id ( 88 bit cardnumber format)
80 // ref:: http://www.proxmark.org/forum/viewtopic.php?pid=14662#p14662
81 static int nexwatch_scamble(NexWatchScramble_t action
, uint32_t *id
, uint32_t *scambled
) {
83 // 255 = Not used/Unknown other values are the bit offset in the ID/FC values
84 const uint8_t hex_2_id
[] = {
85 31, 27, 23, 19, 15, 11, 7, 3,
86 30, 26, 22, 18, 14, 10, 6, 2,
87 29, 25, 21, 17, 13, 9, 5, 1,
88 28, 24, 20, 16, 12, 8, 4, 0
94 for (uint8_t idx
= 0; idx
< 32; idx
++) {
96 if (hex_2_id
[idx
] == 255)
99 bool bit_state
= (*scambled
>> hex_2_id
[idx
]) & 1;
100 *id
|= (bit_state
<< (31 - idx
));
106 for (uint8_t idx
= 0; idx
< 32; idx
++) {
108 if (hex_2_id
[idx
] == 255)
111 bool bit_state
= (*id
>> idx
) & 1;
112 *scambled
|= (bit_state
<< (31 - hex_2_id
[idx
]));
122 static int nexwatch_magic_bruteforce(uint32_t cn
, uint8_t calc_parity
, uint8_t chk
) {
123 for (uint8_t magic
= 0; magic
< 255; magic
++) {
124 uint8_t temp_checksum
;
125 temp_checksum
= nexwatch_checksum(magic
, cn
, calc_parity
);
126 if (temp_checksum
== chk
) {
127 PrintAndLogEx(SUCCESS
, " Magic number : " _GREEN_("0x%X"), magic
);
131 PrintAndLogEx(DEBUG
, "DEBUG: Error - Magic number not found");
136 int demodNexWatch(bool verbose
) {
137 (void) verbose
; // unused so far
138 if (PSKDemod(0, 0, 100, false) != PM3_SUCCESS
) {
139 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch can't demod signal");
143 size_t size
= g_DemodBufferLen
;
144 int idx
= detectNexWatch(g_DemodBuffer
, &size
, &invert
);
147 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch not enough samples");
148 // else if (idx == -2)
149 // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch only noise found");
150 // else if (idx == -3)
151 // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch problem during PSK demod");
153 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch preamble not found");
154 // else if (idx == -5)
155 // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch size not correct: %d", size);
157 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch error %d", idx
);
162 // skip the 4 first bits from the nexwatch preamble identification (we use 4 extra zeros..)
165 setDemodBuff(g_DemodBuffer
, size
, idx
);
166 setClockGrid(g_DemodClock
, g_DemodStartIdx
+ (idx
* g_DemodClock
));
169 PrintAndLogEx(INFO
, "Inverted the demodulated data");
170 for (size_t i
= 0; i
< size
; i
++)
171 g_DemodBuffer
[i
] ^= 1;
175 uint32_t raw1
= bytebits_to_byte(g_DemodBuffer
, 32);
176 uint32_t raw2
= bytebits_to_byte(g_DemodBuffer
+ 32, 32);
177 uint32_t raw3
= bytebits_to_byte(g_DemodBuffer
+ 32 + 32, 32);
181 for (uint8_t k
= 0; k
< 4; k
++) {
182 for (uint8_t m
= 0; m
< 8; m
++) {
183 rawid
= (rawid
<< 1) | g_DemodBuffer
[m
+ k
+ (m
* 4)];
189 uint32_t scambled
= bytebits_to_byte(g_DemodBuffer
+ 8 + 32, 32);
190 nexwatch_scamble(DESCRAMBLE
, &cn
, &scambled
);
192 uint8_t mode
= bytebits_to_byte(g_DemodBuffer
+ 72, 4);
193 uint8_t parity
= bytebits_to_byte(g_DemodBuffer
+ 76, 4);
194 uint8_t chk
= bytebits_to_byte(g_DemodBuffer
+ 80, 8);
197 // from 32b hex id, 4b mode
198 uint8_t hex
[5] = {0};
199 for (uint8_t i
= 0; i
< 5; i
++) {
200 hex
[i
] = bytebits_to_byte(g_DemodBuffer
+ 8 + 32 + (i
* 8), 8);
202 // mode is only 4 bits.
204 uint8_t calc_parity
= nexwatch_parity(hex
);
212 nexwatch_magic_t items
[] = {
213 {0xBE, "Quadrakey", 0},
215 {0x86, "Honeywell", 0}
219 for (m_idx
= 0; m_idx
< ARRAYLEN(items
); m_idx
++) {
221 items
[m_idx
].chk
= nexwatch_checksum(items
[m_idx
].magic
, cn
, calc_parity
);
222 if (items
[m_idx
].chk
== chk
) {
228 PrintAndLogEx(SUCCESS
, " NexWatch raw id : " _YELLOW_("0x%08"PRIx32
), rawid
);
230 if (m_idx
< ARRAYLEN(items
)) {
231 PrintAndLogEx(SUCCESS
, " fingerprint : " _GREEN_("%s"), items
[m_idx
].desc
);
233 nexwatch_magic_bruteforce(cn
, calc_parity
, chk
);
235 PrintAndLogEx(SUCCESS
, " 88bit id : " _YELLOW_("%"PRIu32
) " (" _YELLOW_("0x%08"PRIx32
)")", cn
, cn
);
236 PrintAndLogEx(SUCCESS
, " mode : %x", mode
);
239 if (parity
== calc_parity
) {
240 PrintAndLogEx(DEBUG
, " parity : ( %s ) 0x%X", _GREEN_("ok"), parity
);
242 PrintAndLogEx(DEBUG
, " parity : ( %s ) 0x%X != 0x%X", _RED_("fail"), parity
, calc_parity
);
245 PrintAndLogEx(DEBUG
, " checksum : ( %s ) 0x%02X", (m_idx
< ARRAYLEN(items
)) ? _GREEN_("ok") : _RED_("fail"), chk
);
247 PrintAndLogEx(INFO
, " Raw : " _YELLOW_("%08"PRIX32
"%08"PRIX32
"%08"PRIX32
), raw1
, raw2
, raw3
);
251 static int CmdNexWatchDemod(const char *Cmd
) {
252 CLIParserContext
*ctx
;
253 CLIParserInit(&ctx
, "lf nexwatch demod",
254 "Try to find Nexwatch preamble, if found decode / descramble data",
262 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
264 return demodNexWatch(true);
267 static int CmdNexWatchReader(const char *Cmd
) {
268 CLIParserContext
*ctx
;
269 CLIParserInit(&ctx
, "lf nexwatch reader",
270 "read a Nexwatch tag",
271 "lf nexwatch reader -@ -> continuous reader mode"
276 arg_lit0("@", NULL
, "optional - continuous reader mode"),
279 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
280 bool cm
= arg_get_lit(ctx
, 1);
284 PrintAndLogEx(INFO
, "Press " _GREEN_("<Enter>") " to exit");
288 lf_read(false, 20000);
290 } while (cm
&& !kbd_enter_pressed());
294 static int CmdNexWatchClone(const char *Cmd
) {
295 CLIParserContext
*ctx
;
296 CLIParserInit(&ctx
, "lf nexwatch clone",
297 "clone a Nexwatch tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
298 "You can use raw hex values or create a credential based on id, mode\n"
299 "and type of credential (Nexkey / Quadrakey / Russian)",
300 "lf nexwatch clone --raw 5600000000213C9F8F150C00\n"
301 "lf nexwatch clone --cn 521512301 -m 1 --nc -> Nexkey credential\n"
302 "lf nexwatch clone --cn 521512301 -m 1 --qc -> Quadrakey credential\n"
303 "lf nexwatch clone --cn 521512301 -m 1 --hc -> Honeywell credential\n"
308 arg_str0("r", "raw", "<hex>", "raw hex data. 12 bytes"),
309 arg_u64_0(NULL
, "cn", "<dec>", "card id"),
310 arg_u64_0("m", "mode", "<dec>", "mode (decimal) (0-15, defaults to 1)"),
311 arg_lit0(NULL
, "nc", "Nexkey credential"),
312 arg_lit0(NULL
, "qc", "Quadrakey credential"),
313 arg_lit0(NULL
, "hc", "Honeywell credential"),
314 arg_lit0(NULL
, "q5", "optional - specify writing to Q5/T5555 tag"),
315 arg_lit0(NULL
, "em", "optional - specify writing to EM4305/4469 tag"),
316 arg_str0(NULL
, "magic", "<hex>", "optional - magic hex data. 1 byte"),
317 arg_lit0(NULL
, "psk2", "optional - specify writing a tag in psk2 modulation"),
320 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
323 // skip first block, 3*4 = 12 bytes left
324 uint8_t raw
[12] = {0x56, 0};
325 CLIGetHexWithReturn(ctx
, 1, raw
, &raw_len
);
327 uint32_t cn
= arg_get_u32_def(ctx
, 2, -1);
328 uint32_t mode
= arg_get_u32_def(ctx
, 3, -1);
329 bool use_nexkey
= arg_get_lit(ctx
, 4);
330 bool use_quadrakey
= arg_get_lit(ctx
, 5);
331 bool use_honeywell
= arg_get_lit(ctx
, 6);
332 bool q5
= arg_get_lit(ctx
, 7);
333 bool em
= arg_get_lit(ctx
, 8);
335 uint8_t magic_arg
[2];
337 CLIGetHexWithReturn(ctx
, 9, magic_arg
, &mlen
);
339 bool use_psk2
= arg_get_lit(ctx
, 10);
343 if (use_nexkey
&& use_quadrakey
) {
344 PrintAndLogEx(FAILED
, "Can't specify both Nexkey and Quadrakey at the same time");
349 PrintAndLogEx(FAILED
, "Can't specify both Q5 and EM4305 at the same time");
353 // 56000000 00213C9F 8F150C00
354 bool use_raw
= (raw_len
!= 0);
356 bool use_custom_magic
= (mlen
!= 0);
359 PrintAndLogEx(FAILED
, "Can't specify a magic number bigger than one byte");
363 if (use_raw
&& cn
!= -1) {
364 PrintAndLogEx(FAILED
, "Can't specify both Raw and Card id at the same time");
370 nexwatch_scamble(SCRAMBLE
, &cn
, &scrambled
);
371 num_to_bytes(scrambled
, 4, raw
+ 5);
379 raw
[9] |= (mode
<< 4);
382 uint8_t magic
= 0xBE;
383 if (use_custom_magic
) {
384 magic
= magic_arg
[0];
396 PrintAndLogEx(INFO
, "Magic byte selected... " _YELLOW_("0x%X"), magic
);
400 //Nexwatch - compat mode, PSK, data rate 40, 3 data blocks
401 blocks
[0] = T55x7_MODULATION_PSK1
| T55x7_BITRATE_RF_32
| 3 << T55x7_MAXBLOCK_SHIFT
;
402 char cardtype
[16] = {"T55x7"};
406 blocks
[0] = T5555_FIXED
| T5555_MODULATION_MANCHESTER
| T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR
| 3 << T5555_MAXBLOCK_SHIFT
;
407 snprintf(cardtype
, sizeof(cardtype
), "Q5/T5555");
412 blocks
[0] = EM4305_NEXWATCH_CONFIG_BLOCK
;
413 snprintf(cardtype
, sizeof(cardtype
), "EM4305/4469");
416 if (use_raw
== false) {
417 uint8_t parity
= nexwatch_parity(raw
+ 5) & 0xF;
419 raw
[10] |= nexwatch_checksum(magic
, cn
, parity
);
423 blocks
[0] = 0x00042080;
425 uint8_t *res_shifted
= calloc(96, sizeof(uint8_t));
426 uint8_t *res
= calloc(96, sizeof(uint8_t));
428 bytes_to_bytebits(raw
, 12, res
);
430 memcpy(res_shifted
, &res
[1], 95 * sizeof(uint8_t));
432 bits_to_array(res_shifted
, 96, raw
);
437 for (uint8_t i
= 1; i
< ARRAYLEN(blocks
); i
++) {
438 blocks
[i
] = bytes_to_num(raw
+ ((i
- 1) * 4), sizeof(uint32_t));
441 PrintAndLogEx(INFO
, "Preparing to clone NexWatch to " _YELLOW_("%s") " raw " _YELLOW_("%s"), cardtype
, sprint_hex_inrow(raw
, sizeof(raw
)));
442 print_blocks(blocks
, ARRAYLEN(blocks
));
446 res
= em4x05_clone_tag(blocks
, ARRAYLEN(blocks
), 0, false);
448 res
= clone_t55xx_tag(blocks
, ARRAYLEN(blocks
));
450 PrintAndLogEx(SUCCESS
, "Done!");
451 PrintAndLogEx(HINT
, "Hint: try " _YELLOW_("`lf nexwatch reader`") " to verify");
455 static int CmdNexWatchSim(const char *Cmd
) {
457 CLIParserContext
*ctx
;
458 CLIParserInit(&ctx
, "lf nexwatch sim",
459 "Enables simulation of secura card with specified card number.\n"
460 "Simulation runs until the button is pressed or another USB command is issued.\n"
461 "You can use raw hex values or create a credential based on id, mode\n"
462 "and type of credential (Nexkey/Quadrakey)",
463 "lf nexwatch sim --raw 5600000000213C9F8F150C00\n"
464 "lf nexwatch sim --cn 521512301 -m 1 --nc -> Nexkey credential\n"
465 "lf nexwatch sim --cn 521512301 -m 1 --qc -> Quadrakey credential\n"
466 "lf nexwatch sim --cn 521512301 -m 1 --hc -> Honeywell credential\n"
471 arg_str0("r", "raw", "<hex>", "raw hex data. 12 bytes"),
472 arg_u64_0(NULL
, "cn", "<dec>", "card id"),
473 arg_u64_0("m", "mode", "<dec>", "mode (decimal) (0-15, defaults to 1)"),
474 arg_lit0(NULL
, "nc", "Nexkey credential"),
475 arg_lit0(NULL
, "qc", "Quadrakey credential"),
476 arg_lit0(NULL
, "hc", "Honeywell credential"),
477 arg_str0(NULL
, "magic", "<hex>", "optional - magic hex data. 1 byte"),
478 arg_lit0(NULL
, "psk2", "optional - specify writing a tag in psk2 modulation"),
481 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
484 // skip first block, 3*4 = 12 bytes left
485 uint8_t raw
[12] = {0x56, 0};
486 CLIGetHexWithReturn(ctx
, 1, raw
, &raw_len
);
488 uint32_t cn
= arg_get_u32_def(ctx
, 2, -1);
489 uint32_t mode
= arg_get_u32_def(ctx
, 3, -1);
490 bool use_nexkey
= arg_get_lit(ctx
, 4);
491 bool use_quadrakey
= arg_get_lit(ctx
, 5);
492 bool use_unk
= arg_get_lit(ctx
, 6);
495 if (use_nexkey
&& use_quadrakey
) {
496 PrintAndLogEx(FAILED
, "Can't specify both Nexkey and Quadrakey at the same time");
500 bool use_raw
= (raw_len
!= 0);
502 if (use_raw
&& cn
!= -1) {
503 PrintAndLogEx(FAILED
, "Can't specify both Raw and Card id at the same time");
509 nexwatch_scamble(SCRAMBLE
, &cn
, &scrambled
);
510 num_to_bytes(scrambled
, 4, raw
+ 5);
518 raw
[9] |= (mode
<< 4);
521 uint8_t magic
= 0xBE;
531 if (use_raw
== false) {
532 uint8_t parity
= nexwatch_parity(raw
+ 5) & 0xF;
534 raw
[10] |= nexwatch_checksum(magic
, cn
, parity
);
538 memset(bs
, 0, sizeof(bs
));
540 // hex to bits. (3 * 32 == 96)
541 for (size_t i
= 0; i
< 3; i
++) {
542 uint32_t tmp
= bytes_to_num(raw
+ (i
* sizeof(uint32_t)), sizeof(uint32_t));
543 num_to_bytebits(tmp
, sizeof(uint32_t) * 8, bs
+ (i
* sizeof(uint32_t) * 8));
546 PrintAndLogEx(SUCCESS
, "Simulating NexWatch - raw " _YELLOW_("%s"), sprint_hex_inrow(raw
, sizeof(raw
)));
548 lf_psksim_t
*payload
= calloc(1, sizeof(lf_psksim_t
) + sizeof(bs
));
549 payload
->carrier
= 2;
552 memcpy(payload
->data
, bs
, sizeof(bs
));
554 clearCommandBuffer();
555 SendCommandNG(CMD_LF_PSK_SIMULATE
, (uint8_t *)payload
, sizeof(lf_psksim_t
) + sizeof(bs
));
558 PacketResponseNG resp
;
559 WaitForResponse(CMD_LF_PSK_SIMULATE
, &resp
);
561 PrintAndLogEx(INFO
, "Done!");
562 if (resp
.status
!= PM3_EOPABORTED
) {
568 static command_t CommandTable
[] = {
569 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
570 {"demod", CmdNexWatchDemod
, AlwaysAvailable
, "demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
571 {"reader", CmdNexWatchReader
, IfPm3Lf
, "attempt to read and extract tag data"},
572 {"clone", CmdNexWatchClone
, IfPm3Lf
, "clone NexWatch tag to T55x7, Q5/T5555 or EM4305/4469"},
573 {"sim", CmdNexWatchSim
, IfPm3Lf
, "simulate NexWatch tag"},
574 {NULL
, NULL
, NULL
, NULL
}
577 static int CmdHelp(const char *Cmd
) {
578 (void)Cmd
; // Cmd is not used so far
579 CmdsHelp(CommandTable
);
583 int CmdLFNEXWATCH(const char *Cmd
) {
584 clearCommandBuffer();
585 return CmdsParse(CommandTable
, Cmd
);
588 int detectNexWatch(uint8_t *dest
, size_t *size
, bool *invert
) {
590 uint8_t preamble
[28] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
592 if (*size
< 96) return -1;
596 if (!preambleSearch(g_DemodBuffer
, preamble
, sizeof(preamble
), size
, &startIdx
)) {
597 // if didn't find preamble try again inverting
598 uint8_t preamble_i
[28] = {1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
599 if (!preambleSearch(g_DemodBuffer
, preamble_i
, sizeof(preamble_i
), size
, &startIdx
)) return -4;
604 return (int) startIdx
;