]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/mifarecmd.c
ADD: added @pivi 's faster authentication method from 'hardnested' into "hf mf...
[proxmark3-svn] / armsrc / mifarecmd.c
index 423b6e95f04a7bbc53a66f7adcd371efd304c32a..c18aba08d3a61d569f97939c311101990b920036 100644 (file)
@@ -613,6 +613,9 @@ int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
 // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on \r
 // Computer and Communications Security, 2015\r
 //-----------------------------------------------------------------------------\r
+#define AUTHENTICATION_TIMEOUT 848                     // card times out 1ms after wrong authentication (according to NXP documentation)\r
+#define PRE_AUTHENTICATION_LEADTIME 400                // some (non standard) cards need a pause after select before they are ready for first authentication \r
+\r
 void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)\r
 {\r
        uint64_t ui64Key = 0;\r
@@ -638,9 +641,6 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
        bool slow = flags & 0x0002;\r
        bool field_off = flags & 0x0004;\r
        \r
-       #define AUTHENTICATION_TIMEOUT 848                      // card times out 1ms after wrong authentication (according to NXP documentation)\r
-       #define PRE_AUTHENTICATION_LEADTIME 400         // some (non standard) cards need a pause after select before they are ready for first authentication \r
-       \r
        LED_A_ON();\r
        LED_C_OFF();\r
 \r
@@ -965,16 +965,17 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
 // MIFARE check keys. key count up to 85. \r
 // \r
 //-----------------------------------------------------------------------------\r
-void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)\r
-{\r
-  // params\r
+void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {\r
        uint8_t blockNo = arg0 & 0xff;\r
        uint8_t keyType = (arg0 >> 8) & 0xff;\r
        bool clearTrace = arg1;\r
        uint8_t keyCount = arg2;\r
        uint64_t ui64Key = 0;\r
        \r
-       // variables\r
+       bool have_uid = FALSE;\r
+       uint8_t cascade_levels = 0;\r
+       uint32_t timeout = 0;\r
+       \r
        int i;\r
        byte_t isOK = 0;\r
        uint8_t uid[10] = {0x00};\r
@@ -999,16 +1000,42 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
        \r
        for (i = 0; i < keyCount; ++i) {\r
 \r
-               mifare_classic_halt(pcs, cuid);\r
-       \r
-               if (!iso14443a_select_card(uid, NULL, &cuid, true, 0))\r
-                       break;\r
+               //mifare_classic_halt(pcs, cuid);\r
 \r
+               // this part is from Piwi's faster nonce collecting part in Hardnested.\r
+               if (!have_uid) { // need a full select cycle to get the uid first\r
+                       iso14a_card_select_t card_info;         \r
+                       if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("ChkKeys: Can't select card (ALL)");\r
+                               break;\r
+                       }\r
+                       switch (card_info.uidlen) {\r
+                               case 4 : cascade_levels = 1; break;\r
+                               case 7 : cascade_levels = 2; break;\r
+                               case 10: cascade_levels = 3; break;\r
+                               default: break;\r
+                       }\r
+                       have_uid = TRUE;        \r
+               } else { // no need for anticollision. We can directly select the card\r
+                       if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("ChkKeys: Can't select card (UID)");\r
+                               continue;\r
+                       }\r
+               }\r
+       \r
                ui64Key = bytes_to_num(datain + i * 6, 6);\r
                \r
-               if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST))\r
+               if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
+\r
+                       uint8_t dummy_answer = 0;\r
+                       ReaderTransmit(&dummy_answer, 1, NULL);\r
+                       timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;\r
+                       \r
+                       // wait for the card to become ready again\r
+                       while(GetCountSspClk() < timeout);\r
+                       \r
                        continue;\r
-               \r
+               }\r
                isOK = 1;\r
                break;\r
        }\r
Impressum, Datenschutz