1 #define __STDC_FORMAT_MACROS
11 #include "crapto1/crapto1.h"
13 #include "iso14443crc.h"
14 #include "util_posix.h"
16 #define AEND "\x1b[0m"
17 #define _RED_(s) "\x1b[31m" s AEND
18 #define _GREEN_(s) "\x1b[32m" s AEND
19 #define _YELLOW_(s) "\x1b[33m" s AEND
20 #define _CYAN_(s) "\x1b[36m" s AEND
22 #define odd_parity(i) (( (i) ^ (i)>>1 ^ (i)>>2 ^ (i)>>3 ^ (i)>>4 ^ (i)>>5 ^ (i)>>6 ^ (i)>>7 ^ 1) & 0x01)
23 #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
25 // a global mutex to prevent interlaced printing from different threads
26 pthread_mutex_t print_lock
;
28 //--------------------- define options here
29 uint32_t uid
= 0; // serial number
30 uint32_t nt_enc
= 0; // Encrypted tag nonce
31 uint32_t nr_enc
= 0; // encrypted reader challenge
32 uint32_t ar_enc
= 0; // encrypted reader response
33 uint32_t at_enc
= 0; // encrypted tag response
34 uint32_t cmd_enc
= 0; // next encrypted command to sector
35 bool is_nt_encrypted
= 1;
37 uint32_t nt_par_err
= 0;
38 uint32_t ar_par_err
= 0;
39 uint32_t at_par_err
= 0;
41 typedef struct thread_args
{
49 typedef struct thread_key_args
{
57 uint8_t enc
[ENC_LEN
]; // next encrypted command + a full read/write
61 //------------------------------------------------------------------
63 uint8_t cmds
[8][2] = {
64 {ISO14443A_CMD_READBLOCK
, 18},
65 {ISO14443A_CMD_WRITEBLOCK
, 18},
66 {MIFARE_AUTH_KEYA
, 0},
67 {MIFARE_AUTH_KEYB
, 0},
70 {MIFARE_CMD_RESTORE
, 6},
71 {MIFARE_CMD_TRANSFER
, 0}
74 static const uint64_t g_mifare_default_keys
[] = {
75 0xffffffffffff, // Default key (first key used by program if no user defined key)
76 0xa0a1a2a3a4a5, // NFCForum MAD key
77 0xd3f7d3f7d3f7, // NDEF public key
78 0x4b791bea7bcc, // MFC EV1 Signature 17 B
79 0x5C8FF9990DA2, // MFC EV1 Signature 16 A
80 0xD01AFEEB890A, // MFC EV1 Signature 16 B
81 0x75CCB59C9BED, // MFC EV1 Signature 17 A
82 0xfc00018778f7, // Public Transport
83 0x6471a5ef2d1a, // SimonsVoss
84 0x4E3552426B32, // ID06
85 0x6A1987C40A21, // Salto
86 0xef1232ab18a0, // Schlage
88 0xb7bf0c13066e, // Gallagher
89 0x135b88a94b8b, // Saflok
90 0x2A2C13CC242A, // Dorma Kaba
91 0x5a7a52d5e20d, // Bosch
92 0x314B49474956, // VIGIK1 A
93 0x564c505f4d41, // VIGIK1 B
94 0x021209197591, // BTCINO
95 0x484558414354, // Intratone
96 0xEC0A9B1A9E06, // Vingcard
97 0x66b31e64ca4b, // Vingcard
98 0x97F5DA640B18, // Bangkok metro key
99 0xA8844B0BCA06, // Metro Valencia key
100 0xE4410EF8ED2D, // Armenian metro
101 0x857464D3AAD1, // HTC Eindhoven key
102 0x08B386463229, // troika
103 0xe00000000000, // icopy
104 0x199404281970, // NSP A
105 0x199404281998, // NSP B
106 0x6A1987C40A21, // SALTO
107 0x7F33625BC129, // SALTO
108 0x484944204953, // HID
109 0x204752454154, // HID
110 0x3B7E4FD575AD, // HID
111 0x11496F97752A, // HID
112 0x3E65E4FB65B3, // Gym
113 0x000000000000, // Blank key
134 //static int global_counter = 0;
135 static int global_found
= 0;
136 static int global_found_candidate
= 0;
137 static uint64_t global_candidate_key
= 0;
138 static int thread_count
= 2;
140 static int param_getptr(const char *line
, int *bg
, int *en
, int paramnum
) {
142 int len
= strlen(line
);
148 while (line
[*bg
] == ' ' || line
[*bg
] == '\t')(*bg
)++;
153 for (i
= 0; i
< paramnum
; i
++) {
154 while (line
[*bg
] != ' ' && line
[*bg
] != '\t' && line
[*bg
] != '\0')(*bg
)++;
155 while (line
[*bg
] == ' ' || line
[*bg
] == '\t')(*bg
)++;
157 if (line
[*bg
] == '\0') return 1;
161 while (line
[*en
] != ' ' && line
[*en
] != '\t' && line
[*en
] != '\0')(*en
)++;
168 static int param_gethex_to_eol(const char *line
, int paramnum
, uint8_t *data
, int maxdatalen
, int *datalen
) {
173 if (param_getptr(line
, &bg
, &en
, paramnum
)) return 1;
179 if (line
[indx
] == '\t' || line
[indx
] == ' ') {
184 if (isxdigit(line
[indx
])) {
185 buf
[strlen(buf
) + 1] = 0x00;
186 buf
[strlen(buf
)] = line
[indx
];
188 // if we have symbols other than spaces and hex
192 if (*datalen
>= maxdatalen
) {
193 // if we don't have space in buffer and have symbols to translate
197 if (strlen(buf
) >= 2) {
198 sscanf(buf
, "%x", &temp
);
199 data
[*datalen
] = (uint8_t)(temp
& 0xff);
208 //error when not completed hex bytes
214 static void hex_to_buffer(const uint8_t *buf
, const uint8_t *hex_data
, const size_t hex_len
, const size_t hex_max_len
,
215 const size_t min_str_len
, const size_t spaces_between
, bool uppercase
) {
217 if (buf
== NULL
) return;
219 char *tmp_base
= (char *)buf
;
220 char *tmp
= tmp_base
;
223 size_t max_len
= (hex_len
> hex_max_len
) ? hex_max_len
: hex_len
;
225 for (i
= 0; i
< max_len
; ++i
, tmp
+= 2 + spaces_between
) {
226 snprintf(tmp
, hex_max_len
- (tmp
- tmp_base
), (uppercase
) ? "%02X" : "%02x", (unsigned int) hex_data
[i
]);
228 for (size_t j
= 0; j
< spaces_between
; j
++)
229 snprintf(tmp
+ 2 + j
, hex_max_len
- (2 + j
+ (tmp
- tmp_base
)), " ");
232 i
*= (2 + spaces_between
);
234 size_t mlen
= min_str_len
> i
? min_str_len
: 0;
235 if (mlen
> hex_max_len
)
238 for (; i
< mlen
; i
++, tmp
+= 1)
239 snprintf(tmp
, hex_max_len
- (tmp
- tmp_base
), " ");
245 static char *sprint_hex_inrow_ex(const uint8_t *data
, const size_t len
, const size_t min_str_len
) {
246 static char buf
[100] = {0};
247 hex_to_buffer((uint8_t *)buf
, data
, len
, sizeof(buf
) - 1, min_str_len
, 0, true);
251 static uint16_t parity_from_err(uint32_t data
, uint16_t par_err
) {
254 par
|= odd_parity((data
>> 24) & 0xFF) ^ ((par_err
>> 12) & 1);
257 par
|= odd_parity((data
>> 16) & 0xFF) ^ ((par_err
>> 8) & 1);
260 par
|= odd_parity((data
>> 8) & 0xFF) ^ ((par_err
>> 4) & 1);
263 par
|= odd_parity(data
& 0xFF) ^ (par_err
& 1);
267 static uint16_t xored_bits(uint16_t nt_par
, uint32_t ntenc
, uint16_t ar_par
, uint32_t arenc
, uint16_t at_par
, uint32_t atenc
) {
273 par
= (nt_par
>> 12) & 1;
274 xored
|= par
^ ((ntenc
>> 16) & 1);
278 par
= (nt_par
>> 8) & 1;
279 xored
|= par
^ ((ntenc
>> 8) & 1);
283 par
= (nt_par
>> 4) & 1;
284 xored
|= par
^ (ntenc
& 1);
288 par
= (ar_par
>> 12) & 1;
289 xored
|= par
^ ((arenc
>> 16) & 1);
293 par
= (ar_par
>> 8) & 1;
294 xored
|= par
^ ((arenc
>> 8) & 1);
298 par
= (ar_par
>> 4) & 1;
299 xored
|= par
^ (arenc
& 1);
304 xored
|= par
^ ((atenc
>> 24) & 1);
308 par
= (at_par
>> 12) & 1;
309 xored
|= par
^ ((atenc
>> 16) & 1);
313 par
= (at_par
>> 8) & 1;
314 xored
|= par
^ ((atenc
>> 8) & 1);
318 par
= (at_par
>> 4) & 1;
319 xored
|= par
^ (atenc
& 1);
324 static bool candidate_nonce(uint32_t xored
, uint32_t nt
, bool ev1
) {
329 byte
= (nt
>> 24) & 0xFF;
330 if (odd_parity(byte
) ^ ((nt
>> 16) & 1) ^ ((xored
>> 9) & 1)) {
335 byte
= (nt
>> 16) & 0xFF;
336 if (odd_parity(byte
) ^ ((nt
>> 8) & 1) ^ ((xored
>> 8) & 1)) {
342 byte
= (nt
>> 8) & 0xFF;
343 if (odd_parity(byte
) ^ (nt
& 1) ^ ((xored
>> 7) & 1)) {
347 uint32_t ar
= prng_successor(nt
, 64);
350 byte
= (ar
>> 24) & 0xFF;
351 if (odd_parity(byte
) ^ ((ar
>> 16) & 1) ^ ((xored
>> 6) & 1)) {
356 byte
= (ar
>> 16) & 0x0FF;
357 if (odd_parity(byte
) ^ ((ar
>> 8) & 1) ^ ((xored
>> 5) & 1)) {
362 byte
= (ar
>> 8) & 0xFF;
363 if (odd_parity(byte
) ^ (ar
& 1) ^ ((xored
>> 4) & 1)) {
367 uint32_t at
= prng_successor(nt
, 96);
371 if (odd_parity(byte
) ^ ((at
>> 24) & 1) ^ ((xored
>> 3) & 1)) {
376 byte
= (at
>> 24) & 0xFF;
377 if (odd_parity(byte
) ^ ((at
>> 16) & 1) ^ ((xored
>> 2) & 1)) {
382 byte
= (at
>> 16) & 0xFF;
383 if (odd_parity(byte
) ^ ((at
>> 8) & 1) ^ ((xored
>> 1) & 1)) {
388 byte
= (at
>> 8) & 0xFF;
389 if (odd_parity(byte
) ^ (at
& 1) ^ (xored
& 1)) {
396 static bool checkValidCmd(uint32_t decrypted
) {
397 uint8_t cmd
= (decrypted
>> 24) & 0xFF;
398 for (int i
= 0; i
< 8; ++i
) {
399 if (cmd
== cmds
[i
][0]) {
406 static bool checkValidCmdByte(uint8_t *cmd
, uint16_t n
) {
407 // if we don't have enough data then this might be a false positive
413 for (int i
= 0; i
< 8; ++i
) {
414 if (cmd
[0] == cmds
[i
][0]) {
419 res
= CheckCrc14443(CRC_14443_A
, cmd
, 4);
422 if (res
== 0 && cmds
[i
][1] > 0 && n
>= cmds
[i
][1]) {
423 res
= CheckCrc14443(CRC_14443_A
, cmd
, cmds
[i
][1]);
434 static bool checkCRC(uint32_t decrypted
) {
436 (decrypted
>> 24) & 0xFF,
437 (decrypted
>> 16) & 0xFF,
438 (decrypted
>> 8) & 0xFF,
441 return CheckCrc14443(CRC_14443_A
, data
, sizeof(data
));
444 static void *check_default_keys(void *arguments
) {
445 struct thread_key_args
*args
= (struct thread_key_args
*) arguments
;
446 uint8_t local_enc
[args
->enc_len
];
447 memcpy(local_enc
, args
->enc
, args
->enc_len
);
449 for (uint8_t i
= 0; i
< ARRAYLEN(g_mifare_default_keys
); i
++) {
451 uint64_t key
= g_mifare_default_keys
[i
];
453 // Init cipher with key
454 struct Crypto1State
*pcs
= crypto1_create(key
);
456 // NESTED decrypt nt with help of new key
457 crypto1_word(pcs
, args
->nt_enc
^ args
->uid
, args
->is_nt_encrypted
);
458 crypto1_word(pcs
, args
->nr_enc
, 1);
459 crypto1_word(pcs
, 0, 0);
460 crypto1_word(pcs
, 0, 0);
463 uint8_t dec
[args
->enc_len
];
464 for (int j
= 0; j
< args
->enc_len
; j
++) {
465 dec
[j
] = crypto1_byte(pcs
, 0x00, 0) ^ local_enc
[j
];
467 crypto1_destroy(pcs
);
469 // check if cmd exists
470 bool res
= checkValidCmdByte(dec
, args
->enc_len
);
471 if (args
->enc_len
> 4) {
472 res
|= checkValidCmdByte(dec
+ 4, args
->enc_len
- 4);
479 __sync_fetch_and_add(&global_found
, 1);
481 pthread_mutex_lock(&print_lock
);
482 printf("\nFound a default key!\n");
483 printf("enc: %s\n", sprint_hex_inrow_ex(local_enc
, args
->enc_len
, 0));
484 printf("dec: %s\n", sprint_hex_inrow_ex(dec
, args
->enc_len
, 0));
485 printf("\nValid Key found [ " _GREEN_("%012" PRIx64
) " ]\n\n", key
);
486 pthread_mutex_unlock(&print_lock
);
493 static void *brute_thread(void *arguments
) {
495 struct thread_args
*args
= (struct thread_args
*) arguments
;
497 struct Crypto1State
*revstate
= NULL
;
498 uint64_t key
; // recovered key candidate
499 uint32_t ks2
; // keystream used to encrypt reader response
500 uint32_t ks3
; // keystream used to encrypt tag response
501 uint32_t ks4
; // keystream used to encrypt next command
502 uint32_t nt
; // current tag nonce
506 // threads calls 0 ev1 == false
507 // threads calls 0,1,2 ev1 == true
508 for (uint32_t count
= args
->idx
; count
<= 0xFFFF; count
+= thread_count
) {
510 if (__atomic_load_n(&global_found
, __ATOMIC_ACQUIRE
) == 1) {
514 nt
= count
<< 16 | prng_successor(count
, 16);
516 if (candidate_nonce(args
->xored
, nt
, args
->ev1
) == false) {
520 p64
= prng_successor(nt
, 64);
522 ks3
= at_enc
^ prng_successor(p64
, 32);
523 revstate
= lfsr_recovery64(ks2
, ks3
);
524 ks4
= crypto1_word(revstate
, 0, 0);
531 // lock this section to avoid interlacing prints from different threats
532 pthread_mutex_lock(&print_lock
);
534 printf("\n---> " _YELLOW_(" Possible key candidate")" <---\n");
538 printf("thread #%d idx %d %s\n", args
->thread
, args
->idx
, (args
->ev1
) ? "(Ev1)" : "");
539 printf("current nt(%08x) ar_enc(%08x) at_enc(%08x)\n", nt
, ar_enc
, at_enc
);
540 printf("ks2:%08x\n", ks2
);
541 printf("ks3:%08x\n", ks3
);
542 printf("ks4:%08x\n", ks4
);
545 uint32_t decrypted
= ks4
^ cmd_enc
;
546 printf("CMD enc( %08x )\n", cmd_enc
);
547 printf(" dec( %08x ) ", decrypted
);
549 // check if cmd exists
550 uint8_t isOK
= checkValidCmd(decrypted
);
552 printf(_RED_("<-- not a valid cmd\n"));
553 pthread_mutex_unlock(&print_lock
);
559 isOK
= checkCRC(decrypted
);
561 printf(_RED_("<-- not a valid crc\n"));
562 pthread_mutex_unlock(&print_lock
);
567 printf("<-- " _GREEN_("valid cmd") "\n");
570 lfsr_rollback_word(revstate
, 0, 0);
571 lfsr_rollback_word(revstate
, 0, 0);
572 lfsr_rollback_word(revstate
, 0, 0);
573 lfsr_rollback_word(revstate
, nr_enc
, 1);
574 lfsr_rollback_word(revstate
, uid
^ nt
, 0);
575 crypto1_get_lfsr(revstate
, &key
);
579 // if it was EV1, we know for sure xxxAAAAAAAA recovery
580 printf("\nKey candidate [ " _YELLOW_("....%08" PRIx64
)" ]\n\n", key
& 0xFFFFFFFF);
581 __sync_fetch_and_add(&global_found_candidate
, 1);
583 printf("\nKey candidate [ " _GREEN_("....%08" PRIx64
) " ]", key
& 0xFFFFFFFF);
584 printf("\nKey candidate [ " _GREEN_("%12" PRIx64
) " ]\n\n", key
);
585 __sync_fetch_and_add(&global_found
, 1);
588 pthread_mutex_unlock(&print_lock
);
589 __sync_fetch_and_add(&global_candidate_key
, key
);
596 // Bruteforce the upper 16 bits of the key
597 static void *brute_key_thread(void *arguments
) {
599 struct thread_key_args
*args
= (struct thread_key_args
*) arguments
;
600 uint8_t local_enc
[args
->enc_len
];
601 memcpy(local_enc
, args
->enc
, args
->enc_len
);
603 for (uint64_t count
= args
->idx
; count
<= 0xFFFF; count
+= thread_count
) {
605 uint64_t key
= args
->part_key
| (count
<< 32);
607 // Init cipher with key
608 struct Crypto1State
*pcs
= crypto1_create(key
);
610 // NESTED decrypt nt with help of new key
611 crypto1_word(pcs
, args
->nt_enc
^ args
->uid
, args
->is_nt_encrypted
);
612 crypto1_word(pcs
, args
->nr_enc
, 1);
613 crypto1_word(pcs
, 0, 0);
614 crypto1_word(pcs
, 0, 0);
617 uint8_t dec
[args
->enc_len
];
618 for (int i
= 0; i
< args
->enc_len
; i
++) {
619 dec
[i
] = crypto1_byte(pcs
, 0x00, 0) ^ local_enc
[i
];
622 crypto1_destroy(pcs
);
624 // check if cmd exists
625 if (checkValidCmdByte(dec
, args
->enc_len
) == false) {
629 __sync_fetch_and_add(&global_found_candidate
, 1);
631 // lock this section to avoid interlacing prints from different threats
632 pthread_mutex_lock(&print_lock
);
633 printf("\nenc: %s\n", sprint_hex_inrow_ex(local_enc
, args
->enc_len
, 0));
634 printf("dec: %s\n", sprint_hex_inrow_ex(dec
, args
->enc_len
, 0));
636 if (key
== global_candidate_key
) {
637 printf("\nValid Key found [ " _GREEN_("%012" PRIx64
) " ] - " _YELLOW_("matches candidate") "\n\n", key
);
639 printf("\nValid Key found [ " _GREEN_("%012" PRIx64
) " ]\n\n", key
);
642 pthread_mutex_unlock(&print_lock
);
648 static int usage(void) {
650 printf("syntax: mf_nonce_brute <uid> <{nt}> <nt_par_err> <{nr}> <{ar}> <ar_par_err> <{at}> <at_par_err> [<{next_command}>]\n\n");
651 printf("alternatively, you can provide a clear nt:\n");
652 printf("syntax: mf_nonce_brute <uid> <nt> clear <{nr}> <{ar}> <ar_par_err> <{at}> <at_par_err> [<{next_command}>]\n\n");
653 printf("how to convert trace data to needed input:\n");
654 printf(" {nt} in trace = 8c! 42 e6! 4e!\n");
655 printf(" => {nt} = 8c42e64e\n");
656 printf(" => nt_par_err = 1011\n\n");
657 printf("samples:\n");
659 printf(" ./mf_nonce_brute fa247164 fb47c594 0000 71909d28 0c254817 1000 0dc7cfbd 1110\n");
661 printf("**** Possible key candidate ****\n");
662 printf("Key candidate: [....ffffffff]\n");
663 printf("Too few next cmd bytes, skipping phase 2\n");
665 printf(" ./mf_nonce_brute 96519578 d7e3c6ac 0011 cd311951 9da49e49 0010 2bb22e00 0100 a4f7f398ebdb4e484d1cb2b174b939d18b469f3fa5d9caab\n");
667 printf("enc: A4F7F398EBDB4E484D1CB2B174B939D18B469F3FA5D9CAABBFA018EC7E0CC5721DE2E590F64BD0A5B4EFCE71\n");
668 printf("dec: 30084A24302F8102F44CA5020500A60881010104763930084A24302F8102F44CA5020500A608810101047639\n");
669 printf("Valid Key found: [3b7e4fd575ad]\n\n");
673 int main(int argc
, const char *argv
[]) {
674 printf("\nMifare classic nested auth key recovery\n\n");
676 if (argc
< 9) return usage();
678 sscanf(argv
[1], "%x", &uid
);
679 sscanf(argv
[2], "%x", &nt_enc
);
680 if (strncmp(argv
[3], "clear", 5) == 0) {
684 sscanf(argv
[3], "%x", &nt_par_err
);
686 sscanf(argv
[4], "%x", &nr_enc
);
687 sscanf(argv
[5], "%x", &ar_enc
);
688 sscanf(argv
[6], "%x", &ar_par_err
);
689 sscanf(argv
[7], "%x", &at_enc
);
690 sscanf(argv
[8], "%x", &at_par_err
);
692 // next encrypted command + a full read/write
694 uint8_t enc
[ENC_LEN
] = {0};
696 param_gethex_to_eol(argv
[9], 0, enc
, sizeof(enc
), &enc_len
);
697 cmd_enc
= (enc
[0] << 24 | enc
[1] << 16 | enc
[2] << 8 | enc
[3]);
700 printf("----------- " _CYAN_("information") " ------------------------\n");
701 printf("uid.................. %08x\n", uid
);
702 printf("nt encrypted......... %08x\n", nt_enc
);
703 printf("nt parity err........ %04x\n", nt_par_err
);
704 printf("nr encrypted......... %08x\n", nr_enc
);
705 printf("ar encrypted......... %08x\n", ar_enc
);
706 printf("ar parity err........ %04x\n", ar_par_err
);
707 printf("at encrypted......... %08x\n", at_enc
);
708 printf("at parity err........ %04x\n", at_par_err
);
711 printf("next encrypted cmd... %s\n", sprint_hex_inrow_ex(enc
, enc_len
, 0));
714 uint64_t t1
= msclock();
715 uint16_t nt_par
= parity_from_err(nt_enc
, nt_par_err
);
716 uint16_t ar_par
= parity_from_err(ar_enc
, ar_par_err
);
717 uint16_t at_par
= parity_from_err(at_enc
, at_par_err
);
719 // calc (parity XOR corresponding nonce bit encoded with the same keystream bit)
720 uint16_t xored
= xored_bits(nt_par
, nt_enc
, ar_par
, ar_enc
, at_par
, at_enc
);
722 #if !defined(_WIN32) || !defined(__WIN32__)
723 thread_count
= sysconf(_SC_NPROCESSORS_CONF
);
724 if (thread_count
< 2)
728 printf("\nBruteforce using " _YELLOW_("%d") " threads\n\n", thread_count
);
730 pthread_t threads
[thread_count
];
732 // create a mutex to avoid interlacing print commands from our different threads
733 pthread_mutex_init(&print_lock
, NULL
);
735 // if we have 4 or more bytes, look for a default key
737 printf("----------- " _CYAN_("Phase 1 pre-processing") " ------------------------\n");
738 printf("Testing default keys using NESTED authentication...\n");
739 struct thread_key_args
*def
= calloc(1, sizeof(struct thread_key_args
));
743 def
->nt_enc
= nt_enc
;
744 def
->nr_enc
= nr_enc
;
745 def
->enc_len
= enc_len
;
746 def
->is_nt_encrypted
= is_nt_encrypted
;
747 memcpy(def
->enc
, enc
, enc_len
);
748 pthread_create(&threads
[0], NULL
, check_default_keys
, (void *)def
);
749 pthread_join(threads
[0], NULL
);
755 printf("\n----------- " _CYAN_("Phase 2 examine") " -------------------------------\n");
756 printf("Looking for the last bytes of the encrypted tagnonce\n");
757 printf("\nTarget old MFC...\n");
758 // the rest of available threads to EV1 scenario
759 for (int i
= 0; i
< thread_count
; ++i
) {
760 struct thread_args
*a
= calloc(1, sizeof(struct thread_args
));
765 pthread_create(&threads
[i
], NULL
, brute_thread
, (void *)a
);
768 // wait for threads to terminate:
769 for (int i
= 0; i
< thread_count
; ++i
) {
770 pthread_join(threads
[i
], NULL
);
774 printf("execution time " _YELLOW_("%.2f") " sec\n", (float)t1
/ 1000.0);
776 if (!global_found
&& !global_found_candidate
) {
777 printf("\nTarget MFC Ev1...\n");
780 // the rest of available threads to EV1 scenario
781 for (int i
= 0; i
< thread_count
; ++i
) {
782 struct thread_args
*a
= calloc(1, sizeof(struct thread_args
));
787 pthread_create(&threads
[i
], NULL
, brute_thread
, (void *)a
);
790 // wait for threads to terminate:
791 for (int i
= 0; i
< thread_count
; ++i
) {
792 pthread_join(threads
[i
], NULL
);
796 printf("execution time " _YELLOW_("%.2f") " sec\n", (float)t1
/ 1000.0);
799 if (!global_found
&& !global_found_candidate
) {
800 printf("\nFailed to find a key\n\n");
806 printf("Too few next cmd bytes, skipping phase 3\n\n");
810 // reset thread signals
811 global_found_candidate
= 0;
813 printf("\n----------- " _CYAN_("Phase 3 validating") " ----------------------------\n");
814 printf("uid.................. %08x\n", uid
);
815 printf("partial key.......... %08x\n", (uint32_t)(global_candidate_key
& 0xFFFFFFFF));
816 printf("possible key......... %012" PRIx64
"\n", global_candidate_key
);
817 printf("nt enc............... %08x\n", nt_enc
);
818 printf("nr enc............... %08x\n", nr_enc
);
819 printf("next encrypted cmd... %s\n", sprint_hex_inrow_ex(enc
, enc_len
, 0));
820 printf("\nLooking for the upper 16 bits of the key\n");
824 for (int i
= 0; i
< thread_count
; ++i
) {
825 struct thread_key_args
*b
= calloc(1, sizeof(struct thread_key_args
));
829 b
->part_key
= (uint32_t)(global_candidate_key
& 0xFFFFFFFF);
832 b
->enc_len
= enc_len
;
833 b
->is_nt_encrypted
= is_nt_encrypted
;
834 memcpy(b
->enc
, enc
, enc_len
);
835 pthread_create(&threads
[i
], NULL
, brute_key_thread
, (void *)b
);
838 // wait for threads to terminate:
839 for (int i
= 0; i
< thread_count
; ++i
) {
840 pthread_join(threads
[i
], NULL
);
844 if (global_found_candidate
> 1) {
845 printf("Key recovery ( " _GREEN_("ok") " )\n");
846 printf("Found " _GREEN_("%d") " possible keys\n", global_found_candidate
);
847 printf(_YELLOW_("You need to test them manually, start with the one matching the candidate\n\n"));
848 } else if (global_found_candidate
== 1) {
849 printf("Key recovery ( " _GREEN_("ok") " )\n\n");
851 printf("Key recovery ( " _RED_("fail") " )\n\n");
856 pthread_mutex_destroy(&print_lock
);