Просмотр исходного кода

nfc: Fix sector reads when one block is unreadable for MIFARE Classic (#2296)

* Fix sector reads when one block is unreadable
* Auth on the correct block instead of first
* Fix in sector reader as well
* Apply patch by @gornekich

Co-authored-by: gornekich <n.gorbadey@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
Krzysztof Zdulski 3 лет назад
Родитель
Сommit
8fc834090d
1 измененных файлов с 21 добавлено и 1 удалено
  1. 21 1
      lib/nfc/protocols/mifare_classic.c

+ 21 - 1
lib/nfc/protocols/mifare_classic.c

@@ -595,6 +595,14 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                     mf_classic_set_block_read(data, i, &block_tmp);
                     mf_classic_set_block_read(data, i, &block_tmp);
                     blocks_read++;
                     blocks_read++;
+                } else if(i > start_block) {
+                    // Try to re-auth to read block in case prevous block was protected from read
+                    furi_hal_nfc_sleep();
+                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyA, &crypto, false, 0)) break;
+                    if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
+                        mf_classic_set_block_read(data, i, &block_tmp);
+                        blocks_read++;
+                    }
                 }
                 }
             } else {
             } else {
                 blocks_read++;
                 blocks_read++;
@@ -607,13 +615,20 @@ void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, u
         if(!key_b_found) break;
         if(!key_b_found) break;
         FURI_LOG_D(TAG, "Try to read blocks with key B");
         FURI_LOG_D(TAG, "Try to read blocks with key B");
         key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
         key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
-        furi_hal_nfc_sleep();
         if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) break;
         if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) break;
         for(size_t i = start_block; i < start_block + total_blocks; i++) {
         for(size_t i = start_block; i < start_block + total_blocks; i++) {
             if(!mf_classic_is_block_read(data, i)) {
             if(!mf_classic_is_block_read(data, i)) {
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                 if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
                     mf_classic_set_block_read(data, i, &block_tmp);
                     mf_classic_set_block_read(data, i, &block_tmp);
                     blocks_read++;
                     blocks_read++;
+                } else if(i > start_block) {
+                    // Try to re-auth to read block in case prevous block was protected from read
+                    furi_hal_nfc_sleep();
+                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyB, &crypto, false, 0)) break;
+                    if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
+                        mf_classic_set_block_read(data, i, &block_tmp);
+                        blocks_read++;
+                    }
                 }
                 }
             } else {
             } else {
                 blocks_read++;
                 blocks_read++;
@@ -665,6 +680,11 @@ static bool mf_classic_read_sector_with_reader(
 
 
         // Read blocks
         // Read blocks
         for(uint8_t i = 0; i < sector->total_blocks; i++) {
         for(uint8_t i = 0; i < sector->total_blocks; i++) {
+            if(mf_classic_read_block(tx_rx, crypto, first_block + i, &sector->block[i])) continue;
+            if(i == 0) continue;
+            // Try to auth to read next block in case previous is locked
+            furi_hal_nfc_sleep();
+            if(!mf_classic_auth(tx_rx, first_block + i, key, key_type, crypto, false, 0)) continue;
             mf_classic_read_block(tx_rx, crypto, first_block + i, &sector->block[i]);
             mf_classic_read_block(tx_rx, crypto, first_block + i, &sector->block[i]);
         }
         }
         // Save sector keys in last block
         // Save sector keys in last block