[FL-2245] Introduce Mifare Classic Emulation (#1242)

* digital signal: introduce digital signal
* nfca: add nfca signal encoder
* nfc: add mifare classic emulation scene
* nfca: add classic emulation support to lib and hal
* mifare classic: support basic read commands
* nfc: add mifare classic menu scene
* mifare classic: start parsing commands in emulation
* mifare classic: add nested auth
* nfc: fix errors
* mifare classic: add encrypt function
* nfc: fix mifare classic save
* lib hex: add hex uint64_t ASCII parser
* flipper format: add uint64 hex format support
* nfc: add mifare classic key map
* nfc: hide mifare classic keys on emulation
* mifare classic: add NACK responce
* nfc: add partial bytes support in transparent mode
* nfc: mifare classic add shadow file support
* digital signal: move arr buffer from BSS to heap
* mifare classic: process access bits more careful
* nfca: fix memory leack
* nfc: format sources
* mifare classic: cleun up

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
gornekich
2022-05-24 17:00:15 +03:00
committed by GitHub
parent 2017baac48
commit d31578508a
28 changed files with 1150 additions and 28 deletions
+84
View File
@@ -1,11 +1,17 @@
#include "nfca.h"
#include <string.h>
#include <stdio.h>
#include <furi.h>
#define NFCA_CMD_RATS (0xE0U)
#define NFCA_CRC_INIT (0x6363)
#define NFCA_F_SIG (13560000.0)
#define NFCA_T_SIG (1.0 / NFCA_F_SIG)
#define NFCA_SIGNAL_MAX_EDGES (1350)
typedef struct {
uint8_t cmd;
uint8_t param;
@@ -53,3 +59,81 @@ bool nfca_emulation_handler(
return sleep;
}
static void nfca_add_bit(DigitalSignal* signal, bool bit) {
if(bit) {
signal->start_level = true;
for(size_t i = 0; i < 7; i++) {
signal->edge_timings[i] = 8 * NFCA_T_SIG;
}
signal->edge_timings[7] = 9 * 8 * NFCA_T_SIG;
signal->edge_cnt = 8;
} else {
signal->start_level = false;
signal->edge_timings[0] = 8 * 8 * NFCA_T_SIG;
for(size_t i = 1; i < 9; i++) {
signal->edge_timings[i] = 8 * NFCA_T_SIG;
}
signal->edge_cnt = 9;
}
}
static void nfca_add_byte(NfcaSignal* nfca_signal, uint8_t byte, bool parity) {
for(uint8_t i = 0; i < 8; i++) {
if(byte & (1 << i)) {
digital_signal_append(nfca_signal->tx_signal, nfca_signal->one);
} else {
digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero);
}
}
if(parity) {
digital_signal_append(nfca_signal->tx_signal, nfca_signal->one);
} else {
digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero);
}
}
NfcaSignal* nfca_signal_alloc() {
NfcaSignal* nfca_signal = malloc(sizeof(NfcaSignal));
nfca_signal->one = digital_signal_alloc(10);
nfca_signal->zero = digital_signal_alloc(10);
nfca_add_bit(nfca_signal->one, true);
nfca_add_bit(nfca_signal->zero, false);
nfca_signal->tx_signal = digital_signal_alloc(NFCA_SIGNAL_MAX_EDGES);
return nfca_signal;
}
void nfca_signal_free(NfcaSignal* nfca_signal) {
furi_assert(nfca_signal);
digital_signal_free(nfca_signal->one);
digital_signal_free(nfca_signal->zero);
digital_signal_free(nfca_signal->tx_signal);
free(nfca_signal);
}
void nfca_signal_encode(NfcaSignal* nfca_signal, uint8_t* data, uint16_t bits, uint8_t* parity) {
furi_assert(nfca_signal);
furi_assert(data);
furi_assert(parity);
nfca_signal->tx_signal->edge_cnt = 0;
nfca_signal->tx_signal->start_level = true;
// Start of frame
digital_signal_append(nfca_signal->tx_signal, nfca_signal->one);
if(bits < 8) {
for(size_t i = 0; i < bits; i++) {
if(FURI_BIT(data[0], i)) {
digital_signal_append(nfca_signal->tx_signal, nfca_signal->one);
} else {
digital_signal_append(nfca_signal->tx_signal, nfca_signal->zero);
}
}
} else {
for(size_t i = 0; i < bits / 8; i++) {
nfca_add_byte(nfca_signal, data[i], parity[i / 8] & (1 << (7 - (i & 0x07))));
}
}
}