1 //-----------------------------------------------------------------------------
3 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
4 // at your option, any later version. See the LICENSE.txt file for the text of
6 //-----------------------------------------------------------------------------
7 // Low frequency Honeywell NexWatch tag commands
8 // PSK1 RF/16, RF/2, 128 bits long (known)
9 //-----------------------------------------------------------------------------
11 #include "cmdlfnexwatch.h"
12 #include <inttypes.h> // PRIu
14 #include <ctype.h> // tolower
15 #include <stdlib.h> // free, alloc
16 #include "commonutil.h" // ARRAYLEN
17 #include "cmdparser.h" // command_t
20 #include "cmddata.h" // preamblesearch
23 #include "protocols.h" // t55xx defines
24 #include "cmdlft55xx.h" // clone..
25 #include "cmdlfem4x05.h" //
26 #include "cliparser.h"
33 static int CmdHelp(const char *Cmd
);
35 // scramble parity (1234) -> (4231)
36 static uint8_t nexwatch_parity_swap(uint8_t parity
) {
37 uint8_t a
= (((parity
>> 3) & 1));
38 a
|= (((parity
>> 1) & 1) << 1);
39 a
|= (((parity
>> 2) & 1) << 2);
40 a
|= ((parity
& 1) << 3);
44 // from 32b hex id, 4b mode,
45 static uint8_t nexwatch_parity(uint8_t hexid
[5]) {
47 for (uint8_t i
= 0; i
< 5; i
++) {
48 p
^= NIBBLE_HIGH(hexid
[i
]);
49 p
^= NIBBLE_LOW(hexid
[i
]);
51 return nexwatch_parity_swap(p
);
55 /// @param magic = 0xBE Quadrakey, 0x88 Nexkey
56 /// @param id = descrambled id (printed card number)
57 /// @param parity = the parity based upon the scrambled raw id.
58 static uint8_t nexwatch_checksum(uint8_t magic
, uint32_t id
, uint8_t parity
) {
59 uint8_t a
= ((id
>> 24) & 0xFF);
60 a
-= ((id
>> 16) & 0xFF);
61 a
-= ((id
>> 8) & 0xFF);
64 a
-= (reflect8(parity
) >> 4);
68 // Scrambled id ( 88 bit cardnumber format)
69 // ref:: http://www.proxmark.org/forum/viewtopic.php?pid=14662#p14662
70 static int nexwatch_scamble(NexWatchScramble_t action
, uint32_t *id
, uint32_t *scambled
) {
72 // 255 = Not used/Unknown other values are the bit offset in the ID/FC values
73 uint8_t hex_2_id
[] = {
74 31, 27, 23, 19, 15, 11, 7, 3,
75 30, 26, 22, 18, 14, 10, 6, 2,
76 29, 25, 21, 17, 13, 9, 5, 1,
77 28, 24, 20, 16, 12, 8, 4, 0
83 for (uint8_t idx
= 0; idx
< 32; idx
++) {
85 if (hex_2_id
[idx
] == 255)
88 bool bit_state
= (*scambled
>> hex_2_id
[idx
]) & 1;
89 *id
|= (bit_state
<< (31 - idx
));
95 for (uint8_t idx
= 0; idx
< 32; idx
++) {
97 if (hex_2_id
[idx
] == 255)
100 bool bit_state
= (*id
>> idx
) & 1;
101 *scambled
|= (bit_state
<< (31 - hex_2_id
[idx
]));
111 int demodNexWatch(bool verbose
) {
112 (void) verbose
; // unused so far
113 if (PSKDemod(0, 0, 100, false) != PM3_SUCCESS
) {
114 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch can't demod signal");
118 size_t size
= DemodBufferLen
;
119 int idx
= detectNexWatch(DemodBuffer
, &size
, &invert
);
122 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch not enough samples");
123 // else if (idx == -2)
124 // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch only noise found");
125 // else if (idx == -3)
126 // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch problem during PSK demod");
128 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch preamble not found");
129 // else if (idx == -5)
130 // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch size not correct: %d", size);
132 PrintAndLogEx(DEBUG
, "DEBUG: Error - NexWatch error %d", idx
);
137 // skip the 4 first bits from the nexwatch preamble identification (we use 4 extra zeros..)
140 setDemodBuff(DemodBuffer
, size
, idx
);
141 setClockGrid(g_DemodClock
, g_DemodStartIdx
+ (idx
* g_DemodClock
));
144 PrintAndLogEx(INFO
, "Inverted the demodulated data");
145 for (size_t i
= 0; i
< size
; i
++)
150 uint32_t raw1
= bytebits_to_byte(DemodBuffer
, 32);
151 uint32_t raw2
= bytebits_to_byte(DemodBuffer
+ 32, 32);
152 uint32_t raw3
= bytebits_to_byte(DemodBuffer
+ 32 + 32, 32);
156 for (uint8_t k
= 0; k
< 4; k
++) {
157 for (uint8_t m
= 0; m
< 8; m
++) {
158 rawid
= (rawid
<< 1) | DemodBuffer
[m
+ k
+ (m
* 4)];
164 uint32_t scambled
= bytebits_to_byte(DemodBuffer
+ 8 + 32, 32);
165 nexwatch_scamble(DESCRAMBLE
, &cn
, &scambled
);
167 uint8_t mode
= bytebits_to_byte(DemodBuffer
+ 72, 4);
168 uint8_t parity
= bytebits_to_byte(DemodBuffer
+ 76, 4);
169 uint8_t chk
= bytebits_to_byte(DemodBuffer
+ 80, 8);
172 // from 32b hex id, 4b mode
173 uint8_t hex
[5] = {0};
174 for (uint8_t i
= 0; i
< 5; i
++) {
175 hex
[i
] = bytebits_to_byte(DemodBuffer
+ 8 + 32 + (i
* 8), 8);
177 // mode is only 4 bits.
179 uint8_t calc_parity
= nexwatch_parity(hex
);
187 nexwatch_magic_t items
[] = {
188 {0xBE, "Quadrakey", 0},
190 {0x86, "Honeywell", 0}
194 for (m_idx
= 0; m_idx
< ARRAYLEN(items
); m_idx
++) {
196 items
[m_idx
].chk
= nexwatch_checksum(items
[m_idx
].magic
, cn
, calc_parity
);
197 if (items
[m_idx
].chk
== chk
) {
203 PrintAndLogEx(SUCCESS
, " NexWatch raw id : " _YELLOW_("0x%08"PRIx32
), rawid
);
205 if (m_idx
< ARRAYLEN(items
)) {
206 PrintAndLogEx(SUCCESS
, " fingerprint : " _GREEN_("%s"), items
[m_idx
].desc
);
208 PrintAndLogEx(SUCCESS
, " 88bit id : " _YELLOW_("%"PRIu32
) " (" _YELLOW_("0x%08"PRIx32
)")", cn
, cn
);
209 PrintAndLogEx(SUCCESS
, " mode : %x", mode
);
211 if (parity
== calc_parity
) {
212 PrintAndLogEx(DEBUG
, " parity : %s (0x%X)", _GREEN_("ok"), parity
);
214 PrintAndLogEx(DEBUG
, " parity : %s (0x%X != 0x%X)", _RED_("fail"), parity
, calc_parity
);
217 PrintAndLogEx(DEBUG
, " checksum : %s (0x%02X)", (m_idx
< ARRAYLEN(items
)) ? _GREEN_("ok") : _RED_("fail"), chk
);
219 PrintAndLogEx(INFO
, " Raw : " _YELLOW_("%08"PRIX32
"%08"PRIX32
"%08"PRIX32
), raw1
, raw2
, raw3
);
223 static int CmdNexWatchDemod(const char *Cmd
) {
224 CLIParserContext
*ctx
;
225 CLIParserInit(&ctx
, "lf nexwatch demod",
226 "Try to find Nexwatch preamble, if found decode / descramble data",
234 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
236 return demodNexWatch(true);
239 static int CmdNexWatchReader(const char *Cmd
) {
240 CLIParserContext
*ctx
;
241 CLIParserInit(&ctx
, "lf nexwatch reader",
242 "read a Nexwatch tag",
243 "lf nexwatch reader -@ -> continuous reader mode"
248 arg_lit0("@", NULL
, "optional - continuous reader mode"),
251 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
252 bool cm
= arg_get_lit(ctx
, 1);
256 PrintAndLogEx(INFO
, "Press " _GREEN_("<Enter>") " to exit");
260 lf_read(false, 20000);
262 } while (cm
&& !kbd_enter_pressed());
266 static int CmdNexWatchClone(const char *Cmd
) {
267 CLIParserContext
*ctx
;
268 CLIParserInit(&ctx
, "lf nexwatch clone",
269 "clone a Nexwatch tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
270 "You can use raw hex values or create a credential based on id, mode\n"
271 "and type of credential (Nexkey / Quadrakey / Russian)",
272 "lf nexwatch clone --raw 5600000000213C9F8F150C00\n"
273 "lf nexwatch clone --cn 521512301 -m 1 --nc -> Nexkey credential\n"
274 "lf nexwatch clone --cn 521512301 -m 1 --qc -> Quadrakey credential\n"
275 "lf nexwatch clone --cn 521512301 -m 1 --hc -> Honeywell credential\n"
280 arg_str0("r", "raw", "<hex>", "raw hex data. 12 bytes"),
281 arg_u64_0(NULL
, "cn", "<dec>", "card id"),
282 arg_u64_0("m", "mode", "<dec>", "mode (decimal) (0-15, defaults to 1)"),
283 arg_lit0(NULL
, "nc", "Nexkey credential"),
284 arg_lit0(NULL
, "qc", "Quadrakey credential"),
285 arg_lit0(NULL
, "hc", "Honeywell credential"),
286 arg_lit0(NULL
, "q5", "optional - specify writing to Q5/T5555 tag"),
287 arg_lit0(NULL
, "em", "optional - specify writing to EM4305/4469 tag"),
290 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
293 // skip first block, 3*4 = 12 bytes left
294 uint8_t raw
[12] = {0x56, 0};
295 CLIGetHexWithReturn(ctx
, 1, raw
, &raw_len
);
297 uint32_t cn
= arg_get_u32_def(ctx
, 2, -1);
298 uint32_t mode
= arg_get_u32_def(ctx
, 3, -1);
299 bool use_nexkey
= arg_get_lit(ctx
, 4);
300 bool use_quadrakey
= arg_get_lit(ctx
, 5);
301 bool use_unk
= arg_get_lit(ctx
, 6);
302 bool q5
= arg_get_lit(ctx
, 7);
303 bool em
= arg_get_lit(ctx
, 8);
306 if (use_nexkey
&& use_quadrakey
) {
307 PrintAndLogEx(FAILED
, "Can't specify both Nexkey and Quadrakey at the same time");
312 PrintAndLogEx(FAILED
, "Can't specify both Q5 and EM4305 at the same time");
316 // 56000000 00213C9F 8F150C00
317 bool use_raw
= (raw_len
!= 0);
319 if (use_raw
&& cn
!= -1) {
320 PrintAndLogEx(FAILED
, "Can't specify both Raw and Card id at the same time");
326 nexwatch_scamble(SCRAMBLE
, &cn
, &scrambled
);
327 num_to_bytes(scrambled
, 4, raw
+ 5);
335 raw
[9] |= (mode
<< 4);
338 uint8_t magic
= 0xBE;
350 //Nexwatch - compat mode, PSK, data rate 40, 3 data blocks
351 blocks
[0] = T55x7_MODULATION_PSK1
| T55x7_BITRATE_RF_32
| 3 << T55x7_MAXBLOCK_SHIFT
;
352 char cardtype
[16] = {"T55x7"};
355 blocks
[0] = T5555_FIXED
| T5555_MODULATION_MANCHESTER
| T5555_SET_BITRATE(64) | T5555_ST_TERMINATOR
| 3 << T5555_MAXBLOCK_SHIFT
;
356 snprintf(cardtype
, sizeof(cardtype
), "Q5/T5555");
361 blocks
[0] = EM4305_NEXWATCH_CONFIG_BLOCK
;
362 snprintf(cardtype
, sizeof(cardtype
), "EM4305/4469");
365 if (use_raw
== false) {
366 uint8_t parity
= nexwatch_parity(raw
+ 5) & 0xF;
368 raw
[10] |= nexwatch_checksum(magic
, cn
, parity
);
371 for (uint8_t i
= 1; i
< ARRAYLEN(blocks
); i
++) {
372 blocks
[i
] = bytes_to_num(raw
+ ((i
- 1) * 4), sizeof(uint32_t));
375 PrintAndLogEx(INFO
, "Preparing to clone NexWatch to " _YELLOW_("%s") " raw " _YELLOW_("%s"), cardtype
, sprint_hex_inrow(raw
, sizeof(raw
)));
376 print_blocks(blocks
, ARRAYLEN(blocks
));
380 res
= em4x05_clone_tag(blocks
, ARRAYLEN(blocks
), 0, false);
382 res
= clone_t55xx_tag(blocks
, ARRAYLEN(blocks
));
384 PrintAndLogEx(SUCCESS
, "Done");
385 PrintAndLogEx(HINT
, "Hint: try " _YELLOW_("`lf nexwatch reader`") " to verify");
389 static int CmdNexWatchSim(const char *Cmd
) {
391 CLIParserContext
*ctx
;
392 CLIParserInit(&ctx
, "lf nexwatch sim",
393 "Enables simulation of secura card with specified card number.\n"
394 "Simulation runs until the button is pressed or another USB command is issued.\n"
395 "You can use raw hex values or create a credential based on id, mode\n"
396 "and type of credential (Nexkey/Quadrakey)",
397 "lf nexwatch sim --raw 5600000000213C9F8F150C00\n"
398 "lf nexwatch sim --cn 521512301 -m 1 --nc -> Nexkey credential\n"
399 "lf nexwatch sim --cn 521512301 -m 1 --qc -> Quadrakey credential\n"
400 "lf nexwatch sim --cn 521512301 -m 1 --hc -> Honeywell credential\n"
405 arg_str0("r", "raw", "<hex>", "raw hex data. 12 bytes"),
406 arg_u64_0(NULL
, "cn", "<dec>", "card id"),
407 arg_u64_0("m", "mode", "<dec>", "mode (decimal) (0-15, defaults to 1)"),
408 arg_lit0(NULL
, "nc", "Nexkey credential"),
409 arg_lit0(NULL
, "qc", "Quadrakey credential"),
410 arg_lit0(NULL
, "hc", "Honeywell credential"),
413 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
416 // skip first block, 3*4 = 12 bytes left
417 uint8_t raw
[12] = {0x56, 0};
418 CLIGetHexWithReturn(ctx
, 1, raw
, &raw_len
);
420 uint32_t cn
= arg_get_u32_def(ctx
, 2, -1);
421 uint32_t mode
= arg_get_u32_def(ctx
, 3, -1);
422 bool use_nexkey
= arg_get_lit(ctx
, 4);
423 bool use_quadrakey
= arg_get_lit(ctx
, 5);
424 bool use_unk
= arg_get_lit(ctx
, 6);
427 if (use_nexkey
&& use_quadrakey
) {
428 PrintAndLogEx(FAILED
, "Can't specify both Nexkey and Quadrakey at the same time");
432 bool use_raw
= (raw_len
!= 0);
434 if (use_raw
&& cn
!= -1) {
435 PrintAndLogEx(FAILED
, "Can't specify both Raw and Card id at the same time");
441 nexwatch_scamble(SCRAMBLE
, &cn
, &scrambled
);
442 num_to_bytes(scrambled
, 4, raw
+ 5);
450 raw
[9] |= (mode
<< 4);
453 uint8_t magic
= 0xBE;
463 if (use_raw
== false) {
464 uint8_t parity
= nexwatch_parity(raw
+ 5) & 0xF;
466 raw
[10] |= nexwatch_checksum(magic
, cn
, parity
);
470 memset(bs
, 0, sizeof(bs
));
472 // hex to bits. (3 * 32 == 96)
473 for (size_t i
= 0; i
< 3; i
++) {
474 uint32_t tmp
= bytes_to_num(raw
+ (i
* sizeof(uint32_t)), sizeof(uint32_t));
475 num_to_bytebits(tmp
, sizeof(uint32_t) * 8, bs
+ (i
* sizeof(uint32_t) * 8));
478 PrintAndLogEx(SUCCESS
, "Simulating NexWatch - raw " _YELLOW_("%s"), sprint_hex_inrow(raw
, sizeof(raw
)));
480 lf_psksim_t
*payload
= calloc(1, sizeof(lf_psksim_t
) + sizeof(bs
));
481 payload
->carrier
= 2;
484 memcpy(payload
->data
, bs
, sizeof(bs
));
486 clearCommandBuffer();
487 SendCommandNG(CMD_LF_PSK_SIMULATE
, (uint8_t *)payload
, sizeof(lf_psksim_t
) + sizeof(bs
));
490 PacketResponseNG resp
;
491 WaitForResponse(CMD_LF_PSK_SIMULATE
, &resp
);
493 PrintAndLogEx(INFO
, "Done");
494 if (resp
.status
!= PM3_EOPABORTED
)
500 static command_t CommandTable
[] = {
501 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
502 {"demod", CmdNexWatchDemod
, AlwaysAvailable
, "demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
503 {"reader", CmdNexWatchReader
, IfPm3Lf
, "attempt to read and extract tag data"},
504 {"clone", CmdNexWatchClone
, IfPm3Lf
, "clone NexWatch tag to T55x7"},
505 {"sim", CmdNexWatchSim
, IfPm3Lf
, "simulate NexWatch tag"},
506 {NULL
, NULL
, NULL
, NULL
}
509 static int CmdHelp(const char *Cmd
) {
510 (void)Cmd
; // Cmd is not used so far
511 CmdsHelp(CommandTable
);
515 int CmdLFNEXWATCH(const char *Cmd
) {
516 clearCommandBuffer();
517 return CmdsParse(CommandTable
, Cmd
);
520 int detectNexWatch(uint8_t *dest
, size_t *size
, bool *invert
) {
522 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};
524 if (*size
< 96) return -1;
528 if (!preambleSearch(DemodBuffer
, preamble
, sizeof(preamble
), size
, &startIdx
)) {
529 // if didn't find preamble try again inverting
530 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};
531 if (!preambleSearch(DemodBuffer
, preamble_i
, sizeof(preamble_i
), size
, &startIdx
)) return -4;
536 return (int) startIdx
;