1 // Merlok, 2011, 2012, 2019
2 // people from mifare@nethemba.com, 2010
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
9 //-----------------------------------------------------------------------------
10 #include "mifarehost.h"
18 #include "commonutil.h"
20 #include "ui.h" // PrintAndLog...
21 #include "crapto1/crapto1.h"
23 #include "protocols.h"
25 #include "util_posix.h" // msclock
26 #include "cmdparser.h" // detection of flash capabilities
27 #include "cmdflashmemspiffs.h" // upload to flash mem
29 int mfDarkside(uint8_t blockno
, uint8_t key_type
, uint64_t *key
) {
31 uint32_t nt
= 0, nr
= 0, ar
= 0;
32 uint64_t par_list
= 0, ks_list
= 0;
33 uint64_t *keylist
= NULL
, *last_keylist
= NULL
;
34 bool first_run
= true;
37 PrintAndLogEx(INFO
, "--------------------------------------------------------------------------------");
38 PrintAndLogEx(INFO
, "Executing darkside attack. Expected execution time: 25sec on average");
39 PrintAndLogEx(INFO
, "press pm3-button on the Proxmark3 device to abort both Proxmark3 and client");
40 PrintAndLogEx(INFO
, "--------------------------------------------------------------------------------");
49 payload
.first_run
= first_run
;
50 payload
.blockno
= blockno
;
51 payload
.key_type
= key_type
;
52 SendCommandNG(CMD_HF_MIFARE_READER
, (uint8_t *)&payload
, sizeof(payload
));
55 while (kbd_enter_pressed()) {
56 return PM3_EOPABORTED
;
59 PrintAndLogEx(INFO
, "." NOLF
);
63 PrintAndLogEx(NORMAL
, "." NOLF
);
65 if (kbd_enter_pressed()) {
66 return PM3_EOPABORTED
;
69 PacketResponseNG resp
;
70 if (WaitForResponseTimeout(CMD_HF_MIFARE_READER
, &resp
, 2000)) {
71 if (resp
.status
== PM3_EOPABORTED
) {
85 struct p
*package
= (struct p
*) resp
.data
.asBytes
;
87 if (package
->isOK
== -6) {
92 if (package
->isOK
< 0)
96 uid
= (uint32_t)bytes_to_num(package
->cuid
, sizeof(package
->cuid
));
97 nt
= (uint32_t)bytes_to_num(package
->nt
, sizeof(package
->nr
));
98 par_list
= bytes_to_num(package
->par_list
, sizeof(package
->par_list
));
99 ks_list
= bytes_to_num(package
->ks_list
, sizeof(package
->ks_list
));
100 nr
= (uint32_t)bytes_to_num(package
->nr
, 4);
101 ar
= (uint32_t)bytes_to_num(package
->ar
, 4);
105 PrintAndLogEx(NORMAL
, "\n");
107 if (par_list
== 0 && first_run
== true) {
108 PrintAndLogEx(SUCCESS
, "Parity is all zero. Most likely this card sends NACK on every authentication.");
112 uint32_t keycount
= nonce2key(uid
, nt
, nr
, ar
, par_list
, ks_list
, &keylist
);
115 PrintAndLogEx(FAILED
, "key not found (lfsr_common_prefix list is null). Nt=%08x", nt
);
116 PrintAndLogEx(FAILED
, "this is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");
120 // only parity zero attack
122 qsort(keylist
, keycount
, sizeof(*keylist
), compare_uint64
);
123 keycount
= intersection(last_keylist
, keylist
);
126 last_keylist
= keylist
;
127 PrintAndLogEx(FAILED
, "no candidates found, trying again");
132 PrintAndLogEx(SUCCESS
, "found " _YELLOW_("%u") " candidate key%s", keycount
, (keycount
> 1) ? "s." : ".");
135 uint8_t keyBlock
[PM3_CMD_DATA_SIZE
];
136 uint32_t max_keys
= KEYS_IN_BLOCK
;
137 for (uint32_t i
= 0; i
< keycount
; i
+= max_keys
) {
139 uint8_t size
= keycount
- i
> max_keys
? max_keys
: keycount
- i
;
141 for (j
= 0; j
< size
; j
++) {
143 num_to_bytes(last_keylist
[i
* max_keys
+ j
], 6, keyBlock
+ (j
* 6));
145 num_to_bytes(keylist
[i
* max_keys
+ j
], 6, keyBlock
+ (j
* 6));
149 if (mfCheckKeys(blockno
, key_type
- 0x60, false, size
, keyBlock
, key
) == PM3_SUCCESS
) {
154 if (*key
!= UINT64_C(-1)) {
157 PrintAndLogEx(FAILED
, "all key candidates failed. Restarting darkside attack");
159 last_keylist
= keylist
;
168 int mfCheckKeys(uint8_t blockNo
, uint8_t keyType
, bool clear_trace
, uint8_t keycnt
, uint8_t *keyBlock
, uint64_t *key
) {
170 clearCommandBuffer();
171 uint8_t data
[PM3_CMD_DATA_SIZE
] = {0};
174 data
[2] = clear_trace
;
177 memcpy(data
+ 5, keyBlock
, 6 * keycnt
);
178 SendCommandNG(CMD_HF_MIFARE_CHKKEYS
, data
, (5 + 6 * keycnt
));
180 PacketResponseNG resp
;
181 if (!WaitForResponseTimeout(CMD_HF_MIFARE_CHKKEYS
, &resp
, 2500)) return PM3_ETIMEOUT
;
182 if (resp
.status
!= PM3_SUCCESS
) return resp
.status
;
188 struct kr
*keyresult
= (struct kr
*)&resp
.data
.asBytes
;
189 if (!keyresult
->found
) return PM3_ESOFT
;
190 *key
= bytes_to_num(keyresult
->key
, sizeof(keyresult
->key
));
194 // Sends chunks of keys to device.
195 // 0 == ok all keys found
197 // 2 == Time-out, aborting
198 int mfCheckKeys_fast(uint8_t sectorsCnt
, uint8_t firstChunk
, uint8_t lastChunk
, uint8_t strategy
,
199 uint32_t size
, uint8_t *keyBlock
, sector_t
*e_sector
, bool use_flashmemory
) {
201 uint64_t t2
= msclock();
204 clearCommandBuffer();
205 SendCommandOLD(CMD_HF_MIFARE_CHKKEYS_FAST
, (sectorsCnt
| (firstChunk
<< 8) | (lastChunk
<< 12)), ((use_flashmemory
<< 8) | strategy
), size
, keyBlock
, 6 * size
);
206 PacketResponseNG resp
;
208 uint32_t timeout
= 0;
209 while (!WaitForResponseTimeout(CMD_ACK
, &resp
, 2000)) {
211 PrintAndLogEx((timeout
== 0) ? INFO
: NORMAL
, "." NOLF
);
216 // max timeout for one chunk of 85keys, 60*3sec = 180seconds
217 // s70 with 40*2 keys to check, 80*85 = 6800 auth.
218 // takes about 97s, still some margin before abort
220 PrintAndLogEx(WARNING
, "\nNo response from Proxmark3. Aborting...");
227 PrintAndLogEx(NORMAL
, "");
230 // time to convert the returned data.
231 uint8_t curr_keys
= resp
.oldarg
[0];
233 PrintAndLogEx(INFO
, "Chunk: %.1fs | found %u/%u keys (%u)", (float)(t2
/ 1000.0), curr_keys
, (sectorsCnt
<< 1), size
);
236 if (curr_keys
== sectorsCnt
* 2 || lastChunk
) {
238 // success array. each byte is status of key
242 foo
= bytes_to_num(resp
.data
.asBytes
+ 480, 8);
243 bar
= (resp
.data
.asBytes
[489] << 8 | resp
.data
.asBytes
[488]);
245 for (uint8_t i
= 0; i
< 64; i
++)
246 arr
[i
] = (foo
>> i
) & 0x1;
248 for (uint8_t i
= 0; i
< 16; i
++)
249 arr
[i
+ 64] = (bar
>> i
) & 0x1;
251 // initialize storage for found keys
252 icesector_t
*tmp
= calloc(sectorsCnt
, sizeof(icesector_t
));
256 memcpy(tmp
, resp
.data
.asBytes
, sectorsCnt
* sizeof(icesector_t
));
258 for (int i
= 0; i
< sectorsCnt
; i
++) {
260 if (!e_sector
[i
].foundKey
[0]) {
261 e_sector
[i
].Key
[0] = bytes_to_num(tmp
[i
].keyA
, 6);
262 e_sector
[i
].foundKey
[0] = arr
[(i
* 2) ];
265 if (!e_sector
[i
].foundKey
[1]) {
266 e_sector
[i
].Key
[1] = bytes_to_num(tmp
[i
].keyB
, 6);
267 e_sector
[i
].foundKey
[1] = arr
[(i
* 2) + 1 ];
272 if (curr_keys
== sectorsCnt
* 2)
280 // Trigger device to use a binary file on flash mem as keylist for mfCheckKeys.
281 // As of now, 255 keys possible in the file
282 // 6 * 255 = 1500 bytes
283 int mfCheckKeys_file(uint8_t *destfn
, uint64_t *key
) {
285 clearCommandBuffer();
288 uint8_t filename
[32];
289 } PACKED payload_file
;
291 memcpy(payload_file
.filename
, destfn
, sizeof(payload_file
.filename
) - 1);
293 PacketResponseNG resp
;
294 clearCommandBuffer();
295 SendCommandNG(CMD_HF_MIFARE_CHKKEYS_FILE
, (uint8_t *)&payload_file
, sizeof(payload_file
));
299 while (!WaitForResponseTimeout(CMD_HF_MIFARE_CHKKEYS
, &resp
, 2000)) {
302 while (kbd_enter_pressed()) {
303 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
304 return PM3_EOPABORTED
;
309 PrintAndLogEx(WARNING
, "Chk keys file, timeouted");
310 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
315 if (resp
.status
!= PM3_SUCCESS
) return resp
.status
;
321 struct kr
*keyresult
= (struct kr
*)&resp
.data
.asBytes
;
322 if (!keyresult
->found
) return PM3_ESOFT
;
324 *key
= bytes_to_num(keyresult
->key
, sizeof(keyresult
->key
));
328 // PM3 imp of J-Run mf_key_brute (part 2)
329 // ref: https://github.com/J-Run/mf_key_brute
330 int mfKeyBrute(uint8_t blockNo
, uint8_t keyType
, uint8_t *key
, uint64_t *resultkey
) {
333 uint8_t found
= false;
334 uint8_t candidates
[CANDIDATE_SIZE
] = {0x00};
335 uint8_t keyBlock
[KEYBLOCK_SIZE
] = {0x00};
337 memset(candidates
, 0, sizeof(candidates
));
338 memset(keyBlock
, 0, sizeof(keyBlock
));
340 // Generate all possible keys for the first two unknown bytes.
341 for (uint16_t i
= 0; i
< 0xFFFF; ++i
) {
343 candidates
[0 + j
] = i
>> 8;
344 candidates
[1 + j
] = i
;
345 candidates
[2 + j
] = key
[2];
346 candidates
[3 + j
] = key
[3];
347 candidates
[4 + j
] = key
[4];
348 candidates
[5 + j
] = key
[5];
351 for (i
= 0, counter
= 1; i
< CANDIDATE_SIZE
; i
+= KEYBLOCK_SIZE
, ++counter
) {
355 // copy candidatekeys to test key block
356 memcpy(keyBlock
, candidates
+ i
, KEYBLOCK_SIZE
);
358 // check a block of generated key candidates.
359 if (mfCheckKeys(blockNo
, keyType
, true, KEYS_IN_BLOCK
, keyBlock
, &key64
) == PM3_SUCCESS
) {
366 if (counter
% 20 == 0)
367 PrintAndLogEx(SUCCESS
, "tried : %s.. \t %u keys", sprint_hex(candidates
+ i
, 6), counter
* KEYS_IN_BLOCK
);
372 // Compare 16 Bits out of cryptostate
373 inline static int Compare16Bits(const void *a
, const void *b
) {
374 if ((*(uint64_t *)b
& 0x00ff000000ff0000) == (*(uint64_t *)a
& 0x00ff000000ff0000)) return 0;
375 if ((*(uint64_t *)b
& 0x00ff000000ff0000) > (*(uint64_t *)a
& 0x00ff000000ff0000)) return 1;
379 // wrapper function for multi-threaded lfsr_recovery32
381 #ifdef __has_attribute
382 #if __has_attribute(force_align_arg_pointer)
383 __attribute__((force_align_arg_pointer
))
386 *nested_worker_thread(void *arg
) {
387 struct Crypto1State
*p1
;
388 StateList_t
*statelist
= arg
;
389 statelist
->head
.slhead
= lfsr_recovery32(statelist
->ks1
, statelist
->nt_enc
^ statelist
->uid
);
391 for (p1
= statelist
->head
.slhead
; p1
->odd
| p1
->even
; p1
++) {};
393 statelist
->len
= p1
- statelist
->head
.slhead
;
394 statelist
->tail
.sltail
= --p1
;
396 qsort(statelist
->head
.slhead
, statelist
->len
, sizeof(uint64_t), Compare16Bits
);
398 return statelist
->head
.slhead
;
401 int mfnested(uint8_t blockNo
, uint8_t keyType
, uint8_t *key
, uint8_t trgBlockNo
, uint8_t trgKeyType
, uint8_t *resultKey
, bool calibrate
) {
404 StateList_t statelists
[2];
405 struct Crypto1State
*p1
, *p2
, *p3
, *p4
;
410 uint8_t target_block
;
411 uint8_t target_keytype
;
415 payload
.block
= blockNo
;
416 payload
.keytype
= keyType
;
417 payload
.target_block
= trgBlockNo
;
418 payload
.target_keytype
= trgKeyType
;
419 payload
.calibrate
= calibrate
;
420 memcpy(payload
.key
, key
, sizeof(payload
.key
));
422 PacketResponseNG resp
;
423 clearCommandBuffer();
424 SendCommandNG(CMD_HF_MIFARE_NESTED
, (uint8_t *)&payload
, sizeof(payload
));
426 if (!WaitForResponseTimeout(CMD_HF_MIFARE_NESTED
, &resp
, 2000)) {
427 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
441 struct p
*package
= (struct p
*)resp
.data
.asBytes
;
443 // error during nested on device side
444 if (package
->isOK
!= PM3_SUCCESS
)
445 return package
->isOK
;
447 memcpy(&uid
, package
->cuid
, sizeof(package
->cuid
));
449 for (uint8_t i
= 0; i
< 2; i
++) {
450 statelists
[i
].blockNo
= package
->block
;
451 statelists
[i
].keyType
= package
->keytype
;
452 statelists
[i
].uid
= uid
;
455 memcpy(&statelists
[0].nt_enc
, package
->nt_a
, sizeof(package
->nt_a
));
456 memcpy(&statelists
[0].ks1
, package
->ks_a
, sizeof(package
->ks_a
));
458 memcpy(&statelists
[1].nt_enc
, package
->nt_b
, sizeof(package
->nt_b
));
459 memcpy(&statelists
[1].ks1
, package
->ks_b
, sizeof(package
->ks_b
));
462 pthread_t thread_id
[2];
464 // create and run worker threads
465 for (uint8_t i
= 0; i
< 2; i
++)
466 pthread_create(thread_id
+ i
, NULL
, nested_worker_thread
, &statelists
[i
]);
468 // wait for threads to terminate:
469 for (uint8_t i
= 0; i
< 2; i
++)
470 pthread_join(thread_id
[i
], (void *)&statelists
[i
].head
.slhead
);
472 // the first 16 Bits of the cryptostate already contain part of our key.
473 // Create the intersection of the two lists based on these 16 Bits and
474 // roll back the cryptostate
475 p1
= p3
= statelists
[0].head
.slhead
;
476 p2
= p4
= statelists
[1].head
.slhead
;
478 while (p1
<= statelists
[0].tail
.sltail
&& p2
<= statelists
[1].tail
.sltail
) {
479 if (Compare16Bits(p1
, p2
) == 0) {
481 struct Crypto1State savestate
;
483 while (Compare16Bits(p1
, &savestate
) == 0 && p1
<= statelists
[0].tail
.sltail
) {
485 lfsr_rollback_word(p3
, statelists
[0].nt_enc
^ statelists
[0].uid
, 0);
490 while (Compare16Bits(p2
, &savestate
) == 0 && p2
<= statelists
[1].tail
.sltail
) {
492 lfsr_rollback_word(p4
, statelists
[1].nt_enc
^ statelists
[1].uid
, 0);
497 while (Compare16Bits(p1
, p2
) == -1) p1
++;
498 while (Compare16Bits(p1
, p2
) == 1) p2
++;
506 statelists
[0].len
= p3
- statelists
[0].head
.slhead
;
507 statelists
[1].len
= p4
- statelists
[1].head
.slhead
;
508 statelists
[0].tail
.sltail
= --p3
;
509 statelists
[1].tail
.sltail
= --p4
;
511 // the statelists now contain possible keys. The key we are searching for must be in the
512 // intersection of both lists
513 qsort(statelists
[0].head
.keyhead
, statelists
[0].len
, sizeof(uint64_t), compare_uint64
);
514 qsort(statelists
[1].head
.keyhead
, statelists
[1].len
, sizeof(uint64_t), compare_uint64
);
515 // Create the intersection
516 statelists
[0].len
= intersection(statelists
[0].head
.keyhead
, statelists
[1].head
.keyhead
);
518 //statelists[0].tail.keytail = --p7;
519 uint32_t keycnt
= statelists
[0].len
;
520 if (keycnt
== 0) goto out
;
522 PrintAndLogEx(SUCCESS
, "Found " _YELLOW_("%u") " key candidates", keycnt
);
524 memset(resultKey
, 0, 6);
527 // The list may still contain several key candidates. Test each of them with mfCheckKeys
528 uint32_t max_keys
= keycnt
> KEYS_IN_BLOCK
? KEYS_IN_BLOCK
: keycnt
;
529 uint8_t keyBlock
[PM3_CMD_DATA_SIZE
] = {0x00};
531 for (uint32_t i
= 0; i
< keycnt
; i
+= max_keys
) {
533 uint64_t start_time
= msclock();
535 uint8_t size
= keycnt
- i
> max_keys
? max_keys
: keycnt
- i
;
538 for (j
= 0; j
< size
; j
++) {
539 crypto1_get_lfsr(statelists
[0].head
.slhead
+ i
, &key64
);
540 num_to_bytes(key64
, 6, keyBlock
+ j
* 6);
543 if (mfCheckKeys(statelists
[0].blockNo
, statelists
[0].keyType
, false, size
, keyBlock
, &key64
) == PM3_SUCCESS
) {
544 free(statelists
[0].head
.slhead
);
545 free(statelists
[1].head
.slhead
);
546 num_to_bytes(key64
, 6, resultKey
);
548 PrintAndLogEx(SUCCESS
, "\ntarget block:%3u key type: %c -- found valid key [ " _GREEN_("%s") "]",
550 package
->keytype
? 'B' : 'A',
551 sprint_hex_inrow(resultKey
, 6)
556 float bruteforce_per_second
= (float)(i
+ max_keys
) / ((msclock() - start_time
) / 1000.0);
557 PrintAndLogEx(INPLACE
, "%6d/%u keys | %5.1f keys/sec | worst case %6.1f seconds remaining", i
, keycnt
, bruteforce_per_second
, (keycnt
- i
) / bruteforce_per_second
);
561 PrintAndLogEx(SUCCESS
, "\ntarget block:%3u key type: %c",
563 package
->keytype
? 'B' : 'A'
566 free(statelists
[0].head
.slhead
);
567 free(statelists
[1].head
.slhead
);
572 int mfStaticNested(uint8_t blockNo
, uint8_t keyType
, uint8_t *key
, uint8_t trgBlockNo
, uint8_t trgKeyType
, uint8_t *resultKey
) {
575 StateList_t statelists
[1];
576 struct Crypto1State
*p1
, *p3
;
581 uint8_t target_block
;
582 uint8_t target_keytype
;
585 payload
.block
= blockNo
;
586 payload
.keytype
= keyType
;
587 payload
.target_block
= trgBlockNo
;
588 payload
.target_keytype
= trgKeyType
;
589 memcpy(payload
.key
, key
, sizeof(payload
.key
));
591 PacketResponseNG resp
;
592 clearCommandBuffer();
593 SendCommandNG(CMD_HF_MIFARE_STATIC_NESTED
, (uint8_t *)&payload
, sizeof(payload
));
595 if (!WaitForResponseTimeout(CMD_HF_MIFARE_STATIC_NESTED
, &resp
, 2000))
598 if (resp
.status
!= PM3_SUCCESS
)
609 struct p
*package
= (struct p
*)resp
.data
.asBytes
;
611 // error during collecting static nested information
612 if (package
->isOK
== 0) return PM3_EUNDEF
;
614 memcpy(&uid
, package
->cuid
, sizeof(package
->cuid
));
616 statelists
[0].blockNo
= package
->block
;
617 statelists
[0].keyType
= package
->keytype
;
618 statelists
[0].uid
= uid
;
620 memcpy(&statelists
[0].nt_enc
, package
->nt
, sizeof(package
->nt
));
621 memcpy(&statelists
[0].ks1
, package
->ks
, sizeof(package
->ks
));
626 // create and run worker thread
627 pthread_create(&t
, NULL
, nested_worker_thread
, &statelists
[0]);
629 // wait for thread to terminate:
630 pthread_join(t
, (void *)&statelists
[0].head
.slhead
);
632 // the first 16 Bits of the cryptostate already contain part of our key.
633 p1
= p3
= statelists
[0].head
.slhead
;
635 // create key candidates.
636 while (p1
<= statelists
[0].tail
.sltail
) {
637 struct Crypto1State savestate
;
639 while (Compare16Bits(p1
, &savestate
) == 0 && p1
<= statelists
[0].tail
.sltail
) {
641 lfsr_rollback_word(p3
, statelists
[0].nt_enc
^ statelists
[0].uid
, 0);
649 statelists
[0].len
= p3
- statelists
[0].head
.slhead
;
650 statelists
[0].tail
.sltail
= --p3
;
652 uint32_t keycnt
= statelists
[0].len
;
653 if (keycnt
== 0) goto out
;
655 PrintAndLogEx(SUCCESS
, "Found " _YELLOW_("%u") " key candidates", keycnt
);
657 memset(resultKey
, 0, 6);
660 // The list may still contain several key candidates. Test each of them with mfCheckKeys
661 uint32_t maxkeysinblock
= IfPm3Flash() ? 1000 : KEYS_IN_BLOCK
;
662 uint32_t max_keys_chunk
= keycnt
> maxkeysinblock
? maxkeysinblock
: keycnt
;
664 uint8_t *mem
= calloc((maxkeysinblock
* 6) + 5, sizeof(uint8_t));
666 free(statelists
[0].head
.slhead
);
670 uint8_t *p_keyblock
= mem
+ 5;
671 mem
[0] = statelists
[0].keyType
;
672 mem
[1] = statelists
[0].blockNo
;
674 mem
[3] = ((max_keys_chunk
>> 8) & 0xFF);
675 mem
[4] = (max_keys_chunk
& 0xFF);
678 strncpy((char *)destfn
, "static_nested_000.bin", sizeof(destfn
) - 1);
680 uint64_t start_time
= msclock();
681 for (uint32_t i
= 0; i
< keycnt
; i
+= max_keys_chunk
) {
684 while (kbd_enter_pressed()) {
685 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
686 PrintAndLogEx(NORMAL
, "");
688 return PM3_EOPABORTED
;
693 uint32_t chunk
= keycnt
- i
> max_keys_chunk
? max_keys_chunk
: keycnt
- i
;
695 // copy x keys to device.
696 for (uint32_t j
= 0; j
< chunk
; j
++) {
697 crypto1_get_lfsr(statelists
[0].head
.slhead
+ i
+ j
, &key64
);
698 num_to_bytes(key64
, 6, p_keyblock
+ j
* 6);
701 // check a block of generated key candidates.
704 mem
[3] = ((chunk
>> 8) & 0xFF);
705 mem
[4] = (chunk
& 0xFF);
708 res
= flashmem_spiffs_load((char *)destfn
, mem
, 5 + (chunk
* 6));
709 if (res
!= PM3_SUCCESS
) {
710 PrintAndLogEx(WARNING
, "\nSPIFFS upload failed");
714 res
= mfCheckKeys_file(destfn
, &key64
);
716 res
= mfCheckKeys(statelists
[0].blockNo
, statelists
[0].keyType
, false, chunk
, mem
, &key64
);
719 if (res
== PM3_SUCCESS
) {
721 free(statelists
[0].head
.slhead
);
724 num_to_bytes(key64
, 6, resultKey
);
726 PrintAndLogEx(NORMAL
, "");
727 PrintAndLogEx(SUCCESS
, "target block:%3u key type: %c -- found valid key [ " _GREEN_("%s") "]",
729 package
->keytype
? 'B' : 'A',
730 sprint_hex_inrow(resultKey
, 6)
733 } else if (res
== PM3_ETIMEOUT
|| res
== PM3_EOPABORTED
) {
734 PrintAndLogEx(NORMAL
, "");
739 float bruteforce_per_second
= (float)(i
+ max_keys_chunk
) / ((msclock() - start_time
) / 1000.0);
740 PrintAndLogEx(INPLACE
, "%6u/%u keys | %5.1f keys/sec | worst case %6.1f seconds", i
, keycnt
, bruteforce_per_second
, (keycnt
- i
) / bruteforce_per_second
);
747 PrintAndLogEx(SUCCESS
, "\ntarget block:%3u key type: %c",
749 package
->keytype
? 'B' : 'A'
752 free(statelists
[0].head
.slhead
);
757 int mfReadSector(uint8_t sectorNo
, uint8_t keyType
, uint8_t *key
, uint8_t *data
) {
759 clearCommandBuffer();
760 SendCommandMIX(CMD_HF_MIFARE_READSC
, sectorNo
, keyType
, 0, key
, 6);
761 PacketResponseNG resp
;
762 if (WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) {
763 uint8_t isOK
= resp
.oldarg
[0] & 0xff;
766 memcpy(data
, resp
.data
.asBytes
, mfNumBlocksPerSector(sectorNo
) * 16);
772 PrintAndLogEx(DEBUG
, "Command execute timeout");
778 int mfReadBlock(uint8_t blockNo
, uint8_t keyType
, uint8_t *key
, uint8_t *data
) {
779 mf_readblock_t payload
= {
783 memcpy(payload
.key
, key
, sizeof(payload
.key
));
785 clearCommandBuffer();
786 SendCommandNG(CMD_HF_MIFARE_READBL
, (uint8_t *)&payload
, sizeof(mf_readblock_t
));
787 PacketResponseNG resp
;
788 if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL
, &resp
, 1500)) {
789 memcpy(data
, resp
.data
.asBytes
, 16);
791 if (resp
.status
!= PM3_SUCCESS
) {
792 PrintAndLogEx(DEBUG
, "failed reading block");
796 PrintAndLogEx(DEBUG
, "Command execute timeout");
803 int mfEmlGetMem(uint8_t *data
, int blockNum
, int blocksCount
) {
805 size_t size
= blocksCount
* 16;
806 if (size
> PM3_CMD_DATA_SIZE
) {
815 payload
.blockno
= blockNum
;
816 payload
.blockcnt
= blocksCount
;
818 clearCommandBuffer();
819 SendCommandNG(CMD_HF_MIFARE_EML_MEMGET
, (uint8_t *)&payload
, sizeof(payload
));
821 PacketResponseNG resp
;
822 if (WaitForResponseTimeout(CMD_HF_MIFARE_EML_MEMGET
, &resp
, 1500) == 0) {
823 PrintAndLogEx(WARNING
, "Command execute timeout");
827 if (resp
.status
== PM3_SUCCESS
)
828 memcpy(data
, resp
.data
.asBytes
, size
);
833 int mfEmlSetMem(uint8_t *data
, int blockNum
, int blocksCount
) {
834 return mfEmlSetMem_xt(data
, blockNum
, blocksCount
, 16);
837 int mfEmlSetMem_xt(uint8_t *data
, int blockNum
, int blocksCount
, int blockBtWidth
) {
846 size_t size
= blocksCount
* blockBtWidth
;
847 if (size
> (PM3_CMD_DATA_SIZE
- sizeof(struct p
))) {
851 size_t paylen
= sizeof(struct p
) + size
;
852 struct p
*payload
= calloc(1, paylen
);
854 payload
->blockno
= blockNum
;
855 payload
->blockcnt
= blocksCount
;
856 payload
->blockwidth
= blockBtWidth
;
857 memcpy(payload
->data
, data
, size
);
859 clearCommandBuffer();
860 SendCommandNG(CMD_HF_MIFARE_EML_MEMSET
, (uint8_t *)payload
, paylen
);
866 int mfCSetUID(uint8_t *uid
, uint8_t uidlen
, uint8_t *atqa
, uint8_t *sak
, uint8_t *old_uid
, uint8_t *verifed_uid
, uint8_t wipecard
) {
868 uint8_t params
= MAGIC_SINGLE
;
870 memset(block0
, 0x00, sizeof(block0
));
872 int res
= mfCGetBlock(0, block0
, params
);
874 PrintAndLogEx(SUCCESS
, "old block 0... %s", sprint_hex_inrow(block0
, sizeof(block0
)));
876 memcpy(old_uid
, block0
, uidlen
);
879 PrintAndLogEx(INFO
, "couldn't get old data. Will write over the last bytes of block 0");
882 // fill in the new values
884 memcpy(block0
, uid
, uidlen
);
887 block0
[4] = block0
[0] ^ block0
[1] ^ block0
[2] ^ block0
[3];
889 // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)
898 } else if (uidlen
== 7) {
899 block0
[7] = block0
[0] ^ block0
[1] ^ block0
[2] ^ block0
[3] ^ block0
[4] ^ block0
[5] ^ block0
[6];
901 // mifare classic SAK(byte 8) and ATQA(byte 9 and 10, reversed)
907 block0
[10] = atqa
[0];
911 PrintAndLogEx(SUCCESS
, "new block 0... %s", sprint_hex_inrow(block0
, 16));
914 params
|= MAGIC_WIPE
;
917 res
= mfCSetBlock(0, block0
, NULL
, params
);
918 if (res
== PM3_SUCCESS
) {
919 params
= MAGIC_SINGLE
;
920 memset(block0
, 0, sizeof(block0
));
921 res
= mfCGetBlock(0, block0
, params
);
924 memcpy(verifed_uid
, block0
, uidlen
);
931 int mfCWipe(uint8_t *uid
, uint8_t *atqa
, uint8_t *sak
) {
932 uint8_t block0
[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF};
933 uint8_t blockD
[16] = {0x00};
934 uint8_t blockK
[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
935 uint8_t params
= MAGIC_SINGLE
;
938 memcpy(block0
, uid
, 4);
939 block0
[4] = block0
[0] ^ block0
[1] ^ block0
[2] ^ block0
[3];
949 for (int blockNo
= 0; blockNo
< 4 * 16; blockNo
++) {
950 for (int retry
= 0; retry
< 3; retry
++) {
952 PrintAndLogEx(INPLACE
, "wipe block %d", blockNo
);
955 res
= mfCSetBlock(blockNo
, block0
, NULL
, params
);
957 if (mfIsSectorTrailer(blockNo
))
958 res
= mfCSetBlock(blockNo
, blockK
, NULL
, params
);
960 res
= mfCSetBlock(blockNo
, blockD
, NULL
, params
);
963 if (res
== PM3_SUCCESS
)
966 PrintAndLogEx(WARNING
, "retry block %d ...", blockNo
);
970 PrintAndLogEx(ERR
, "error setting block %d (%d)", blockNo
, res
);
975 PrintAndLogEx(NORMAL
, "");
979 int mfCSetBlock(uint8_t blockNo
, uint8_t *data
, uint8_t *uid
, uint8_t params
) {
981 clearCommandBuffer();
982 SendCommandMIX(CMD_HF_MIFARE_CSETBL
, params
, blockNo
, 0, data
, 16);
983 PacketResponseNG resp
;
984 if (WaitForResponseTimeout(CMD_ACK
, &resp
, 3500)) {
985 uint8_t isOK
= resp
.oldarg
[0] & 0xff;
987 memcpy(uid
, resp
.data
.asBytes
, 4);
991 PrintAndLogEx(WARNING
, "command execute timeout");
997 int mfCGetBlock(uint8_t blockNo
, uint8_t *data
, uint8_t params
) {
998 clearCommandBuffer();
999 SendCommandMIX(CMD_HF_MIFARE_CGETBL
, params
, blockNo
, 0, NULL
, 0);
1000 PacketResponseNG resp
;
1001 if (WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) {
1002 uint8_t isOK
= resp
.oldarg
[0] & 0xff;
1005 memcpy(data
, resp
.data
.asBytes
, 16);
1007 PrintAndLogEx(WARNING
, "command execute timeout");
1008 return PM3_ETIMEOUT
;
1013 int mfGen3UID(uint8_t *uid
, uint8_t uidlen
, uint8_t *oldUid
) {
1014 clearCommandBuffer();
1015 SendCommandMIX(CMD_HF_MIFARE_GEN3UID
, uidlen
, 0, 0, uid
, uidlen
);
1016 PacketResponseNG resp
;
1017 if (WaitForResponseTimeout(CMD_HF_MIFARE_GEN3UID
, &resp
, 3500)) {
1018 if (resp
.status
== PM3_SUCCESS
&& oldUid
) {
1019 memcpy(oldUid
, resp
.data
.asBytes
, uidlen
);
1023 PrintAndLogEx(WARNING
, "Command execute timeout");
1024 return PM3_ETIMEOUT
;
1028 int mfGen3Block(uint8_t *block
, int blockLen
, uint8_t *newBlock
) {
1029 clearCommandBuffer();
1030 SendCommandMIX(CMD_HF_MIFARE_GEN3BLK
, blockLen
, 0, 0, block
, 16);
1031 PacketResponseNG resp
;
1032 if (WaitForResponseTimeout(CMD_HF_MIFARE_GEN3BLK
, &resp
, 3500)) {
1033 if (resp
.status
== PM3_SUCCESS
&& newBlock
) {
1034 memcpy(newBlock
, resp
.data
.asBytes
, 16);
1038 PrintAndLogEx(WARNING
, "Command execute timeout");
1039 return PM3_ETIMEOUT
;
1043 int mfGen3Freeze(void) {
1044 clearCommandBuffer();
1045 SendCommandNG(CMD_HF_MIFARE_GEN3FREEZ
, NULL
, 0);
1046 PacketResponseNG resp
;
1047 if (WaitForResponseTimeout(CMD_HF_MIFARE_GEN3FREEZ
, &resp
, 3500)) {
1050 PrintAndLogEx(WARNING
, "Command execute timeout");
1051 return PM3_ETIMEOUT
;
1055 int mfG3GetBlock(uint8_t blockno
, uint8_t *data
) {
1059 payload
.blockno
= blockno
;
1061 clearCommandBuffer();
1062 SendCommandNG(CMD_HF_MIFARE_G3_RDBL
, (uint8_t*)&payload
, sizeof(payload
));
1063 PacketResponseNG resp
;
1064 if (WaitForResponseTimeout(CMD_HF_MIFARE_G3_RDBL
, &resp
, 1500)) {
1065 if (resp
.status
!= PM3_SUCCESS
)
1067 memcpy(data
, resp
.data
.asBytes
, 16);
1069 PrintAndLogEx(WARNING
, "command execute timeout");
1070 return PM3_ETIMEOUT
;
1077 uint32_t cuid
= 0; // uid part used for crypto1.
1079 void mf_crypto1_decrypt(struct Crypto1State
*pcs
, uint8_t *data
, int len
, bool isEncrypted
) {
1081 for (int i
= 0; i
< len
; i
++)
1082 data
[i
] = crypto1_byte(pcs
, 0x00, isEncrypted
) ^ data
[i
];
1085 bt
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 0)) << 0;
1086 bt
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 1)) << 1;
1087 bt
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 2)) << 2;
1088 bt
|= (crypto1_bit(pcs
, 0, isEncrypted
) ^ BIT(data
[0], 3)) << 3;
1093 int tryDecryptWord(uint32_t nt
, uint32_t ar_enc
, uint32_t at_enc
, uint8_t *data
, int len
) {
1094 PrintAndLogEx(SUCCESS
, "encrypted data... %s", sprint_hex(data
, len
));
1095 struct Crypto1State
*s
;
1096 uint32_t ks2
= ar_enc
^ prng_successor(nt
, 64);
1097 uint32_t ks3
= at_enc
^ prng_successor(nt
, 96);
1098 s
= lfsr_recovery64(ks2
, ks3
);
1099 mf_crypto1_decrypt(s
, data
, len
, false);
1100 PrintAndLogEx(SUCCESS
, "decrypted data... " _YELLOW_("%s"), sprint_hex(data
, len
));
1101 PrintAndLogEx(NORMAL
, "");
1107 * function performs a partial AUTH, where it tries to authenticate against block0, key A, but only collects tag nonce.
1108 * the tag nonce is check to see if it has a predictable PRNG.
1110 * TRUE if tag uses WEAK prng (ie Now the NACK bug also needs to be present for Darkside attack)
1111 * FALSE is tag uses HARDEND prng (ie hardnested attack possible, with known key)
1113 int detect_classic_prng(void) {
1115 PacketResponseNG resp
, respA
;
1116 uint8_t cmd
[] = {MIFARE_AUTH_KEYA
, 0x00};
1117 uint32_t flags
= ISO14A_CONNECT
| ISO14A_RAW
| ISO14A_APPEND_CRC
| ISO14A_NO_RATS
;
1119 clearCommandBuffer();
1120 SendCommandMIX(CMD_HF_ISO14443A_READER
, flags
, sizeof(cmd
), 0, cmd
, sizeof(cmd
));
1122 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 2000)) {
1123 PrintAndLogEx(WARNING
, "PRNG UID: Reply timeout.");
1124 return PM3_ETIMEOUT
;
1127 // if select tag failed.
1128 if (resp
.oldarg
[0] == 0) {
1129 PrintAndLogEx(ERR
, "error: selecting tag failed, can't detect prng\n");
1130 return PM3_ERFTRANS
;
1132 if (!WaitForResponseTimeout(CMD_ACK
, &respA
, 2500)) {
1133 PrintAndLogEx(WARNING
, "PRNG data: Reply timeout.");
1134 return PM3_ETIMEOUT
;
1138 if (respA
.oldarg
[0] != 4) {
1139 PrintAndLogEx(ERR
, "PRNG data error: Wrong length: %"PRIu64
, respA
.oldarg
[0]);
1143 uint32_t nonce
= bytes_to_num(respA
.data
.asBytes
, respA
.oldarg
[0]);
1144 return validate_prng_nonce(nonce
);
1146 /* Detect Mifare Classic NACK bug
1149 0 = error during test / aborted
1151 2 = has not nack bug
1152 3 = always leak nacks (clones)
1154 int detect_classic_nackbug(bool verbose
) {
1156 clearCommandBuffer();
1157 SendCommandNG(CMD_HF_MIFARE_NACK_DETECT
, NULL
, 0);
1158 PacketResponseNG resp
;
1160 PrintAndLogEx(INFO
, "Checking for NACK bug");
1163 PrintAndLogEx(SUCCESS
, "press pm3-button on the Proxmark3 device to abort both Proxmark3 and client.\n");
1167 PrintAndLogEx(NORMAL
, "." NOLF
);
1168 if (kbd_enter_pressed()) {
1169 return PM3_EOPABORTED
;
1172 if (WaitForResponseTimeout(CMD_HF_MIFARE_NACK_DETECT
, &resp
, 500)) {
1174 PrintAndLogEx(NORMAL
, "");
1176 if (resp
.status
== PM3_EOPABORTED
) {
1177 PrintAndLogEx(WARNING
, "button pressed. Aborted.");
1178 return PM3_EOPABORTED
;
1181 uint8_t ok
= resp
.data
.asBytes
[0];
1182 uint8_t nacks
= resp
.data
.asBytes
[1];
1183 uint16_t auths
= bytes_to_num(resp
.data
.asBytes
+ 2, 2);
1186 PrintAndLogEx(SUCCESS
, "num of auth requests : %u", auths
);
1187 PrintAndLogEx(SUCCESS
, "num of received NACK : %u", nacks
);
1193 PrintAndLogEx(FAILED
, "card random number generator is not predictable.");
1194 PrintAndLogEx(WARNING
, "detection failed");
1199 PrintAndLogEx(FAILED
, "card random number generator seems to be based on the well-known generating polynomial");
1200 PrintAndLogEx(FAILED
, "with 16 effective bits only, but shows unexpected behavior, try again.");
1205 PrintAndLogEx(SUCCESS
, "NACK test: " _GREEN_("always leak NACK"));
1208 PrintAndLogEx(SUCCESS
, "NACK test: " _GREEN_("detected"));
1211 PrintAndLogEx(SUCCESS
, "NACK test: " _GREEN_("no bug"));
1214 PrintAndLogEx(ERR
, "errorcode from device " _RED_("[%i]"), ok
);
1223 /* Detect Mifare Classic Static / Fixed nonce
1224 detects special magic cards that has a static / fixed nonce
1226 0 = has normal nonce
1227 1 = has static/fixed nonce
1230 int detect_classic_static_nonce(void) {
1232 clearCommandBuffer();
1233 SendCommandNG(CMD_HF_MIFARE_STATIC_NONCE
, NULL
, 0);
1234 PacketResponseNG resp
;
1235 if (WaitForResponseTimeout(CMD_HF_MIFARE_STATIC_NONCE
, &resp
, 1000)) {
1237 if (resp
.status
== PM3_ESOFT
)
1240 return resp
.data
.asBytes
[0];
1245 /* try to see if card responses to "Chinese magic backdoor" commands. */
1246 int detect_mf_magic(bool is_mfc
) {
1248 uint8_t isGeneration
= 0;
1249 PacketResponseNG resp
;
1250 clearCommandBuffer();
1251 uint8_t payload
[] = { is_mfc
};
1252 SendCommandNG(CMD_HF_MIFARE_CIDENT
, payload
, sizeof(payload
));
1253 if (WaitForResponseTimeout(CMD_HF_MIFARE_CIDENT
, &resp
, 1500)) {
1254 if (resp
.status
== PM3_SUCCESS
)
1255 isGeneration
= resp
.data
.asBytes
[0];
1258 switch (isGeneration
) {
1260 PrintAndLogEx(SUCCESS
, "Magic capabilities : " _GREEN_("Gen 1a"));
1263 PrintAndLogEx(SUCCESS
, "Magic capabilities : " _GREEN_("Gen 1b"));
1266 PrintAndLogEx(SUCCESS
, "Magic capabilities : " _GREEN_("Gen 2 / CUID"));
1269 PrintAndLogEx(SUCCESS
, "Magic capabilities : possibly " _GREEN_("Gen 3 / APDU"));
1271 case MAGIC_GEN_UNFUSED
:
1272 PrintAndLogEx(SUCCESS
, "Magic capabilities : " _GREEN_("Write Once / FUID"));
1275 PrintAndLogEx(SUCCESS
, "Magic capabilities : " _GREEN_("super card"));
1278 PrintAndLogEx(SUCCESS
, "Magic capabilities : " _GREEN_("NTAG21x"));
1283 return isGeneration
;
1286 int detect_mfc_ev1_signature(uint8_t *signature
) {
1287 if (signature
== NULL
) {
1290 uint8_t sign
[32] = {0};
1291 uint8_t key
[] = {0x4b, 0x79, 0x1b, 0xea, 0x7b, 0xcc};
1292 int res
= mfReadBlock(69, 1, key
, sign
);
1293 if (res
== PM3_SUCCESS
) {
1294 res
= mfReadBlock(70, 1, key
, sign
+ 16);
1295 if (res
== PM3_SUCCESS
) {
1296 memcpy(signature
, sign
, sizeof(sign
));