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

Mifare Classic emulation fixes (#1566)

* Add fix for field
* More small bugfixes
* Clean up
Astra 3 лет назад
Родитель
Сommit
01eb92db06
2 измененных файлов с 20 добавлено и 5 удалено
  1. 5 2
      firmware/targets/f7/furi_hal/furi_hal_nfc.c
  2. 15 3
      lib/nfc/protocols/mifare_classic.c

+ 5 - 2
firmware/targets/f7/furi_hal/furi_hal_nfc.c

@@ -341,13 +341,13 @@ void furi_hal_nfc_listen_start(FuriHalNfcDevData* nfc_data) {
     if(nfc_data->uid_len == 4) {
         pt_memory[12] = nfc_data->sak & ~FURI_HAL_NFC_UID_INCOMPLETE;
     } else {
-        pt_memory[12] = nfc_data->sak | FURI_HAL_NFC_UID_INCOMPLETE;
+        pt_memory[12] = FURI_HAL_NFC_UID_INCOMPLETE;
     }
     pt_memory[13] = nfc_data->sak & ~FURI_HAL_NFC_UID_INCOMPLETE;
     pt_memory[14] = nfc_data->sak & ~FURI_HAL_NFC_UID_INCOMPLETE;
 
     st25r3916WritePTMem(pt_memory, sizeof(pt_memory));
-    // Go to sence
+    // Go to sense
     st25r3916ExecuteCommand(ST25R3916_CMD_GOTO_SENSE);
 }
 
@@ -507,6 +507,9 @@ static bool furi_hal_nfc_transparent_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_
     uint8_t rxe = 0;
     uint32_t start = DWT->CYCCNT;
     while(true) {
+        if(!rfalIsExtFieldOn()) {
+            return false;
+        }
         if(furi_hal_gpio_read(&gpio_nfc_irq_rfid_pull) == true) {
             st25r3916ReadRegister(ST25R3916_REG_IRQ_MAIN, &rxe);
             if(rxe & (1 << 4)) {

+ 15 - 3
lib/nfc/protocols/mifare_classic.c

@@ -771,6 +771,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
     // Read command
     while(!command_processed) {
         if(!is_encrypted) {
+            crypto1_reset(&emulator->crypto);
             memcpy(plain_data, tx_rx->rx_data, tx_rx->rx_bits / 8);
         } else {
             if(!furi_hal_nfc_tx_rx(tx_rx, 300)) {
@@ -803,7 +804,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
                 access_key = MfClassicKeyB;
             }
 
-            uint32_t nonce = prng_successor(DWT->CYCCNT, 32);
+            uint32_t nonce = prng_successor(DWT->CYCCNT, 32) ^ 0xAA;
             uint8_t nt[4];
             uint8_t nt_keystream[4];
             nfc_util_num2bytes(nonce, 4, nt);
@@ -858,7 +859,7 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
             uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0);
             if(cardRr != prng_successor(nonce, 64)) {
                 FURI_LOG_T(TAG, "Wrong AUTH! %08X != %08X", cardRr, prng_successor(nonce, 64));
-                // Don't send NACK, as tag don't send it
+                // Don't send NACK, as the tag doesn't send it
                 command_processed = true;
                 break;
             }
@@ -897,7 +898,18 @@ bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_
             } else {
                 if(!mf_classic_is_allowed_access(
                        emulator, block, access_key, MfClassicActionDataRead)) {
-                    memset(block_data, 0, 16);
+                    // Send NACK
+                    uint8_t nack = 0x04;
+                    if(is_encrypted) {
+                        mf_crypto1_encrypt(
+                            &emulator->crypto, NULL, &nack, 4, tx_rx->tx_data, tx_rx->tx_parity);
+                    } else {
+                        tx_rx->tx_data[0] = nack;
+                    }
+                    tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
+                    tx_rx->tx_bits = 4;
+                    furi_hal_nfc_tx_rx(tx_rx, 300);
+                    break;
                 }
             }
             nfca_append_crc16(block_data, 16);