better layer separation for ISO15693

This commit is contained in:
g3gg0
2022-11-29 02:15:20 +01:00
parent 1b6b4b6522
commit 1489e3e676
5 changed files with 69 additions and 63 deletions
+8 -8
View File
@@ -181,7 +181,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCV);
furi_hal_console_printf("Detect presence\r\n");
ReturnCode ret = slix_l_get_random(nfcv_data);
ReturnCode ret = slix_get_random(nfcv_data);
if(ret == ERR_NONE) {
/* there is some chip, responding with a RAND */
@@ -207,13 +207,13 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
}
while(slix_l_get_random(NULL) == ERR_NONE) {
while(slix_get_random(NULL) == ERR_NONE) {
furi_delay_ms(100);
}
furi_hal_console_printf(" => chip is already visible, wait for chip to disappear.\r\n");
nfc_worker->callback(NfcWorkerEventAborted, nfc_worker->context);
while(slix_l_get_random(NULL) == ERR_NONE) {
while(slix_get_random(NULL) == ERR_NONE) {
furi_delay_ms(100);
}
@@ -233,14 +233,14 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
key |= key_data[2] << 8;
key |= key_data[3] << 0;
ret = slix_l_unlock(nfcv_data, 4);
ret = slix_unlock(nfcv_data, 4);
} else {
key = 0x7FFD6E5B;
key_data[0] = key >> 24;
key_data[1] = key >> 16;
key_data[2] = key >> 8;
key_data[3] = key >> 0;
ret = slix_l_unlock(nfcv_data, 4);
ret = slix_unlock(nfcv_data, 4);
if(ret != ERR_NONE) {
/* main key failed, trying second one */
@@ -251,7 +251,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
furi_delay_ms(20);
furi_hal_nfc_ll_txrx_on();
if(slix_l_get_random(nfcv_data) != ERR_NONE) {
if(slix_get_random(nfcv_data) != ERR_NONE) {
furi_hal_console_printf(" reset failed\r\n");
}
@@ -260,7 +260,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
key_data[1] = key >> 16;
key_data[2] = key >> 8;
key_data[3] = key >> 0;
ret = slix_l_unlock(nfcv_data, 4);
ret = slix_unlock(nfcv_data, 4);
}
}
if(ret != ERR_NONE) {
@@ -275,7 +275,7 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
furi_hal_nfc_ll_txrx_on();
/* wait for disappearing */
while(slix_l_get_random(NULL) == ERR_NONE) {
while(slix_get_random(NULL) == ERR_NONE) {
furi_delay_ms(100);
}
}
+27 -25
View File
@@ -310,40 +310,40 @@ static int nfcv_uidcmp(uint8_t *dst, uint8_t *src) {
return 0;
}
void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint8_t* payload, uint32_t payload_length) {
void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in, uint8_t* payload, uint32_t payload_length) {
if(!payload_length) {
return;
}
NfcVData* nfcv_data = (NfcVData*)nfcv_data_in;
NfcVEmuProtocolCtx* ctx = &nfcv_data->emu_protocol_ctx;
ctx->payload = payload;
ctx->flags = ctx->payload[0];
ctx->command = ctx->payload[1];
ctx->frame = payload;
ctx->frame_length = payload_length;
ctx->flags = ctx->frame[0];
ctx->command = ctx->frame[1];
ctx->addressed = !(ctx->flags & RFAL_NFCV_REQ_FLAG_INVENTORY) && (ctx->flags & RFAL_NFCV_REQ_FLAG_ADDRESS);
ctx->advanced = (ctx->command >= 0xA0);
ctx->address_offset = 2 + (ctx->advanced ? 1 : 0);
ctx->payload_offset = ctx->address_offset + (ctx->addressed ? 8 : 0);
ctx->address = &ctx->payload[ctx->address_offset];
ctx->response_flags = NfcVSendFlagsNormal;
bool handled = false;
/* first give control to the card specific protocol handler */
if(nfcv_data->emu_protocol_handler != NULL) {
handled = nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data);
if(nfcv_data->emu_protocol_filter != NULL) {
if(nfcv_data->emu_protocol_filter(tx_rx, nfc_data, nfcv_data)) {
return;
}
}
if(handled) {
return;
}
if(ctx->addressed && nfcv_uidcmp(ctx->address, nfc_data->uid)) {
FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", ctx->command);
FURI_LOG_D(TAG, " dest: %02X%02X%02X%02X%02X%02X%02X%02X", ctx->address[7], ctx->address[6], ctx->address[5], ctx->address[4], ctx->address[3], ctx->address[2], ctx->address[1], ctx->address[0]);
FURI_LOG_D(TAG, " our UID: %02X%02X%02X%02X%02X%02X%02X%02X", nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3], nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
return;
if(ctx->addressed) {
uint8_t* address = &ctx->frame[ctx->address_offset];
if(nfcv_uidcmp(address, nfc_data->uid)) {
FURI_LOG_D(TAG, "addressed command 0x%02X, but not for us:", ctx->command);
FURI_LOG_D(TAG, " dest: %02X%02X%02X%02X%02X%02X%02X%02X", address[7], address[6], address[5], address[4], address[3], address[2], address[1], address[0]);
FURI_LOG_D(TAG, " our UID: %02X%02X%02X%02X%02X%02X%02X%02X", nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3], nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
return;
}
}
/* unfortunately our response is quicker than the original NFC tag which causes frame misses */
@@ -379,11 +379,11 @@ void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc
case ISO15693_READ_MULTI_BLOCK:
case ISO15693_READBLOCK: {
uint8_t block = ctx->payload[ctx->payload_offset];
uint8_t block = ctx->frame[ctx->payload_offset];
uint8_t blocks = 1;
if(ctx->command == ISO15693_READ_MULTI_BLOCK) {
blocks = ctx->payload[ctx->payload_offset + 1] + 1;
blocks = ctx->frame[ctx->payload_offset + 1] + 1;
}
if(block + blocks > nfcv_data->block_num) {
@@ -400,23 +400,23 @@ void nfcv_emu_handle_packet(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc
case ISO15693_WRITE_MULTI_BLOCK:
case ISO15693_WRITEBLOCK: {
uint8_t block = ctx->payload[ctx->payload_offset];
uint8_t block = ctx->frame[ctx->payload_offset];
uint8_t blocks = 1;
uint8_t data_pos = 1;
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
blocks = ctx->payload[ctx->payload_offset + 1] + 1;
blocks = ctx->frame[ctx->payload_offset + 1] + 1;
data_pos++;
}
uint8_t *data = &ctx->payload[ctx->payload_offset + data_pos];
uint8_t *data = &ctx->frame[ctx->payload_offset + data_pos];
uint32_t data_len = nfcv_data->block_size * blocks;
if(block + blocks > nfcv_data->block_num || ctx->payload_offset + data_len + 2 > payload_length) {
ctx->response_buffer[0] = ISO15693_ERROR_CMD_NOT_REC;
} else {
ctx->response_buffer[0] = ISO15693_NOERROR;
memcpy(&nfcv_data->data[nfcv_data->block_size * block], &ctx->payload[ctx->payload_offset + data_pos], data_len);
memcpy(&nfcv_data->data[nfcv_data->block_size * block], &ctx->frame[ctx->payload_offset + data_pos], data_len);
}
nfcv_emu_send(tx_rx, nfcv_data, ctx->response_buffer, 1, ctx->response_flags);
@@ -464,6 +464,8 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet;
FURI_LOG_D(TAG, "Starting NfcV emulation");
FURI_LOG_D(TAG, " UID: %02X %02X %02X %02X %02X %02X %02X %02X",
nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3],
@@ -650,7 +652,7 @@ bool nfcv_emu_loop(FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, Nf
if(tx_rx->sniff_rx) {
tx_rx->sniff_rx(frame_payload, frame_pos * 8, false, tx_rx->sniff_context);
}
nfcv_emu_handle_packet(tx_rx, nfc_data, nfcv_data, frame_payload, frame_pos);
nfcv_data->emu_protocol_handler(tx_rx, nfc_data, nfcv_data, frame_payload, frame_pos);
pulse_reader_start(nfcv_data->emu_air.reader_signal);
ret = true;
}
+15 -11
View File
@@ -122,19 +122,22 @@ typedef struct {
typedef struct {
uint8_t* payload;
uint8_t flags;
uint8_t command;
bool addressed;
bool advanced;
uint8_t address_offset;
uint8_t payload_offset;
uint8_t* address;
uint8_t response_buffer[128];
NfcVSendFlags response_flags;
uint8_t* frame; /* ISO15693-2 incoming raw data from air layer */
uint8_t frame_length; /* ISO15693-2 length of incoming data */
uint8_t flags; /* ISO15693-3 flags of the header as specified */
uint8_t command; /* ISO15693-3 command at offset 1 as specified */
bool addressed; /* ISO15693-3 flags: addressed frame */
bool advanced; /* ISO15693-3 command: advanced command */
uint8_t address_offset; /* ISO15693-3 offset of the address in frame, if addressed is set */
uint8_t payload_offset; /* ISO15693-3 offset of the payload in frame */
uint8_t response_buffer[128]; /* pre-allocated response buffer */
NfcVSendFlags response_flags; /* flags to use when sending response */
} NfcVEmuProtocolCtx;
typedef bool (*NfcVEmuProtocolHandler) (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data);
typedef void (*NfcVEmuProtocolHandler) (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data, uint8_t* payload, uint32_t payload_length);
typedef bool (*NfcVEmuProtocolFilter) (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data);
typedef struct {
/* common ISO15693 fields */
@@ -151,6 +154,7 @@ typedef struct {
NfcVEmuAir emu_air;
NfcVEmuProtocolCtx emu_protocol_ctx;
NfcVEmuProtocolHandler emu_protocol_handler;
NfcVEmuProtocolFilter emu_protocol_filter;
/* runtime data */
char last_command[128];
+17 -17
View File
@@ -63,7 +63,7 @@ bool slix_l_check_card_type(FuriHalNfcDevData* nfc_data) {
}
ReturnCode slix_l_get_random(NfcVData* data) {
ReturnCode slix_get_random(NfcVData* data) {
uint16_t received = 0;
uint8_t rxBuf[32];
@@ -91,7 +91,7 @@ ReturnCode slix_l_get_random(NfcVData* data) {
return ret;
}
ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id) {
ReturnCode slix_unlock(NfcVData* data, uint32_t password_id) {
furi_assert(rand);
uint16_t received = 0;
@@ -148,7 +148,7 @@ ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id) {
}
bool slix_generic_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in, uint32_t password_supported) {
bool slix_generic_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in, uint32_t password_supported) {
furi_assert(tx_rx);
furi_assert(nfc_data);
furi_assert(nfcv_data_in);
@@ -186,13 +186,13 @@ bool slix_generic_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevD
}
case ISO15693_CMD_NXP_SET_PASSWORD: {
uint8_t password_id = ctx->payload[ctx->payload_offset];
uint8_t password_id = ctx->frame[ctx->payload_offset];
if(!(password_id & password_supported)) {
break;
}
uint8_t *password_xored = &ctx->payload[ctx->payload_offset + 1];
uint8_t *password_xored = &ctx->frame[ctx->payload_offset + 1];
uint8_t *rand = slix->rand;
uint8_t *password = NULL;
uint8_t password_rcv[4];
@@ -269,7 +269,7 @@ bool slix_generic_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevD
return handled;
}
bool slix_l_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
bool slix_l_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
furi_assert(tx_rx);
furi_assert(nfc_data);
furi_assert(nfcv_data_in);
@@ -277,7 +277,7 @@ bool slix_l_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* n
bool handled = false;
/* many SLIX share some of the functions, place that in a generic handler */
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_PRIVACY | SLIX_PASS_DESTROY | SLIX_PASS_EASAFI)) {
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_PRIVACY | SLIX_PASS_DESTROY | SLIX_PASS_EASAFI)) {
return true;
}
@@ -290,10 +290,10 @@ void slix_l_prepare(NfcVData* nfcv_data) {
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
nfcv_data->emu_protocol_handler = &slix_l_protocol_handler;
nfcv_data->emu_protocol_filter = &slix_l_protocol_filter;
}
bool slix_s_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
bool slix_s_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
furi_assert(tx_rx);
furi_assert(nfc_data);
furi_assert(nfcv_data_in);
@@ -301,7 +301,7 @@ bool slix_s_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* n
bool handled = false;
/* many SLIX share some of the functions, place that in a generic handler */
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
return true;
}
@@ -314,10 +314,10 @@ void slix_s_prepare(NfcVData* nfcv_data) {
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
nfcv_data->emu_protocol_handler = &slix_s_protocol_handler;
nfcv_data->emu_protocol_filter = &slix_s_protocol_filter;
}
bool slix_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
bool slix_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
furi_assert(tx_rx);
furi_assert(nfc_data);
furi_assert(nfcv_data_in);
@@ -325,7 +325,7 @@ bool slix_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc
bool handled = false;
/* many SLIX share some of the functions, place that in a generic handler */
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_EASAFI)) {
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_EASAFI)) {
return true;
}
@@ -338,10 +338,10 @@ void slix_prepare(NfcVData* nfcv_data) {
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
nfcv_data->emu_protocol_handler = &slix_protocol_handler;
nfcv_data->emu_protocol_filter = &slix_protocol_filter;
}
bool slix2_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
bool slix2_protocol_filter (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nfc_data, void* nfcv_data_in) {
furi_assert(tx_rx);
furi_assert(nfc_data);
furi_assert(nfcv_data_in);
@@ -349,7 +349,7 @@ bool slix2_protocol_handler (FuriHalNfcTxRxContext* tx_rx, FuriHalNfcDevData* nf
bool handled = false;
/* many SLIX share some of the functions, place that in a generic handler */
if(slix_generic_protocol_handler(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
if(slix_generic_protocol_filter(tx_rx, nfc_data, nfcv_data_in, SLIX_PASS_ALL)) {
return true;
}
@@ -362,5 +362,5 @@ void slix2_prepare(NfcVData* nfcv_data) {
FURI_LOG_D(TAG, " EAS pass: 0x%08lX", slix_read_be(nfcv_data->sub_data.slix.key_eas, 4));
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix.privacy ? "ON" : "OFF");
nfcv_data->emu_protocol_handler = &slix2_protocol_handler;
nfcv_data->emu_protocol_filter = &slix2_protocol_filter;
}
+2 -2
View File
@@ -36,8 +36,8 @@ bool slix_check_card_type(FuriHalNfcDevData* nfc_data);
bool slix2_check_card_type(FuriHalNfcDevData* nfc_data);
bool slix_s_check_card_type(FuriHalNfcDevData* nfc_data);
bool slix_l_check_card_type(FuriHalNfcDevData* nfc_data);
ReturnCode slix_l_get_random(NfcVData* data);
ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id);
ReturnCode slix_get_random(NfcVData* data);
ReturnCode slix_unlock(NfcVData* data, uint32_t password_id);
void slix_prepare(NfcVData* nfcv_data);
void slix_s_prepare(NfcVData* nfcv_data);