WIP OFW PR 2825: NFC: Improved MFC emulation on some readers

Not finished yet, added in current condition for more tests
by AloneLiberty
This commit is contained in:
MX 2023-07-06 02:44:28 +03:00
parent d9b95fd156
commit a6978bfd2d
No known key found for this signature in database
GPG key ID: 7CCC66B7DBDD1C83
4 changed files with 32 additions and 27 deletions

View file

@ -1107,7 +1107,9 @@ void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker) {
furi_hal_nfc_listen_start(nfc_data);
while(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { //-V1044
if(furi_hal_nfc_listen_rx(&tx_rx, 300)) {
mf_classic_emulator(&emulator, &tx_rx, false);
if(!mf_classic_emulator(&emulator, &tx_rx, false)) {
furi_hal_nfc_listen_start(nfc_data);
}
}
}
if(emulator.data_changed) {
@ -1382,8 +1384,6 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
bool reader_no_data_notified = true;
while(nfc_worker->state == NfcWorkerStateAnalyzeReader) {
furi_hal_nfc_stop_cmd();
furi_delay_ms(5);
furi_hal_nfc_listen_start(nfc_data);
if(furi_hal_nfc_listen_rx(&tx_rx, 300)) {
if(reader_no_data_notified) {
@ -1394,7 +1394,9 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
NfcProtocol protocol =
reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8);
if(protocol == NfcDeviceProtocolMifareClassic) {
mf_classic_emulator(&emulator, &tx_rx, true);
if(!mf_classic_emulator(&emulator, &tx_rx, true)) {
furi_hal_nfc_listen_start(nfc_data);
}
}
} else {
reader_no_data_received_cnt++;
@ -1406,6 +1408,7 @@ void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
FURI_LOG_D(TAG, "No data from reader");
continue;
}
furi_delay_ms(1);
}
rfal_platform_spi_release();

View file

@ -869,7 +869,7 @@ bool mf_classic_emulator(
if(!furi_hal_nfc_tx_rx(tx_rx, 300)) {
FURI_LOG_D(
TAG,
"Error in tx rx. Tx :%d bits, Rx: %d bits",
"Error in tx rx. Tx: %d bits, Rx: %d bits",
tx_rx->tx_bits,
tx_rx->rx_bits);
break;
@ -883,12 +883,17 @@ bool mf_classic_emulator(
break;
}
if(cmd == 0x50 && plain_data[1] == 0x00) {
if(cmd == NFCA_CMD_HALT && plain_data[1] == 0x00) {
FURI_LOG_T(TAG, "Halt received");
furi_hal_nfc_listen_sleep();
command_processed = true;
return false;
}
if(cmd == NFCA_CMD_RATS && !is_encrypted) {
// Mifare Classic doesn't support ATS, NACK it and start listening again
FURI_LOG_T(TAG, "RATS received");
break;
}
if(cmd == MF_CLASSIC_AUTH_KEY_A_CMD || cmd == MF_CLASSIC_AUTH_KEY_B_CMD) {
uint8_t block = plain_data[1];
uint64_t key = 0;
@ -903,8 +908,7 @@ bool mf_classic_emulator(
access_key = MfClassicKeyA;
} else {
FURI_LOG_D(TAG, "Key not known");
command_processed = true;
break;
return false;
}
} else {
if(mf_classic_is_key_found(
@ -914,8 +918,7 @@ bool mf_classic_emulator(
access_key = MfClassicKeyB;
} else {
FURI_LOG_D(TAG, "Key not known");
command_processed = true;
break;
return false;
}
}
@ -943,16 +946,14 @@ bool mf_classic_emulator(
tx_rx->tx_bits = sizeof(nt) * 8;
tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
}
if(!furi_hal_nfc_tx_rx(tx_rx, 500)) {
FURI_LOG_E(TAG, "Error in NT exchange");
command_processed = true;
break;
return false;
}
if(tx_rx->rx_bits != 64) {
FURI_LOG_W(TAG, "Incorrect nr + ar length: %d", tx_rx->rx_bits);
command_processed = true;
break;
return false;
}
uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4);
@ -963,8 +964,7 @@ bool mf_classic_emulator(
if(cardRr != prng_successor(nonce, 64)) {
FURI_LOG_T(TAG, "Wrong AUTH! %08lX != %08lX", cardRr, prng_successor(nonce, 64));
// Don't send NACK, as the tag doesn't send it
command_processed = true;
break;
return false;
}
uint32_t ans = prng_successor(nonce, 96);
@ -1156,6 +1156,7 @@ bool mf_classic_emulator(
tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
tx_rx->tx_bits = 4;
furi_hal_nfc_tx_rx(tx_rx, 300);
return false;
}
return true;
@ -1164,7 +1165,7 @@ bool mf_classic_emulator(
void mf_classic_halt(FuriHalNfcTxRxContext* tx_rx, Crypto1* crypto) {
furi_assert(tx_rx);
uint8_t plain_data[4] = {0x50, 0x00, 0x00, 0x00};
uint8_t plain_data[4] = {NFCA_CMD_HALT, 0x00, 0x00, 0x00};
nfca_append_crc16(plain_data, 2);
if(crypto) {

View file

@ -3,8 +3,6 @@
#include <stdio.h>
#include <furi.h>
#define NFCA_CMD_RATS (0xE0U)
#define NFCA_CRC_INIT (0x6363)
#define NFCA_F_SIG (13560000.0)
@ -22,7 +20,7 @@ typedef struct {
static uint8_t nfca_default_ats[] = {0x05, 0x78, 0x80, 0x80, 0x00};
static uint8_t nfca_sleep_req[] = {0x50, 0x00};
static uint8_t nfca_halt_req[] = {NFCA_CMD_HALT, 0x00};
uint16_t nfca_get_crc16(uint8_t* buff, uint16_t len) {
uint16_t crc = NFCA_CRC_INIT;
@ -50,17 +48,17 @@ bool nfca_emulation_handler(
uint16_t buff_rx_len,
uint8_t* buff_tx,
uint16_t* buff_tx_len) {
bool sleep = false;
bool halt = false;
uint8_t rx_bytes = buff_rx_len / 8;
if(rx_bytes == sizeof(nfca_sleep_req) && !memcmp(buff_rx, nfca_sleep_req, rx_bytes)) {
sleep = true;
if(rx_bytes == sizeof(nfca_halt_req) && !memcmp(buff_rx, nfca_halt_req, rx_bytes)) {
halt = true;
} else if(rx_bytes == sizeof(nfca_cmd_rats) && buff_rx[0] == NFCA_CMD_RATS) {
memcpy(buff_tx, nfca_default_ats, sizeof(nfca_default_ats));
*buff_tx_len = sizeof(nfca_default_ats) * 8;
}
return sleep;
return halt;
}
static void nfca_add_bit(DigitalSignal* signal, bool bit) {

View file

@ -5,6 +5,9 @@
#include <lib/digital_signal/digital_signal.h>
#define NFCA_CMD_RATS (0xE0U)
#define NFCA_CMD_HALT (0x50U)
typedef struct {
DigitalSignal* one;
DigitalSignal* zero;