1 //-----------------------------------------------------------------------------
2 // Copyright (C) Merlok - 2017
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
8 //-----------------------------------------------------------------------------
9 // Command: hf mf list. It shows data from arm buffer.
10 //-----------------------------------------------------------------------------
12 #include "cmdhflist.h"
18 #include "commonutil.h" // ARRAYLEN
19 #include "mifare/mifarehost.h"
20 #include "parity.h" // oddparity
23 #include "crapto1/crapto1.h"
24 #include "protocols.h"
25 #include "cmdhficlass.h"
37 static enum MifareAuthSeq MifareAuthState
;
38 static TAuthData AuthData
;
40 void ClearAuthData(void) {
43 AuthData
.first_auth
= true;
49 * @brief iso14443A_CRC_check Checks CRC in command or response
53 * @return 0 : CRC-command, CRC not ok
54 * 1 : CRC-command, CRC ok
58 uint8_t iso14443A_CRC_check(bool isResponse
, uint8_t *d
, uint8_t n
) {
60 if (isResponse
&& (n
< 6)) return 2;
62 d
[0] >= ISO14443A_CMD_ANTICOLL_OR_SELECT
&&
63 d
[0] <= ISO14443A_CMD_ANTICOLL_OR_SELECT_3
) {
66 return check_crc(CRC_14443_A
, d
, n
);
69 uint8_t mifare_CRC_check(bool isResponse
, uint8_t *data
, uint8_t len
) {
70 switch (MifareAuthState
) {
73 return iso14443A_CRC_check(isResponse
, data
, len
);
86 * @brief iso14443B_CRC_check Checks CRC
89 * @return 0 : CRC-command, CRC not ok
90 * 1 : CRC-command, CRC ok
93 uint8_t iso14443B_CRC_check(uint8_t *d
, uint8_t n
) {
94 return check_crc(CRC_14443_B
, d
, n
);
97 uint8_t iso15693_CRC_check(uint8_t *d
, uint8_t n
) {
98 return check_crc(CRC_15693
, d
, n
);
101 uint8_t felica_CRC_check(uint8_t *d
, uint8_t n
) {
102 return check_crc(CRC_FELICA
, d
, n
);
106 * @brief iclass_CRC_Ok Checks CRC in command or response
110 * @return 0 : CRC-command, CRC not ok
111 * 1 : CRC-command, CRC ok
112 * 2 : Not crc-command
114 uint8_t iclass_CRC_check(bool isResponse
, uint8_t *d
, uint8_t n
) {
115 //CRC commands (and responses) are all at least 4 bytes
119 //Don't include the command byte
122 These commands should have CRC. Total length leftmost
125 12 UPDATE - unsecured, ends with CRC16
126 14 UPDATE - secured, ends with signature instead
129 //Covers three of them
130 if (n
== 4 || n
== 12) {
131 return check_crc(CRC_ICLASS
, d
+ 1, n
- 1);
136 These tag responses should have CRC. Total length leftmost
138 10 READ data[8] crc[2]
139 34 READ4 data[32]crc[2]
140 10 UPDATE data[8] crc[2]
141 10 SELECT csn[8] crc[2]
142 10 IDENTIFY asnb[8] crc[2]
143 10 PAGESEL block1[8] crc[2]
144 10 DETECT csn[8] crc[2]
148 4 CHECK chip_response[4]
153 In conclusion, without looking at the command; any response
154 of length 10 or 34 should have CRC
156 if (n
!= 10 && n
!= 34) return true;
158 return check_crc(CRC_ICLASS
, d
, n
);
161 int applyIso14443a(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
163 case ISO14443A_CMD_WUPA
:
164 snprintf(exp
, size
, "WUPA");
166 case ISO14443A_CMD_ANTICOLL_OR_SELECT
: {
167 // 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
168 // 93 50 = Bit oriented anti-collision (usage: 9350+ up to 5bytes, 9350 answer - up to 5bytes UID+BCC)
169 // 93 70 = Select (usage: 9370+5bytes 9370 answer - answer: 1byte SAK)
171 snprintf(exp
, size
, "SELECT_UID");
172 else if (cmd
[1] == 0x20 || cmd
[1] == 0x50)
173 snprintf(exp
, size
, "ANTICOLL");
175 snprintf(exp
, size
, "SELECT_XXX");
178 case ISO14443A_CMD_ANTICOLL_OR_SELECT_2
: {
179 //95 20 = Anticollision of cascade level2
180 //95 50 = Bit oriented anti-collision level2
181 //95 70 = Select of cascade level2
183 snprintf(exp
, size
, "SELECT_UID-2");
184 else if (cmd
[1] == 0x20 || cmd
[1] == 0x50)
185 snprintf(exp
, size
, "ANTICOLL-2");
187 snprintf(exp
, size
, "SELECT_XXX-2");
190 case ISO14443A_CMD_ANTICOLL_OR_SELECT_3
: {
191 //97 20 = Anticollision of cascade level3
192 //97 50 = Bit oriented anti-collision level3
193 //97 70 = Select of cascade level3
195 snprintf(exp
, size
, "SELECT_UID-3");
196 else if (cmd
[1] == 0x20 || cmd
[1] == 0x50)
197 snprintf(exp
, size
, "ANTICOLL-3");
199 snprintf(exp
, size
, "SELECT_XXX-3");
202 case ISO14443A_CMD_REQA
:
203 snprintf(exp
, size
, "REQA");
205 case ISO14443A_CMD_READBLOCK
:
206 snprintf(exp
, size
, "READBLOCK(%d)", cmd
[1]);
208 case ISO14443A_CMD_WRITEBLOCK
:
209 snprintf(exp
, size
, "WRITEBLOCK(%d)", cmd
[1]);
211 case ISO14443A_CMD_HALT
:
212 snprintf(exp
, size
, "HALT");
213 MifareAuthState
= masNone
;
215 case ISO14443A_CMD_RATS
:
216 snprintf(exp
, size
, "RATS");
218 case ISO14443A_CMD_PPS
:
219 snprintf(exp
, size
, "PPS");
221 case ISO14443A_CMD_OPTS
:
222 snprintf(exp
, size
, "OPTIONAL TIMESLOT");
225 snprintf(exp
, size
, "INC(%d)", cmd
[1]);
228 snprintf(exp
, size
, "DEC(%d)", cmd
[1]);
230 case MIFARE_CMD_RESTORE
:
232 snprintf(exp
, size
, "RESTORE(%d)", cmd
[1]);
236 case MIFARE_CMD_TRANSFER
:
237 snprintf(exp
, size
, "TRANSFER(%d)", cmd
[1]);
239 case MIFARE_AUTH_KEYA
: {
241 snprintf(exp
, size
, "AUTH-A(%d)", cmd
[1]);
242 MifareAuthState
= masNt
;
244 // case MIFARE_ULEV1_VERSION : both 0x60.
245 snprintf(exp
, size
, "EV1 VERSION");
249 case MIFARE_AUTH_KEYB
: {
250 MifareAuthState
= masNt
;
251 snprintf(exp
, size
, "AUTH-B(%d)", cmd
[1]);
254 case MIFARE_MAGICWUPC1
:
255 snprintf(exp
, size
, "MAGIC WUPC1");
257 case MIFARE_MAGICWUPC2
:
258 snprintf(exp
, size
, "MAGIC WUPC2");
260 case MIFARE_MAGICWIPEC
:
261 snprintf(exp
, size
, "MAGIC WIPEC");
263 case MIFARE_ULC_AUTH_1
:
264 snprintf(exp
, size
, "AUTH ");
266 case MIFARE_ULC_AUTH_2
:
267 snprintf(exp
, size
, "AUTH_ANSW");
269 case MIFARE_ULEV1_AUTH
:
271 snprintf(exp
, size
, "PWD-AUTH KEY: " _YELLOW_("0x%02x%02x%02x%02x"), cmd
[1], cmd
[2], cmd
[3], cmd
[4]);
273 snprintf(exp
, size
, "PWD-AUTH");
275 case MIFARE_ULEV1_FASTREAD
: {
276 if (cmdsize
>= 3 && cmd
[2] <= 0xE6)
277 snprintf(exp
, size
, "READ RANGE (%d-%d)", cmd
[1], cmd
[2]);
279 // outside limits, useful for some tags...
280 snprintf(exp
, size
, "READ RANGE (%d-%d) (?)", cmd
[1], cmd
[2]);
283 case MIFARE_ULC_WRITE
: {
285 snprintf(exp
, size
, "WRITEBLOCK(%d)", cmd
[1]);
287 // outside limits, useful for some tags...
288 snprintf(exp
, size
, "WRITEBLOCK(%d) (?)", cmd
[1]);
291 case MIFARE_ULEV1_READ_CNT
: {
293 snprintf(exp
, size
, "READ CNT(%d)", cmd
[1]);
295 snprintf(exp
, size
, "?");
298 case MIFARE_ULEV1_INCR_CNT
: {
300 snprintf(exp
, size
, "INCR(%d)", cmd
[1]);
302 snprintf(exp
, size
, "?");
305 case MIFARE_ULEV1_READSIG
:
306 snprintf(exp
, size
, "READ SIG");
308 case MIFARE_ULEV1_CHECKTEAR
:
309 snprintf(exp
, size
, "CHK TEARING(%d)", cmd
[1]);
311 case MIFARE_ULEV1_VCSL
:
312 snprintf(exp
, size
, "VCSL");
314 case MIFARE_ULNANO_WRITESIG
:
315 snprintf(exp
, size
, "WRITE SIG");
317 case MIFARE_ULNANO_LOCKSIG
: {
319 snprintf(exp
, size
, "UNLOCK SIG");
320 else if (cmd
[1] == 2)
321 snprintf(exp
, size
, "LOCK SIG");
323 snprintf(exp
, size
, "?");
332 void annotateIso14443a(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
333 applyIso14443a(exp
, size
, cmd
, cmdsize
);
336 void annotateIclass(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
, bool isResponse
) {
338 enum pico_state
{PICO_NONE
, PICO_SELECT
, PICO_AUTH_EPURSE
, PICO_AUTH_MACS
};
339 static enum pico_state curr_state
= PICO_NONE
;
340 static uint8_t csn
[8];
341 static uint8_t epurse
[8];
342 static uint8_t rmac
[4];
343 static uint8_t tmac
[4];
345 if (isResponse
== false) {
346 uint8_t c
= cmd
[0] & 0x0F;
348 for (uint8_t i
= 0; i
< 7; i
++) {
349 parity
^= (cmd
[0] >> i
) & 1;
353 case ICLASS_CMD_HALT
:
354 snprintf(exp
, size
, "HALT");
355 curr_state
= PICO_NONE
;
357 case ICLASS_CMD_SELECT
:
358 snprintf(exp
, size
, "SELECT");
359 curr_state
= PICO_SELECT
;
361 case ICLASS_CMD_ACTALL
:
362 snprintf(exp
, size
, "ACTALL");
363 curr_state
= PICO_NONE
;
365 case ICLASS_CMD_DETECT
:
366 snprintf(exp
, size
, "DETECT");
367 curr_state
= PICO_NONE
;
369 case ICLASS_CMD_CHECK
:
370 snprintf(exp
, size
, "CHECK");
371 curr_state
= PICO_AUTH_MACS
;
372 memcpy(rmac
, cmd
+ 1, 4);
373 memcpy(tmac
, cmd
+ 5, 4);
375 case ICLASS_CMD_READ4
:
376 snprintf(exp
, size
, "READ4(%d)", cmd
[1]);
378 case ICLASS_CMD_READ_OR_IDENTIFY
: {
381 snprintf(exp
, size
, "READ(%d)", cmd
[1]);
383 snprintf(exp
, size
, "IDENTIFY");
387 case ICLASS_CMD_PAGESEL
:
388 snprintf(exp
, size
, "PAGESEL(%d)", cmd
[1]);
389 curr_state
= PICO_NONE
;
391 case ICLASS_CMD_UPDATE
:
392 snprintf(exp
, size
, "UPDATE(%d)", cmd
[1]);
393 curr_state
= PICO_NONE
;
395 case ICLASS_CMD_READCHECK
:
396 if (ICLASS_CREDIT(cmd
[0])) {
397 snprintf(exp
, size
, "READCHECK[Kc](%d)", cmd
[1]);
398 curr_state
= PICO_AUTH_EPURSE
;
400 snprintf(exp
, size
, "READCHECK[Kd](%d)", cmd
[1]);
401 curr_state
= PICO_AUTH_EPURSE
;
405 snprintf(exp
, size
, "ACT");
406 curr_state
= PICO_NONE
;
409 snprintf(exp
, size
, "?");
410 curr_state
= PICO_NONE
;
416 if (curr_state
== PICO_SELECT
) {
418 curr_state
= PICO_NONE
;
419 } else if (curr_state
== PICO_AUTH_EPURSE
) {
420 memcpy(epurse
, cmd
, 8);
421 } else if (curr_state
== PICO_AUTH_MACS
) {
424 if (check_known_default(csn
, epurse
, rmac
, tmac
, key
)) {
425 snprintf(exp
, size
, "( " _GREEN_("%s") " )", sprint_hex_inrow(key
, 8));
427 curr_state
= PICO_NONE
;
433 void annotateIso15693(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
437 case ISO15693_INVENTORY
:
438 snprintf(exp
, size
, "INVENTORY");
440 case ISO15693_STAYQUIET
:
441 snprintf(exp
, size
, "STAY_QUIET");
443 case ISO15693_READBLOCK
: {
448 else if (cmdsize
== 5)
451 snprintf(exp
, size
, "READBLOCK(%d)", block
);
454 case ISO15693_WRITEBLOCK
: {
458 snprintf(exp
, size
, "WRITEBLOCK(%d)", block
);
461 case ISO15693_LOCKBLOCK
:
462 snprintf(exp
, size
, "LOCKBLOCK");
464 case ISO15693_READ_MULTI_BLOCK
:
465 snprintf(exp
, size
, "READ_MULTI_BLOCK");
467 case ISO15693_WRITE_MULTI_BLOCK
:
468 snprintf(exp
, size
, "WRITE_MULTI_BLOCK");
470 case ISO15693_SELECT
:
471 snprintf(exp
, size
, "SELECT");
473 case ISO15693_RESET_TO_READY
:
474 snprintf(exp
, size
, "RESET_TO_READY");
476 case ISO15693_WRITE_AFI
:
477 snprintf(exp
, size
, "WRITE_AFI");
479 case ISO15693_LOCK_AFI
:
480 snprintf(exp
, size
, "LOCK_AFI");
482 case ISO15693_WRITE_DSFID
:
483 snprintf(exp
, size
, "WRITE_DSFID");
485 case ISO15693_LOCK_DSFID
:
486 snprintf(exp
, size
, "LOCK_DSFID");
488 case ISO15693_GET_SYSTEM_INFO
:
489 snprintf(exp
, size
, "GET_SYSTEM_INFO");
491 case ISO15693_READ_MULTI_SECSTATUS
:
492 snprintf(exp
, size
, "READ_MULTI_SECSTATUS");
494 case ISO15693_INVENTORY_READ
:
495 snprintf(exp
, size
, "INVENTORY_READ");
497 case ISO15693_FAST_INVENTORY_READ
:
498 snprintf(exp
, size
, "FAST_INVENTORY_READ");
500 case ISO15693_SET_EAS
:
501 snprintf(exp
, size
, "SET_EAS");
503 case ISO15693_RESET_EAS
:
504 snprintf(exp
, size
, "RESET_EAS");
506 case ISO15693_LOCK_EAS
:
507 snprintf(exp
, size
, "LOCK_EAS");
509 case ISO15693_EAS_ALARM
:
510 snprintf(exp
, size
, "EAS_ALARM");
512 case ISO15693_PASSWORD_PROTECT_EAS
:
513 snprintf(exp
, size
, "PASSWORD_PROTECT_EAS");
515 case ISO15693_WRITE_EAS_ID
:
516 snprintf(exp
, size
, "WRITE_EAS_ID");
518 case ISO15693_READ_EPC
:
519 snprintf(exp
, size
, "READ_EPC");
521 case ISO15693_GET_NXP_SYSTEM_INFO
:
522 snprintf(exp
, size
, "GET_NXP_SYSTEM_INFO");
524 case ISO15693_INVENTORY_PAGE_READ
:
525 snprintf(exp
, size
, "INVENTORY_PAGE_READ");
527 case ISO15693_FAST_INVENTORY_PAGE_READ
:
528 snprintf(exp
, size
, "FAST_INVENTORY_PAGE_READ");
530 case ISO15693_GET_RANDOM_NUMBER
:
531 snprintf(exp
, size
, "GET_RANDOM_NUMBER");
533 case ISO15693_SET_PASSWORD
:
534 snprintf(exp
, size
, "SET_PASSWORD");
536 case ISO15693_WRITE_PASSWORD
:
537 snprintf(exp
, size
, "WRITE_PASSWORD");
539 case ISO15693_LOCK_PASSWORD
:
540 snprintf(exp
, size
, "LOCK_PASSWORD");
542 case ISO15693_PROTECT_PAGE
:
543 snprintf(exp
, size
, "PROTECT_PAGE");
545 case ISO15693_LOCK_PAGE_PROTECTION
:
546 snprintf(exp
, size
, "LOCK_PAGE_PROTECTION");
548 case ISO15693_GET_MULTI_BLOCK_PROTECTION
:
549 snprintf(exp
, size
, "GET_MULTI_BLOCK_PROTECTION");
551 case ISO15693_DESTROY
:
552 snprintf(exp
, size
, "DESTROY");
554 case ISO15693_ENABLE_PRIVACY
:
555 snprintf(exp
, size
, "ENABLE_PRIVACY");
557 case ISO15693_64BIT_PASSWORD_PROTECTION
:
558 snprintf(exp
, size
, "64BIT_PASSWORD_PROTECTION");
560 case ISO15693_STAYQUIET_PERSISTENT
:
561 snprintf(exp
, size
, "STAYQUIET_PERSISTENT");
563 case ISO15693_READ_SIGNATURE
:
564 snprintf(exp
, size
, "READ_SIGNATURE");
570 if (cmd
[1] > ISO15693_STAYQUIET
&& cmd
[1] < ISO15693_READBLOCK
) snprintf(exp
, size
, "Mandatory RFU");
571 else if (cmd
[1] > ISO15693_READ_MULTI_SECSTATUS
&& cmd
[1] <= 0x9F) snprintf(exp
, size
, "Optional RFU");
572 // else if (cmd[1] >= 0xA0 && cmd[1] <= 0xDF) snprintf(exp, size, "Cust IC MFG dependent");
573 else if (cmd
[1] > ISO15693_READ_SIGNATURE
&& cmd
[1] <= 0xDF) snprintf(exp
, size
, "Cust IC MFG dependent");
574 else if (cmd
[1] >= 0xE0) snprintf(exp
, size
, "Proprietary IC MFG dependent");
576 snprintf(exp
, size
, "?");
580 void annotateTopaz(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
583 snprintf(exp
, size
, "REQA");
586 snprintf(exp
, size
, "WUPA");
589 snprintf(exp
, size
, "RID");
592 snprintf(exp
, size
, "RALL");
595 snprintf(exp
, size
, "READ");
598 snprintf(exp
, size
, "WRITE-E");
601 snprintf(exp
, size
, "WRITE-NE");
604 snprintf(exp
, size
, "RSEG");
607 snprintf(exp
, size
, "READ8");
610 snprintf(exp
, size
, "WRITE-E8");
612 case TOPAZ_WRITE_NE8
:
613 snprintf(exp
, size
, "WRITE-NE8");
616 snprintf(exp
, size
, "?");
622 void annotateIso7816(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
628 if ((cmd
[0] & 0xC0) && (cmdsize
== 3)) {
629 switch ((cmd
[0] & 0x3f)) {
631 snprintf(exp
, size
, "S-block RESYNCH req");
634 snprintf(exp
, size
, "S-block RESYNCH resp");
637 snprintf(exp
, size
, "S-block IFS req");
640 snprintf(exp
, size
, "S-block IFS resp");
643 snprintf(exp
, size
, "S-block ABORT req");
646 snprintf(exp
, size
, "S-block ABORT resp");
649 snprintf(exp
, size
, "S-block WTX reqt");
652 snprintf(exp
, size
, "S-block WTX resp");
655 snprintf(exp
, size
, "S-block");
660 else if (((cmd
[0] & 0xD0) == 0x80) && (cmdsize
> 2)) {
661 if ((cmd
[0] & 0x10) == 0)
662 snprintf(exp
, size
, "R-block ACK");
664 snprintf(exp
, size
, "R-block NACK");
682 case ISO7816_READ_BINARY
:
683 snprintf(exp
, size
, "READ BIN");
685 case ISO7816_WRITE_BINARY
:
686 snprintf(exp
, size
, "WRITE BIN");
688 case ISO7816_UPDATE_BINARY
:
689 snprintf(exp
, size
, "UPDATE BIN");
691 case ISO7816_ERASE_BINARY
:
692 snprintf(exp
, size
, "ERASE BIN");
694 case ISO7816_READ_RECORDS
:
695 snprintf(exp
, size
, "READ RECORDS");
697 case ISO7816_WRITE_RECORDS
:
698 snprintf(exp
, size
, "WRITE RECORDS");
700 case ISO7816_APPEND_RECORD
:
701 snprintf(exp
, size
, "APPEND RECORD");
703 case ISO7816_UPDATE_RECORD
:
704 snprintf(exp
, size
, "UPDATE RECORD");
706 case ISO7816_GET_DATA
:
707 snprintf(exp
, size
, "GET DATA");
709 case ISO7816_PUT_DATA
:
710 snprintf(exp
, size
, "PUT DATA");
712 case ISO7816_SELECT_FILE
:
713 snprintf(exp
, size
, "SELECT FILE");
716 snprintf(exp
, size
, "VERIFY");
718 case ISO7816_INTERNAL_AUTHENTICATION
:
719 snprintf(exp
, size
, "INTERNAL AUTH");
721 case ISO7816_EXTERNAL_AUTHENTICATION
:
722 snprintf(exp
, size
, "EXTERNAL AUTH");
724 case ISO7816_GET_CHALLENGE
:
725 snprintf(exp
, size
, "GET CHALLENGE");
727 case ISO7816_MANAGE_CHANNEL
:
728 snprintf(exp
, size
, "MANAGE CHANNEL");
730 case ISO7816_GET_RESPONSE
:
731 snprintf(exp
, size
, "GET RESPONSE");
734 //snprintf(exp, size, "?");
741 void annotateMfDesfire(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
743 // it's basically a ISO14443a tag, so try annotation from there
744 if (applyIso14443a(exp
, size
, cmd
, cmdsize
) == 0) {
747 if ((cmd
[0] & 0xC0) && (cmdsize
== 3)) {
748 switch ((cmd
[0] & 0x30)) {
750 snprintf(exp
, size
, "S-block DESELECT");
753 snprintf(exp
, size
, "S-block WTX");
756 snprintf(exp
, size
, "S-block");
760 // R-block (ack) 101xx01x
761 else if (((cmd
[0] & 0xB0) == 0xA0) && (cmdsize
> 2)) {
762 if ((cmd
[0] & 0x10) == 0)
763 snprintf(exp
, size
, "R-block ACK(%d)", (cmd
[0] & 0x01));
765 snprintf(exp
, size
, "R-block NACK(%d)", (cmd
[0] & 0x01));
768 else if ((cmd
[0] & 0xC0) == 0x00) {
770 // PCB [CID] [NAD] [INF] CRC CRC
772 if ((cmd
[0] & 0x08) == 0x08) // cid byte following
775 if ((cmd
[0] & 0x04) == 0x04) // nad byte following
778 for (uint8_t i
= 0; i
< 2; i
++, pos
++) {
779 bool found_annotation
= true;
782 case MFDES_CREATE_APPLICATION
:
783 snprintf(exp
, size
, "CREATE APPLICATION");
785 case MFDES_DELETE_APPLICATION
:
786 snprintf(exp
, size
, "DELETE APPLICATION");
788 case MFDES_GET_APPLICATION_IDS
:
789 snprintf(exp
, size
, "GET APPLICATION IDS");
791 case MFDES_SELECT_APPLICATION
:
792 snprintf(exp
, size
, "SELECT APPLICATION");
794 case MFDES_FORMAT_PICC
:
795 snprintf(exp
, size
, "FORMAT PICC");
797 case MFDES_GET_VERSION
:
798 snprintf(exp
, size
, "GET VERSION");
800 case MFDES_READ_DATA
:
801 snprintf(exp
, size
, "READ DATA");
803 case MFDES_WRITE_DATA
:
804 snprintf(exp
, size
, "WRITE DATA");
806 case MFDES_GET_VALUE
:
807 snprintf(exp
, size
, "GET VALUE");
810 snprintf(exp
, size
, "CREDIT");
813 snprintf(exp
, size
, "DEBIT");
815 case MFDES_LIMITED_CREDIT
:
816 snprintf(exp
, size
, "LIMITED CREDIT");
818 case MFDES_WRITE_RECORD
:
819 snprintf(exp
, size
, "WRITE RECORD");
821 case MFDES_READ_RECORDS
:
822 snprintf(exp
, size
, "READ RECORDS");
824 case MFDES_CLEAR_RECORD_FILE
:
825 snprintf(exp
, size
, "CLEAR RECORD FILE");
827 case MFDES_COMMIT_TRANSACTION
:
828 snprintf(exp
, size
, "COMMIT TRANSACTION");
830 case MFDES_ABORT_TRANSACTION
:
831 snprintf(exp
, size
, "ABORT TRANSACTION");
833 case MFDES_GET_FREE_MEMORY
:
834 snprintf(exp
, size
, "GET FREE MEMORY");
836 case MFDES_GET_FILE_IDS
:
837 snprintf(exp
, size
, "GET FILE IDS");
839 case MFDES_GET_DF_NAMES
:
840 snprintf(exp
, size
, "GET DF NAMES");
842 case MFDES_GET_ISOFILE_IDS
:
843 snprintf(exp
, size
, "GET ISOFILE IDS");
845 case MFDES_GET_FILE_SETTINGS
:
846 snprintf(exp
, size
, "GET FILE SETTINGS");
848 case MFDES_CHANGE_FILE_SETTINGS
:
849 snprintf(exp
, size
, "CHANGE FILE SETTINGS");
851 case MFDES_CREATE_STD_DATA_FILE
:
852 snprintf(exp
, size
, "CREATE STD DATA FILE");
854 case MFDES_CREATE_BACKUP_DATA_FILE
:
855 snprintf(exp
, size
, "CREATE BACKUP DATA FILE");
857 case MFDES_CREATE_VALUE_FILE
:
858 snprintf(exp
, size
, "CREATE VALUE FILE");
860 case MFDES_CREATE_LINEAR_RECORD_FILE
:
861 snprintf(exp
, size
, "CREATE LINEAR RECORD FILE");
863 case MFDES_CREATE_CYCLIC_RECORD_FILE
:
864 snprintf(exp
, size
, "CREATE CYCLIC RECORD FILE");
866 case MFDES_CREATE_TRANS_MAC_FILE
:
867 snprintf(exp
, size
, "CREATE TRANSACTION MAC FILE");
869 case MFDES_DELETE_FILE
:
870 snprintf(exp
, size
, "DELETE FILE");
872 case MFDES_AUTHENTICATE
:
873 snprintf(exp
, size
, "AUTH NATIVE (keyNo %d)", cmd
[pos
+ 4]);
874 break; // AUTHENTICATE_NATIVE
875 case MFDES_AUTHENTICATE_ISO
:
876 snprintf(exp
, size
, "AUTH ISO (keyNo %d)", cmd
[pos
+ 4]);
877 break; // AUTHENTICATE_STANDARD
878 case MFDES_AUTHENTICATE_AES
:
879 snprintf(exp
, size
, "AUTH AES (keyNo %d)", cmd
[pos
+ 4]);
881 case MFDES_AUTHENTICATE_EV2F
:
882 snprintf(exp
, size
, "AUTH EV2 First");
884 case MFDES_AUTHENTICATE_EV2NF
:
885 snprintf(exp
, size
, "AUTH EV2 Non First");
887 case MFDES_CHANGE_KEY_SETTINGS
:
888 snprintf(exp
, size
, "CHANGE KEY SETTINGS");
890 case MFDES_GET_KEY_SETTINGS
:
891 snprintf(exp
, size
, "GET KEY SETTINGS");
893 case MFDES_CHANGE_KEY
:
894 snprintf(exp
, size
, "CHANGE KEY");
896 case MFDES_GET_KEY_VERSION
:
897 snprintf(exp
, size
, "GET KEY VERSION");
899 case MFDES_ADDITIONAL_FRAME
:
900 snprintf(exp
, size
, "AUTH FRAME / NEXT FRAME");
903 snprintf(exp
, size
, "READ SIGNATURE");
905 case MFDES_ROLL_KEY_SETTINGS
:
906 snprintf(exp
, size
, "ROLL KEY SETTINGS");
908 case MFDES_INIT_KEY_SETTINGS
:
909 snprintf(exp
, size
, "INIT KEY SETTINGS");
911 case MFDES_FINALIZE_KEY_SETTINGS
:
912 snprintf(exp
, size
, "FINALIZE KEY SETTINGS");
914 case MFDES_GET_DELEGATE_INFO
:
915 snprintf(exp
, size
, "GET DELEGATE INFO");
917 case MFDES_CHANGE_KEY_EV2
:
918 snprintf(exp
, size
, "CHANGE KEY EV2");
920 case MFDES_COMMIT_READER_ID
:
921 snprintf(exp
, size
, "COMMIT READER ID");
923 case MFDES_CREATE_DELEGATE_APP
:
924 snprintf(exp
, size
, "CREATE DELEGATE APPLICATION");
926 case MFDES_PREPARE_PC
:
927 snprintf(exp
, size
, "PREPARE PROXIMITY CHECK");
929 case MFDES_PROXIMITY_CHECK
:
930 snprintf(exp
, size
, "PROXIMITY CHECK");
932 case MFDES_VERIFY_PC
:
933 snprintf(exp
, size
, "VERIFY PROXIMITY CHECK");
936 found_annotation
= false;
940 if (found_annotation
) {
946 snprintf(exp
, size
, "?");
953 0E xx = SELECT ID (xx = Chip-ID)
955 08 yy = Read Block (yy = block number)
956 09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written)
957 0C = Reset to Inventory
959 0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate)
961 void annotateIso14443b(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
963 case ISO14443B_REQB
: {
965 switch (cmd
[2] & 0x07) {
967 snprintf(exp
, size
, "1 slot ");
970 snprintf(exp
, size
, "2 slots ");
973 snprintf(exp
, size
, "4 slots ");
976 snprintf(exp
, size
, "8 slots ");
979 snprintf(exp
, size
, "16 slots ");
983 snprintf(exp
, size
, "WUPB");
985 snprintf(exp
, size
, "REQB");
988 case ISO14443B_ATTRIB
:
989 snprintf(exp
, size
, "ATTRIB");
992 snprintf(exp
, size
, "HALT");
994 case ISO14443B_INITIATE
:
995 snprintf(exp
, size
, "INITIATE");
997 case ISO14443B_SELECT
:
998 snprintf(exp
, size
, "SELECT(%d)", cmd
[1]);
1000 case ISO14443B_GET_UID
:
1001 snprintf(exp
, size
, "GET UID");
1003 case ISO14443B_READ_BLK
:
1004 snprintf(exp
, size
, "READ_BLK(%d)", cmd
[1]);
1006 case ISO14443B_WRITE_BLK
:
1007 snprintf(exp
, size
, "WRITE_BLK(%d)", cmd
[1]);
1009 case ISO14443B_RESET
:
1010 snprintf(exp
, size
, "RESET");
1012 case ISO14443B_COMPLETION
:
1013 snprintf(exp
, size
, "COMPLETION");
1015 case ISO14443B_AUTHENTICATE
:
1016 snprintf(exp
, size
, "AUTHENTICATE");
1018 case ISO14443B_PING
:
1019 snprintf(exp
, size
, "PING");
1021 case ISO14443B_PONG
:
1022 snprintf(exp
, size
, "PONG");
1025 snprintf(exp
, size
, "?");
1030 // CryptoRF which is based on ISO-14443B
1031 void annotateCryptoRF(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
1034 case CRYPTORF_SET_USER_ZONE
:
1035 snprintf(exp
, size
, "SET USR ZONE");
1037 case CRYPTORF_READ_USER_ZONE
:
1038 snprintf(exp
, size
, "READ USR ZONE");
1040 case CRYPTORF_WRITE_USER_ZONE
:
1041 snprintf(exp
, size
, "WRITE USR ZONE");
1043 case CRYPTORF_WRITE_SYSTEM_ZONE
:
1044 snprintf(exp
, size
, "WRITE SYSTEM ZONE");
1046 case CRYPTORF_READ_SYSTEM_ZONE
:
1047 snprintf(exp
, size
, "READ SYSTEM ZONE");
1049 case CRYPTORF_VERIFY_CRYPTO
:
1050 snprintf(exp
, size
, "VERIFY CRYPTO");
1052 case CRYPTORF_SEND_CHECKSUM
:
1053 snprintf(exp
, size
, "SEND CHKSUM");
1055 case CRYPTORF_DESELECT
:
1056 snprintf(exp
, size
, "DESELECT");
1059 snprintf(exp
, size
, "IDLE");
1061 case CRYPTORF_CHECK_PASSWORD
:
1062 snprintf(exp
, size
, "CHECK PWD");
1065 snprintf(exp
, size
, "?");
1075 void annotateLegic(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
1076 uint8_t bitsend
= cmd
[0];
1077 uint8_t cmdBit
= (cmd
[1] & 1);
1080 snprintf(exp
, size
, "IV 0x%02X", cmd
[1]);
1085 snprintf(exp
, size
, "MIM22");
1088 snprintf(exp
, size
, "MIM256");
1090 case LEGIC_MIM_1024
:
1091 snprintf(exp
, size
, "MIM1024");
1094 snprintf(exp
, size
, "ACK 22");
1097 snprintf(exp
, size
, "ACK 256/1024");
1105 uint16_t address
= (cmd
[2] << 7) | cmd
[1] >> 1;
1107 if (cmdBit
== LEGIC_READ
)
1108 snprintf(exp
, size
, "READ Byte(%d)", address
);
1110 if (cmdBit
== LEGIC_WRITE
)
1111 snprintf(exp
, size
, "WRITE Byte(%d)", address
);
1115 if (cmdBit
== LEGIC_WRITE
) {
1116 uint16_t address
= ((cmd
[2] << 7) | cmd
[1] >> 1) & 0xFF;
1117 uint8_t val
= (cmd
[3] & 1) << 7 | cmd
[2] >> 1;
1118 snprintf(exp
, size
, "WRITE Byte(%d) %02X", address
, val
);
1123 if (cmdBit
== LEGIC_WRITE
) {
1124 uint16_t address
= ((cmd
[2] << 7) | cmd
[1] >> 1) & 0x3FF;
1125 uint8_t val
= (cmd
[3] & 0x7) << 5 | cmd
[2] >> 3;
1126 snprintf(exp
, size
, "WRITE Byte(%d) %02X", address
, val
);
1136 void annotateFelica(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
1138 case FELICA_POLL_REQ
:
1139 snprintf(exp
, size
, "POLLING");
1141 case FELICA_POLL_ACK
:
1142 snprintf(exp
, size
, "POLL ACK");
1144 case FELICA_REQSRV_REQ
:
1145 snprintf(exp
, size
, "REQUEST SERVICE");
1147 case FELICA_REQSRV_ACK
:
1148 snprintf(exp
, size
, "REQ SERV ACK");
1150 case FELICA_REQRESP_REQ
:
1151 snprintf(exp
, size
, "REQUEST RESPONSE");
1153 case FELICA_REQRESP_ACK
:
1154 snprintf(exp
, size
, "REQ RESP ACK");
1156 case FELICA_RDBLK_REQ
:
1157 snprintf(exp
, size
, "READ BLK");
1159 case FELICA_RDBLK_ACK
:
1160 snprintf(exp
, size
, "READ BLK ACK");
1162 case FELICA_WRTBLK_REQ
:
1163 snprintf(exp
, size
, "WRITE BLK");
1165 case FELICA_WRTBLK_ACK
:
1166 snprintf(exp
, size
, "WRITE BLK ACK");
1168 case FELICA_SRCHSYSCODE_REQ
:
1169 snprintf(exp
, size
, "SEARCH SERVICE CODE");
1171 case FELICA_SRCHSYSCODE_ACK
:
1172 snprintf(exp
, size
, "SSC ACK");
1174 case FELICA_REQSYSCODE_REQ
:
1175 snprintf(exp
, size
, "REQUEST SYSTEM CODE");
1177 case FELICA_REQSYSCODE_ACK
:
1178 snprintf(exp
, size
, "RSC ACK");
1180 case FELICA_AUTH1_REQ
:
1181 snprintf(exp
, size
, "AUTH 1");
1183 case FELICA_AUTH1_ACK
:
1184 snprintf(exp
, size
, "AUTH 1 ACK");
1186 case FELICA_AUTH2_REQ
:
1187 snprintf(exp
, size
, "AUTH 2");
1189 case FELICA_AUTH2_ACK
:
1190 snprintf(exp
, size
, "AUTH 2 ACK");
1192 case FELICA_RDSEC_REQ
:
1193 snprintf(exp
, size
, "READ");
1195 case FELICA_RDSEC_ACK
:
1196 snprintf(exp
, size
, "READ ACK");
1198 case FELICA_WRTSEC_REQ
:
1199 snprintf(exp
, size
, "WRITE");
1201 case FELICA_WRTSEC_ACK
:
1202 snprintf(exp
, size
, "WRITE ACK");
1204 case FELICA_REQSRV2_REQ
:
1205 snprintf(exp
, size
, "REQUEST SERVICE v2");
1207 case FELICA_REQSRV2_ACK
:
1208 snprintf(exp
, size
, "REQ SERV v2 ACK");
1210 case FELICA_GETSTATUS_REQ
:
1211 snprintf(exp
, size
, "GET STATUS");
1213 case FELICA_GETSTATUS_ACK
:
1214 snprintf(exp
, size
, "GET STATUS ACK");
1216 case FELICA_OSVER_REQ
:
1217 snprintf(exp
, size
, "REQUEST SPECIFIC VERSION");
1219 case FELICA_OSVER_ACK
:
1220 snprintf(exp
, size
, "RSV ACK");
1222 case FELICA_RESET_MODE_REQ
:
1223 snprintf(exp
, size
, "RESET MODE");
1225 case FELICA_RESET_MODE_ACK
:
1226 snprintf(exp
, size
, "RESET MODE ACK");
1228 case FELICA_AUTH1V2_REQ
:
1229 snprintf(exp
, size
, "AUTH 1 v2");
1231 case FELICA_AUTH1V2_ACK
:
1232 snprintf(exp
, size
, "AUTH 1 v2 ACK");
1234 case FELICA_AUTH2V2_REQ
:
1235 snprintf(exp
, size
, "AUTH 2 v2");
1237 case FELICA_AUTH2V2_ACK
:
1238 snprintf(exp
, size
, "AUTH 2 v2 ACK");
1240 case FELICA_RDSECV2_REQ
:
1241 snprintf(exp
, size
, "READ v2");
1243 case FELICA_RDSECV2_ACK
:
1244 snprintf(exp
, size
, "READ v2 ACK");
1246 case FELICA_WRTSECV2_REQ
:
1247 snprintf(exp
, size
, "WRITE v2");
1249 case FELICA_WRTSECV2_ACK
:
1250 snprintf(exp
, size
, "WRITE v2 ACK");
1252 case FELICA_UPDATE_RNDID_REQ
:
1253 snprintf(exp
, size
, "UPDATE RANDOM ID");
1255 case FELICA_UPDATE_RNDID_ACK
:
1256 snprintf(exp
, size
, "URI ACK");
1259 snprintf(exp
, size
, "?");
1264 void annotateLTO(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
) {
1266 case LTO_REQ_STANDARD
:
1267 snprintf(exp
, size
, "REQ Standard");
1271 snprintf(exp
, size
, "SELECT_UID-2");
1272 else if (cmd
[1] == 0x20)
1273 snprintf(exp
, size
, "SELECT");
1276 snprintf(exp
, size
, "REQ All");
1278 case LTO_TEST_CMD_1
:
1279 snprintf(exp
, size
, "TEST CMD 1");
1281 case LTO_TEST_CMD_2
:
1282 snprintf(exp
, size
, "TEST CMD 2");
1285 snprintf(exp
, size
, "READWORD");
1287 case (LTO_READBLOCK
& 0xF0):
1288 snprintf(exp
, size
, "READBLOCK(%d)", cmd
[1]);
1290 case LTO_READBLOCK_CONT
:
1291 snprintf(exp
, size
, "READBLOCK CONT");
1294 snprintf(exp
, size
, "WRITEWORD");
1296 case (LTO_WRITEBLOCK
& 0xF0):
1297 snprintf(exp
, size
, "WRITEBLOCK(%d)", cmd
[1]);
1300 snprintf(exp
, size
, "HALT");
1307 void annotateMifare(char *exp
, size_t size
, uint8_t *cmd
, uint8_t cmdsize
, uint8_t *parity
, uint8_t paritysize
, bool isResponse
) {
1308 if (!isResponse
&& cmdsize
== 1) {
1310 case ISO14443A_CMD_WUPA
:
1311 case ISO14443A_CMD_REQA
:
1312 MifareAuthState
= masNone
;
1320 if (MifareAuthState
== masNone
) {
1321 if (cmdsize
== 9 && cmd
[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT
&& cmd
[1] == 0x70) {
1323 AuthData
.uid
= bytes_to_num(&cmd
[2], 4);
1325 if (cmdsize
== 9 && cmd
[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2
&& cmd
[1] == 0x70) {
1327 AuthData
.uid
= bytes_to_num(&cmd
[2], 4);
1329 if (cmdsize
== 9 && cmd
[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3
&& cmd
[1] == 0x70) {
1331 AuthData
.uid
= bytes_to_num(&cmd
[2], 4);
1335 switch (MifareAuthState
) {
1337 if (cmdsize
== 4 && isResponse
) {
1338 snprintf(exp
, size
, "AUTH: nt %s", (AuthData
.first_auth
) ? "" : "(enc)");
1339 MifareAuthState
= masNrAr
;
1340 if (AuthData
.first_auth
) {
1341 AuthData
.nt
= bytes_to_num(cmd
, 4);
1342 AuthData
.nt_enc_par
= 0;
1344 AuthData
.nt_enc
= bytes_to_num(cmd
, 4);
1345 AuthData
.nt_enc_par
= parity
[0] & 0xF0;
1349 MifareAuthState
= masError
;
1353 if (cmdsize
== 8 && !isResponse
) {
1354 snprintf(exp
, size
, "AUTH: nr ar (enc)");
1355 MifareAuthState
= masAt
;
1356 AuthData
.nr_enc
= bytes_to_num(cmd
, 4);
1357 AuthData
.nr_enc_par
= parity
[0] & 0xF0;
1358 AuthData
.ar_enc
= bytes_to_num(&cmd
[4], 4);
1359 AuthData
.ar_enc_par
= parity
[0] << 4;
1362 MifareAuthState
= masError
;
1366 if (cmdsize
== 4 && isResponse
) {
1367 snprintf(exp
, size
, "AUTH: at (enc)");
1368 MifareAuthState
= masAuthComplete
;
1369 AuthData
.at_enc
= bytes_to_num(cmd
, 4);
1370 AuthData
.at_enc_par
= parity
[0] & 0xF0;
1373 MifareAuthState
= masError
;
1378 case masAuthComplete
:
1384 if (!isResponse
&& ((MifareAuthState
== masNone
) || (MifareAuthState
== masError
)))
1385 annotateIso14443a(exp
, size
, cmd
, cmdsize
);
1389 static void mf_get_paritybinstr(char *s
, uint32_t val
, uint8_t par
) {
1390 uint8_t foo
[4] = {0, 0, 0, 0};
1391 num_to_bytes(val
, sizeof(uint32_t), foo
);
1392 for (uint8_t i
= 0; i
< 4; i
++) {
1393 if (oddparity8(foo
[i
]) != ((par
>> (7 - (i
& 0x0007))) & 0x01))
1400 bool DecodeMifareData(uint8_t *cmd
, uint8_t cmdsize
, uint8_t *parity
, bool isResponse
, uint8_t *mfData
, size_t *mfDataLen
, const uint64_t *dicKeys
, uint32_t dicKeysCount
) {
1401 static struct Crypto1State
*traceCrypto1
;
1405 if (MifareAuthState
== masAuthComplete
) {
1407 crypto1_destroy(traceCrypto1
);
1408 traceCrypto1
= NULL
;
1411 MifareAuthState
= masFirstData
;
1418 if (MifareAuthState
== masFirstData
) {
1419 static uint64_t mfLastKey
;
1420 if (AuthData
.first_auth
) {
1421 AuthData
.ks2
= AuthData
.ar_enc
^ prng_successor(AuthData
.nt
, 64);
1422 AuthData
.ks3
= AuthData
.at_enc
^ prng_successor(AuthData
.nt
, 96);
1424 mfLastKey
= GetCrypto1ProbableKey(&AuthData
);
1425 PrintAndLogEx(NORMAL
, " | | * |%49s " _GREEN_("%012" PRIX64
) " prng %s | |",
1428 validate_prng_nonce(AuthData
.nt
) ? _GREEN_("WEAK") : _YELLOW_("HARD"));
1430 AuthData
.first_auth
= false;
1432 traceCrypto1
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
);
1435 crypto1_destroy(traceCrypto1
);
1436 traceCrypto1
= NULL
;
1439 // check last used key
1441 if (NestedCheckKey(mfLastKey
, &AuthData
, cmd
, cmdsize
, parity
)) {
1442 PrintAndLogEx(NORMAL
, " | | * |%60s " _GREEN_("%012" PRIX64
) "| |", "last used key", mfLastKey
);
1443 traceCrypto1
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
);
1447 // check default keys
1448 if (!traceCrypto1
&& dicKeys
!= NULL
&& dicKeysCount
> 0) {
1449 for (int i
= 0; i
< dicKeysCount
; i
++) {
1450 if (NestedCheckKey(dicKeys
[i
], &AuthData
, cmd
, cmdsize
, parity
)) {
1451 PrintAndLogEx(NORMAL
, " | | * |%60s " _GREEN_("%012" PRIX64
) "| |", "key", dicKeys
[i
]);
1453 mfLastKey
= dicKeys
[i
];
1454 traceCrypto1
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
);
1461 if (!traceCrypto1
&& validate_prng_nonce(AuthData
.nt
)) {
1462 uint32_t ntx
= prng_successor(AuthData
.nt
, 90);
1463 for (int i
= 0; i
< 16383; i
++) {
1464 ntx
= prng_successor(ntx
, 1);
1465 if (NTParityChk(&AuthData
, ntx
)) {
1467 uint32_t ks2
= AuthData
.ar_enc
^ prng_successor(ntx
, 64);
1468 uint32_t ks3
= AuthData
.at_enc
^ prng_successor(ntx
, 96);
1469 struct Crypto1State
*pcs
= lfsr_recovery64(ks2
, ks3
);
1470 memcpy(mfData
, cmd
, cmdsize
);
1471 mf_crypto1_decrypt(pcs
, mfData
, cmdsize
, 0);
1472 crypto1_destroy(pcs
);
1474 if (CheckCrypto1Parity(cmd
, cmdsize
, mfData
, parity
) && check_crc(CRC_14443_A
, mfData
, cmdsize
)) {
1478 mfLastKey
= GetCrypto1ProbableKey(&AuthData
);
1479 PrintAndLogEx(NORMAL
, " | | * | nested probable key: " _GREEN_("%012" PRIX64
) " ks2:%08x ks3:%08x | |",
1484 traceCrypto1
= lfsr_recovery64(AuthData
.ks2
, AuthData
.ks3
);
1492 if (!traceCrypto1
) {
1494 //PrintAndLogEx(NORMAL, "hardnested not implemented. uid:%x nt:%x ar_enc:%x at_enc:%x\n", AuthData.uid, AuthData.nt, AuthData.ar_enc, AuthData.at_enc);
1496 char snt
[5] = {0, 0, 0, 0, 0};
1497 mf_get_paritybinstr(snt
, AuthData
.nt_enc
, AuthData
.nt_enc_par
);
1498 char sar
[5] = {0, 0, 0, 0, 0};
1499 mf_get_paritybinstr(sar
, AuthData
.ar_enc
, AuthData
.ar_enc_par
);
1500 char sat
[5] = {0, 0, 0, 0, 0};
1501 mf_get_paritybinstr(sat
, AuthData
.at_enc
, AuthData
.at_enc_par
);
1503 PrintAndLogEx(NORMAL
, "Nested authentication detected. ");
1504 PrintAndLogEx(NORMAL
, "tools/mf_nonce_brute/mf_nonce_brute %x %x %s %x %x %s %x %s %s\n"
1513 , sprint_hex_inrow(cmd
, cmdsize
)
1516 MifareAuthState
= masError
;
1518 /* TOO SLOW( needs to have more strong filter. with this filter - aprox 4 mln tests
1519 uint32_t t = msclock();
1522 for (uint32_t i = 0; i < 0xFFFFFFFF; i++) {
1523 if (NTParityChk(&AuthData, i)){
1525 uint32_t ks2 = AuthData.ar_enc ^ prng_successor(i, 64);
1526 uint32_t ks3 = AuthData.at_enc ^ prng_successor(i, 96);
1527 struct Crypto1State *pcs = lfsr_recovery64(ks2, ks3);
1531 if (!(n % 100000)) {
1532 PrintAndLogEx(NORMAL, "delta=%d n=%d ks2=%x ks3=%x \n", msclock() - t1 , n, ks2, ks3);
1538 PrintAndLogEx(NORMAL, "delta=%d n=%d\n", msclock() - t, n);
1542 MifareAuthState
= masData
;
1545 if (MifareAuthState
== masData
&& traceCrypto1
) {
1546 memcpy(mfData
, cmd
, cmdsize
);
1547 mf_crypto1_decrypt(traceCrypto1
, mfData
, cmdsize
, 0);
1548 *mfDataLen
= cmdsize
;
1551 return *mfDataLen
> 0;
1554 bool NTParityChk(TAuthData
*ad
, uint32_t ntx
) {
1556 (oddparity8(ntx
>> 8 & 0xff) ^ (ntx
& 0x01) ^ ((ad
->nt_enc_par
>> 5) & 0x01) ^ (ad
->nt_enc
& 0x01)) ||
1557 (oddparity8(ntx
>> 16 & 0xff) ^ (ntx
>> 8 & 0x01) ^ ((ad
->nt_enc_par
>> 6) & 0x01) ^ (ad
->nt_enc
>> 8 & 0x01)) ||
1558 (oddparity8(ntx
>> 24 & 0xff) ^ (ntx
>> 16 & 0x01) ^ ((ad
->nt_enc_par
>> 7) & 0x01) ^ (ad
->nt_enc
>> 16 & 0x01))
1562 uint32_t ar
= prng_successor(ntx
, 64);
1564 (oddparity8(ar
>> 8 & 0xff) ^ (ar
& 0x01) ^ ((ad
->ar_enc_par
>> 5) & 0x01) ^ (ad
->ar_enc
& 0x01)) ||
1565 (oddparity8(ar
>> 16 & 0xff) ^ (ar
>> 8 & 0x01) ^ ((ad
->ar_enc_par
>> 6) & 0x01) ^ (ad
->ar_enc
>> 8 & 0x01)) ||
1566 (oddparity8(ar
>> 24 & 0xff) ^ (ar
>> 16 & 0x01) ^ ((ad
->ar_enc_par
>> 7) & 0x01) ^ (ad
->ar_enc
>> 16 & 0x01))
1570 uint32_t at
= prng_successor(ntx
, 96);
1572 (oddparity8(ar
& 0xff) ^ (at
>> 24 & 0x01) ^ ((ad
->ar_enc_par
>> 4) & 0x01) ^ (ad
->at_enc
>> 24 & 0x01)) ||
1573 (oddparity8(at
>> 8 & 0xff) ^ (at
& 0x01) ^ ((ad
->at_enc_par
>> 5) & 0x01) ^ (ad
->at_enc
& 0x01)) ||
1574 (oddparity8(at
>> 16 & 0xff) ^ (at
>> 8 & 0x01) ^ ((ad
->at_enc_par
>> 6) & 0x01) ^ (ad
->at_enc
>> 8 & 0x01)) ||
1575 (oddparity8(at
>> 24 & 0xff) ^ (at
>> 16 & 0x01) ^ ((ad
->at_enc_par
>> 7) & 0x01) ^ (ad
->at_enc
>> 16 & 0x01))
1582 bool NestedCheckKey(uint64_t key
, TAuthData
*ad
, uint8_t *cmd
, uint8_t cmdsize
, uint8_t *parity
) {
1583 uint8_t buf
[32] = {0};
1584 struct Crypto1State
*pcs
;
1589 pcs
= crypto1_create(key
);
1590 uint32_t nt1
= crypto1_word(pcs
, ad
->nt_enc
^ ad
->uid
, 1) ^ ad
->nt_enc
;
1591 uint32_t ar
= prng_successor(nt1
, 64);
1592 uint32_t at
= prng_successor(nt1
, 96);
1594 crypto1_word(pcs
, ad
->nr_enc
, 1);
1595 // uint32_t nr1 = crypto1_word(pcs, ad->nr_enc, 1) ^ ad->nr_enc; // if needs deciphered nr
1596 uint32_t ar1
= crypto1_word(pcs
, 0, 0) ^ ad
->ar_enc
;
1597 uint32_t at1
= crypto1_word(pcs
, 0, 0) ^ ad
->at_enc
;
1599 if (!(ar
== ar1
&& at
== at1
&& NTParityChk(ad
, nt1
))) {
1600 crypto1_destroy(pcs
);
1604 memcpy(buf
, cmd
, cmdsize
);
1605 mf_crypto1_decrypt(pcs
, buf
, cmdsize
, 0);
1606 crypto1_destroy(pcs
);
1608 if (!CheckCrypto1Parity(cmd
, cmdsize
, buf
, parity
))
1611 if (!check_crc(CRC_14443_A
, buf
, cmdsize
))
1615 AuthData
.ks2
= AuthData
.ar_enc
^ ar
;
1616 AuthData
.ks3
= AuthData
.at_enc
^ at
;
1620 bool CheckCrypto1Parity(uint8_t *cmd_enc
, uint8_t cmdsize
, uint8_t *cmd
, uint8_t *parity_enc
) {
1621 for (int i
= 0; i
< cmdsize
- 1; i
++) {
1622 if (oddparity8(cmd
[i
]) ^ (cmd
[i
+ 1] & 0x01) ^ ((parity_enc
[i
/ 8] >> (7 - i
% 8)) & 0x01) ^ (cmd_enc
[i
+ 1] & 0x01))
1628 // Another implementation of mfkey64 attack, more "valid" than "probable"
1630 uint64_t GetCrypto1ProbableKey(TAuthData
*ad
) {
1631 struct Crypto1State
*revstate
= lfsr_recovery64(ad
->ks2
, ad
->ks3
);
1632 lfsr_rollback_word(revstate
, 0, 0);
1633 lfsr_rollback_word(revstate
, 0, 0);
1634 lfsr_rollback_word(revstate
, ad
->nr_enc
, 1);
1635 lfsr_rollback_word(revstate
, ad
->uid
^ ad
->nt
, 0);
1637 crypto1_get_lfsr(revstate
, &key
);
1638 crypto1_destroy(revstate
);