cleaned up SLIX code

fixed byte order mixup
read larger cards
This commit is contained in:
g3gg0
2022-11-17 21:49:29 +01:00
parent b4802247df
commit 971e0093c4
8 changed files with 271 additions and 108 deletions
+2 -2
View File
@@ -276,7 +276,7 @@ static void nfc_cli_st25r_trans(Cli* cli, FuriString* args) {
printf("ISO15693 emulator...\r\nPress Ctrl+C to abort\r\n");
FuriHalNfcDevData nfc_data = {
.uid = { 0x36, 0x78, 0x45, 0x0E, 0x50, 0x03, 0x04, 0xE0 },
.uid = { 0xE0, 0x04, 0x45, 0x03, 0x50, 0x0E, 0x78, 0x36 },
.uid_len = 8,
.type = FuriHalNfcTypeV,
};
@@ -295,7 +295,7 @@ static void nfc_cli_st25r_trans(Cli* cli, FuriString* args) {
memset(nfcv_data.data, 0xAE, 4 * 8);
nfcv_emu_init();
nfcv_emu_init(&nfc_data, &nfcv_data);
while(!cli_cmd_interrupt_received(cli)) {
if(nfcv_emu_loop(&nfc_data, &nfcv_data, 1000)) {
printf("[NfcV-Emu] %s\r\n", nfcv_data.last_command);
@@ -7,6 +7,17 @@ void nfc_scene_nfc_data_info_widget_callback(GuiButtonType result, InputType typ
}
}
uint32_t nfc_scene_nfc_data_info_get_key(uint8_t *data) {
uint32_t value = 0;
for(uint32_t pos = 0; pos < 4; pos++) {
value <<= 8;
value |= data[pos];
}
return value;
}
void nfc_scene_nfc_data_info_on_enter(void* context) {
Nfc* nfc = context;
Widget* widget = nfc->widget;
@@ -85,13 +96,59 @@ void nfc_scene_nfc_data_info_on_enter(void* context) {
furi_string_cat_printf(temp_str, "Data (%d byte)\n", nfcv_data->block_num * nfcv_data->block_size);
for(int block = 0; block < nfcv_data->block_num; block++) {
int maxBlocks = nfcv_data->block_num;
if(maxBlocks > 32) {
maxBlocks = 32;
furi_string_cat_printf(temp_str, "(truncated to %d blocks)\n", maxBlocks);
}
for(int block = 0; block < maxBlocks; block++) {
for(int pos = 0; pos < nfcv_data->block_size; pos++) {
furi_string_cat_printf(temp_str, " %02X", nfcv_data->data[block * nfcv_data->block_size + pos]);
}
furi_string_cat_printf(temp_str, "\n");
}
furi_string_cat_printf(temp_str, "\n");
switch (dev_data->nfcv_data.type)
{
case NfcVTypePlain:
furi_string_cat_printf(temp_str, "Type: Plain\n");
break;
case NfcVTypeSlix:
furi_string_cat_printf(temp_str, "Type: SLIX\n");
furi_string_cat_printf(temp_str, "Keys:\n");
furi_string_cat_printf(temp_str, " EAS %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix.key_eas));
break;
case NfcVTypeSlixS:
furi_string_cat_printf(temp_str, "Type: SLIX-S\n");
furi_string_cat_printf(temp_str, "Keys:\n");
furi_string_cat_printf(temp_str, " Read %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_s.key_read));
furi_string_cat_printf(temp_str, " Write %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_s.key_write));
furi_string_cat_printf(temp_str, " Privacy %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_s.key_privacy));
furi_string_cat_printf(temp_str, " Destroy %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_s.key_destroy));
furi_string_cat_printf(temp_str, " EAS %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_s.key_eas));
break;
case NfcVTypeSlixL:
furi_string_cat_printf(temp_str, "Type: SLIX-L\n");
furi_string_cat_printf(temp_str, "Keys:\n");
furi_string_cat_printf(temp_str, " Privacy %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_l.key_privacy));
furi_string_cat_printf(temp_str, " Destroy %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_l.key_destroy));
furi_string_cat_printf(temp_str, " EAS %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix_l.key_eas));
break;
case NfcVTypeSlix2:
furi_string_cat_printf(temp_str, "Type: SLIX2\n");
furi_string_cat_printf(temp_str, "Keys:\n");
furi_string_cat_printf(temp_str, " Read %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix2.key_read));
furi_string_cat_printf(temp_str, " Write %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix2.key_write));
furi_string_cat_printf(temp_str, " Privacy %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix2.key_privacy));
furi_string_cat_printf(temp_str, " Destroy %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix2.key_destroy));
furi_string_cat_printf(temp_str, " EAS %08lX\n", nfc_scene_nfc_data_info_get_key(nfcv_data->sub_data.slix2.key_eas));
break;
default:
furi_string_cat_printf(temp_str, "\e#ISO15693 (unknown)\n");
break;
}
} else {
char iso_type = FURI_BIT(nfc_data->sak, 5) ? '4' : '3';
furi_string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type);
+13 -7
View File
@@ -807,23 +807,26 @@ bool nfc_device_load_slix2_data(FlipperFormat* file, NfcDevice* dev) {
static bool nfc_device_save_nfcv_data(FlipperFormat* file, NfcDevice* dev) {
bool saved = false;
uint8_t temp_value = 0;
NfcVData* data = &dev->dev_data.nfcv_data;
do {
uint32_t temp_uint32 = 0;
uint8_t temp_uint8 = 0;
if(!flipper_format_write_hex(file, "DSFID", &(data->dsfid), 1)) break;
if(!flipper_format_write_hex(file, "AFI", &(data->afi), 1)) break;
if(!flipper_format_write_hex(file, "IC Reference", &(data->ic_ref), 1)) break;
if(!flipper_format_write_hex(file, "Block Count", &(data->block_num), 1)) break;
temp_uint32 = data->block_num;
if(!flipper_format_write_uint32(file, "Block Count", &temp_uint32, 1)) break;
if(!flipper_format_write_hex(file, "Block Size", &(data->block_size), 1)) break;
if(!flipper_format_write_hex(file, "Data Content", data->data, data->block_num * data->block_size)) break;
if(!flipper_format_write_comment_cstr(file, "Subtype of this card (0 = ISO15693, 1 = SLIX, 2 = SLIX-S, 3 = SLIX-L, 4 = SLIX2)")) break;
temp_value = data->type;
if(!flipper_format_write_hex(file, "Subtype", &temp_value, 1)) break;
temp_uint8 = (uint8_t)data->type;
if(!flipper_format_write_hex(file, "Subtype", &temp_uint8, 1)) break;
switch(data->type) {
case NfcVTypePlain:
if(!flipper_format_write_comment_cstr(file, "End of ISO15693 parameters")) break;
saved = true;
break;
case NfcVTypeSlix:
@@ -846,16 +849,19 @@ static bool nfc_device_save_nfcv_data(FlipperFormat* file, NfcDevice* dev) {
bool nfc_device_load_nfcv_data(FlipperFormat* file, NfcDevice* dev) {
bool parsed = false;
uint8_t temp_value = 0;
NfcVData* data = &dev->dev_data.nfcv_data;
memset(data, 0, sizeof(NfcVData));
do {
uint32_t temp_uint32 = 0;
uint8_t temp_value = 0;
if(!flipper_format_read_hex(file, "DSFID", &(data->dsfid), 1)) break;
if(!flipper_format_read_hex(file, "AFI", &(data->afi), 1)) break;
if(!flipper_format_read_hex(file, "IC Reference", &(data->ic_ref), 1)) break;
if(!flipper_format_read_hex(file, "Block Count", &(data->block_num), 1)) break;
if(!flipper_format_read_uint32(file, "Block Count", &temp_uint32, 1)) break;
data->block_num = temp_uint32;
if(!flipper_format_read_hex(file, "Block Size", &(data->block_size), 1)) break;
if(!flipper_format_read_hex(
file, "Data Content", data->data, data->block_num * data->block_size))
+60 -57
View File
@@ -6,6 +6,7 @@
#define TAG "NfcWorker"
/***************************** NFC Worker API *******************************/
NfcWorker* nfc_worker_alloc() {
@@ -122,6 +123,31 @@ int32_t nfc_worker_task(void* context) {
return 0;
}
static bool nfc_worker_read_nfcv_content(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
bool read_success = false;
NfcVReader reader = {};
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
NfcVData* nfcv_data = &nfc_worker->dev_data->nfcv_data;
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false);
reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
}
do {
if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 200)) break;
if(!nfcv_read_card(&reader, nfc_data, nfcv_data)) break;
read_success = true;
} while(false);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_stop(nfc_worker->reader_analyzer);
}
return read_success;
}
void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
furi_assert(nfc_worker);
@@ -129,6 +155,8 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
NfcVData* nfcv_data = &nfc_worker->dev_data->nfcv_data;
FuriHalNfcTxRxContext tx_rx = {};
uint8_t *key_data = nfcv_data->sub_data.slix_l.key_privacy;
uint32_t key = 0;
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, &tx_rx, true);
@@ -153,21 +181,20 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc);
furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCV);
uint8_t rand[2];
furi_hal_console_printf("Detect presence\r\n");
ReturnCode ret = slix_l_get_random(rand);
ReturnCode ret = slix_l_get_random(nfcv_data);
if(ret == ERR_NONE) {
/* there is some chip, responding with a RAND */
nfc_worker->dev_data->protocol = NfcDeviceProtocolNfcV;
furi_hal_console_printf(" Chip detected. In privacy?\r\n");
ret = nfcv_inventory(NULL);
if(ret == ERR_NONE) {
/* chip is also visible, so no action required, just save */
if(nfc_worker->state == NfcWorkerStateNfcVUnlockAndSave) {
NfcVReader reader;
NfcVReader reader = {};
if(!nfcv_read_card(&reader, &nfc_worker->dev_data->nfc_data, nfcv_data)) {
furi_hal_console_printf(" => failed, wait for chip to disappear.\r\n");
snprintf(nfcv_data->error, sizeof(nfcv_data->error), "Read card\nfailed");
@@ -190,21 +217,32 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
while(slix_l_get_random(NULL) == ERR_NONE) {
furi_delay_ms(100);
}
key_data[0] = 0;
key_data[1] = 0;
key_data[2] = 0;
key_data[3] = 0;
} else {
/* chip is invisible, try to unlock */
furi_hal_console_printf(" chip is invisible, unlocking\r\n");
if(nfcv_data->auth_method == NfcVAuthMethodManual) {
uint32_t key = 0;
uint8_t *key_data = nfc_worker->dev_data->nfcv_data.sub_data.slix_l.key_privacy;
key |= key_data[0] << 24;
key |= key_data[1] << 16;
key |= key_data[2] << 8;
key |= key_data[3] << 0;
ret = slix_l_unlock(4, rand, key);
ret = slix_l_unlock(nfcv_data, 4);
} else {
ret = slix_l_unlock(4, rand, 0x7FFD6E5B);
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);
if(ret != ERR_NONE) {
/* main key failed, trying second one */
furi_hal_console_printf(" trying second key after resetting\r\n");
@@ -214,10 +252,16 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
furi_delay_ms(20);
furi_hal_nfc_ll_txrx_on();
if(slix_l_get_random(rand) != ERR_NONE) {
if(slix_l_get_random(nfcv_data) != ERR_NONE) {
furi_hal_console_printf(" reset failed\r\n");
}
ret = slix_l_unlock(4, rand, 0x0F0F0F0F);
key = 0x0F0F0F0F;
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);
}
}
if(ret != ERR_NONE) {
@@ -251,27 +295,6 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
}
}
static bool nfc_worker_read_nfcv_content(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
bool read_success = false;
NfcVReader reader = {};
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false);
reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
}
do {
if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 200)) break;
if(!nfcv_read_card(&reader, &nfc_worker->dev_data->nfc_data, &nfc_worker->dev_data->nfcv_data)) break;
read_success = true;
} while(false);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_stop(nfc_worker->reader_analyzer);
}
return read_success;
}
static bool nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
@@ -491,9 +514,6 @@ static bool nfc_worker_read_nfcv(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t
furi_assert(nfc_worker);
furi_assert(tx_rx);
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
NfcVData* nfcv_data = &nfc_worker->dev_data->nfcv_data;
bool card_read = false;
furi_hal_nfc_sleep();
@@ -501,24 +521,6 @@ static bool nfc_worker_read_nfcv(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t
we will read it here again and it will get placed in the right order. */
card_read = nfc_worker_read_nfcv_content(nfc_worker, tx_rx);
nfc_worker->dev_data->protocol = NfcDeviceProtocolNfcV;
if(slix_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX detected");
nfcv_data->type = NfcVTypeSlix;
} else if(slix2_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX2 detected");
nfcv_data->type = NfcVTypeSlix2;
} else if(slix_s_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX-L detected");
nfcv_data->type = NfcVTypeSlixS;
} else if(slix_l_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX-L detected");
nfcv_data->type = NfcVTypeSlixL;
} else {
nfcv_data->type = NfcVTypePlain;
}
return card_read;
}
@@ -570,12 +572,13 @@ void nfc_worker_read(NfcWorker* nfc_worker) {
break;
} else if(nfc_data->type == FuriHalNfcTypeV) {
FURI_LOG_I(TAG, "NfcV detected");
nfc_worker->dev_data->protocol = NfcDeviceProtocolNfcV;
if(nfc_worker_read_nfcv(nfc_worker, &tx_rx)) {
FURI_LOG_I(TAG, "nfc_worker_read_nfcv success");
event = NfcWorkerEventReadNfcV;
break;
//event = NfcWorkerEventReadNfcV;
//break;
}
event = NfcWorkerEventReadUidNfcV;
event = NfcWorkerEventReadNfcV;
break;
}
} else {
@@ -622,7 +625,7 @@ void nfc_worker_emulate_nfcv(NfcWorker* nfc_worker) {
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
NfcVData* nfcv_data = &nfc_worker->dev_data->nfcv_data;
nfcv_emu_init();
nfcv_emu_init(nfc_data, nfcv_data);
while(nfc_worker->state == NfcWorkerStateNfcVEmulate) {
if(nfcv_emu_loop(nfc_data, nfcv_data, 1000)) {
if(nfc_worker->callback) {
+100 -27
View File
@@ -15,15 +15,24 @@
#include "nfcv.h"
#include "nfc_util.h"
#include "slix.h"
#define TAG "NfcV"
ReturnCode nfcv_inventory(uint8_t* uid) {
uint16_t received = 0;
rfalNfcvInventoryRes res;
ReturnCode ret = ERR_NONE;
/* TODO: needs proper abstraction via fury_hal(_ll)_* */
ReturnCode ret = rfalNfcvPollerInventory(RFAL_NFCV_NUM_SLOTS_1, 0, NULL, &res, &received);
for(int tries = 0; tries < 5; tries++) {
/* TODO: needs proper abstraction via fury_hal(_ll)_* */
ret = rfalNfcvPollerInventory(
RFAL_NFCV_NUM_SLOTS_1, 0, NULL, &res, &received);
if(ret == ERR_NONE) {
break;
}
}
if(ret == ERR_NONE) {
if(uid != NULL) {
@@ -37,18 +46,24 @@ ReturnCode nfcv_inventory(uint8_t* uid) {
ReturnCode nfcv_read_blocks(
NfcVReader* reader,
NfcVData* data) {
reader->blocks_read = 0;
UNUSED(reader);
uint16_t received = 0;
for(size_t block = 0; block < data->block_num; block++) {
uint8_t rxBuf[32];
FURI_LOG_D(TAG, "Reading block %d", block);
FURI_LOG_D(TAG, "Reading block %d/%d", block, (data->block_num - 1));
ReturnCode ret = rfalNfcvPollerReadSingleBlock(
RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, block,
rxBuf, sizeof(rxBuf), &received);
ReturnCode ret = ERR_NONE;
for(int tries = 0; tries < 5; tries++) {
ret = rfalNfcvPollerReadSingleBlock(
RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, block,
rxBuf, sizeof(rxBuf), &received);
if(ret == ERR_NONE) {
break;
}
}
if(ret != ERR_NONE) {
FURI_LOG_D(TAG, "failed to read: %d", ret);
return ret;
@@ -57,24 +72,27 @@ ReturnCode nfcv_read_blocks(
FURI_LOG_D(TAG, " %02X %02X %02X %02X",
data->data[block * data->block_size + 0], data->data[block * data->block_size + 1],
data->data[block * data->block_size + 2], data->data[block * data->block_size + 3]);
reader->blocks_read++;
}
FURI_LOG_D(TAG, "Read %d blocks", reader->blocks_read);
return ERR_NONE;
}
ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) {
uint8_t rxBuf[32];
uint16_t received = 0;
ReturnCode ret = ERR_NONE;
FURI_LOG_D(TAG, "Read SystemInformation...");
FURI_LOG_D(TAG, "Read SYSTEM INFORMATION...");
ReturnCode ret = rfalNfcvPollerGetSystemInformation(
RFAL_NFCV_REQ_FLAG_DEFAULT, NULL,
rxBuf, sizeof(rxBuf), &received);
for(int tries = 0; tries < 5; tries++) {
/* TODO: needs proper abstraction via fury_hal(_ll)_* */
ret = rfalNfcvPollerGetSystemInformation(
RFAL_NFCV_REQ_FLAG_DEFAULT, NULL, rxBuf, sizeof(rxBuf), &received);
if(ret == ERR_NONE) {
break;
}
}
if(ret == ERR_NONE) {
nfc_data->type = FuriHalNfcTypeV;
@@ -88,6 +106,9 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) {
data->block_num = rxBuf[12] + 1;
data->block_size = rxBuf[13] + 1;
data->ic_ref = rxBuf[14];
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],
nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
FURI_LOG_D(TAG, " DSFID %d, AFI %d, Blocks %d, Size %d, IC Ref %d", data->dsfid, data->afi, data->block_num, data->block_size, data->ic_ref);
return ret;
}
@@ -101,14 +122,34 @@ bool nfcv_read_card(
FuriHalNfcDevData* nfc_data,
NfcVData* nfcv_data) {
furi_assert(reader);
furi_assert(nfc_data);
furi_assert(nfcv_data);
if(nfcv_read_sysinfo(nfc_data, nfcv_data) != ERR_NONE) {
return false;
}
reader->blocks_to_read = nfcv_data->block_num;
return (nfcv_read_blocks(reader, nfcv_data) == ERR_NONE);
if(nfcv_read_blocks(reader, nfcv_data) != ERR_NONE) {
return false;
}
if(slix_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX detected");
nfcv_data->type = NfcVTypeSlix;
} else if(slix2_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX2 detected");
nfcv_data->type = NfcVTypeSlix2;
} else if(slix_s_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX-S detected");
nfcv_data->type = NfcVTypeSlixS;
} else if(slix_l_check_card_type(nfc_data)) {
FURI_LOG_I(TAG, "NXP SLIX-L detected");
nfcv_data->type = NfcVTypeSlixL;
} else {
nfcv_data->type = NfcVTypePlain;
}
return true;
}
/* emulation part */
@@ -296,7 +337,26 @@ int nfcv_uidcmp(uint8_t *dst, uint8_t *src) {
return 0;
}
uint32_t nfcv_read_le(uint8_t *data, uint32_t length) {
uint32_t value = 0;
for(uint32_t pos = 0; pos < length; pos++) {
value |= data[pos] << ((int)pos * 8);
}
return value;
}
uint32_t nfcv_read_be(uint8_t *data, uint32_t length) {
uint32_t value = 0;
for(uint32_t pos = 0; pos < length; pos++) {
value <<= 8;
value |= data[pos];
}
return value;
}
void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint8_t* payload, uint32_t payload_length) {
@@ -307,7 +367,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
uint8_t flags = payload[0];
uint8_t command = payload[1];
bool addressed = !(flags & RFAL_NFCV_REQ_FLAG_INVENTORY) && (flags & RFAL_NFCV_REQ_FLAG_ADDRESS);
bool advanced = addressed && (command >= 0xA0);
bool advanced = (command >= 0xA0);
uint8_t address_offset = 2 + (advanced ? 1 : 0);
uint8_t payload_offset = address_offset + (addressed ? 8 : 0);
uint8_t *address = &payload[address_offset];
@@ -315,7 +375,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
if(addressed && nfcv_uidcmp(address, nfc_data->uid)) {
printf("addressed packet, but not for us:\r\n");
printf(" destination: %02X%02X%02X%02X%02X%02X%02X%02X\r\n", address[7], address[6], address[5], address[4], address[3], address[2], address[1], address[0]);
printf(" our UID: %02X%02X%02X%02X%02X%02X%02X%02X\r\n", nfc_data->uid[7], nfc_data->uid[6], nfc_data->uid[5], nfc_data->uid[4], nfc_data->uid[3], nfc_data->uid[2], nfc_data->uid[1], nfc_data->uid[0]);
printf(" our UID: %02X%02X%02X%02X%02X%02X%02X%02X\r\n", 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;
}
@@ -326,7 +386,9 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
if(nfcv_data->sub_data.slix_l.privacy &&
command != ISO15693_CMD_NXP_GET_RANDOM_NUMBER &&
command != ISO15693_CMD_NXP_SET_PASSWORD) {
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "(command ignored, privacy)");
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "command 0x%02X ignored, privacy mode", command);
FURI_LOG_D(TAG, "%s", nfcv_data->last_command);
return;
}
break;
@@ -434,8 +496,8 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
nfcv_data->sub_data.slix_l.rand[1] = 0x00;
response_buffer[0] = ISO15693_NOERROR;
response_buffer[1] = nfcv_data->sub_data.slix_l.rand[0];
response_buffer[2] = nfcv_data->sub_data.slix_l.rand[1];
response_buffer[1] = nfcv_data->sub_data.slix_l.rand[1];
response_buffer[2] = nfcv_data->sub_data.slix_l.rand[0];
nfcv_emu_send(response_buffer, 3);
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "GET_RANDOM_NUMBER");
@@ -466,14 +528,16 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
}
for(int pos = 0; pos < 4; pos++) {
password_rcv[pos] = password_xored[pos] ^ rand[pos % 2];
password_rcv[pos] = password_xored[3 - pos] ^ rand[pos % 2];
}
uint32_t pass_expect = nfcv_read_be(password, 4);
uint32_t pass_received = nfcv_read_be(password_rcv, 4);
if(!memcmp(password, password_rcv, 4)) {
if(pass_expect == pass_received) {
status = ISO15693_NOERROR;
nfcv_data->sub_data.slix_l.privacy = false;
} else {
printf("pass mismatch: %08lX %08lX %02X", *((uint32_t *)password), *((uint32_t *)password_xored), *rand);
FURI_LOG_D(TAG, "Password #%d mismatch. Expected 0x%08lX, got 0x%08lX", password_id, pass_expect, pass_received);
}
response_buffer[0] = status;
@@ -505,7 +569,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
uint32_t nfcv_timer_buffer_src[32];
uint32_t nfcv_timer_buffer[1024];
void nfcv_emu_init() {
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
nfcv_emu_alloc();
rfal_platform_spi_acquire();
@@ -516,6 +580,15 @@ void nfcv_emu_init() {
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
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],
nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]);
FURI_LOG_D(TAG, " Card type: %d", nfcv_data->type);
FURI_LOG_D(TAG, " Privacy pass: 0x%08lX", nfcv_read_be(nfcv_data->sub_data.slix_l.key_privacy, 4));
FURI_LOG_D(TAG, " Privacy mode: %s", nfcv_data->sub_data.slix_l.privacy ? "ON" : "OFF");
#if 0
memset(nfcv_timer_buffer_src, 0xEE, sizeof(nfcv_timer_buffer_src));
memset(nfcv_timer_buffer, 0xFA, sizeof(nfcv_timer_buffer));
+3 -3
View File
@@ -15,7 +15,7 @@
#define DIGITAL_SIGNAL_UNIT_S (100000000000.0f)
#define DIGITAL_SIGNAL_UNIT_US (100000.0f)
#define NFCV_TOTAL_BLOCKS_MAX 32
#define NFCV_TOTAL_BLOCKS_MAX 256
#define NFCV_BLOCK_SIZE 4
#define NFCV_MAX_DUMP_SIZE (NFCV_BLOCK_SIZE*NFCV_TOTAL_BLOCKS_MAX)
@@ -133,7 +133,7 @@ typedef struct {
uint8_t dsfid;
uint8_t afi;
uint8_t ic_ref;
uint8_t block_num;
uint16_t block_num;
uint8_t block_size;
uint8_t data[NFCV_MAX_DUMP_SIZE];
@@ -158,6 +158,6 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data);
ReturnCode nfcv_inventory(uint8_t* uid);
bool nfcv_read_card(NfcVReader* reader, FuriHalNfcDevData* nfc_data, NfcVData* data);
void nfcv_emu_init();
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data);
void nfcv_emu_deinit();
bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t timeout_ms);
+33 -9
View File
@@ -46,7 +46,7 @@ bool slix_l_check_card_type(FuriHalNfcDevData* nfc_data) {
}
ReturnCode slix_l_get_random(uint8_t* rand) {
ReturnCode slix_l_get_random(NfcVData* data) {
uint16_t received = 0;
uint8_t rxBuf[32];
@@ -65,26 +65,50 @@ ReturnCode slix_l_get_random(uint8_t* rand) {
if(received != 3) {
return ERR_PROTO;
}
if(rand != NULL) {
memcpy(rand, &rxBuf[1], 2);
if(data != NULL) {
data->sub_data.slix_l.rand[0] = rxBuf[2];
data->sub_data.slix_l.rand[1] = rxBuf[1];
}
}
return ret;
}
ReturnCode slix_l_unlock(uint32_t id, uint8_t* rand, uint32_t password) {
ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id) {
furi_assert(rand);
uint16_t received = 0;
uint8_t rxBuf[32];
uint8_t cmd_set_pass[] = {
id,
rand[0] ^ ((password >> 0) & 0xFF),
rand[1] ^ ((password >> 8) & 0xFF),
rand[0] ^ ((password >> 16) & 0xFF),
rand[1] ^ ((password >> 24) & 0xFF)
password_id,
data->sub_data.slix_l.rand[1],
data->sub_data.slix_l.rand[0],
data->sub_data.slix_l.rand[1],
data->sub_data.slix_l.rand[0]
};
uint8_t *password = NULL;
switch(password_id) {
case 4:
password = data->sub_data.slix_l.key_privacy;
break;
case 8:
password = data->sub_data.slix_l.key_destroy;
break;
case 10:
password = data->sub_data.slix_l.key_eas;
break;
default:
break;
}
if(!password) {
return ERR_NOTSUPP;
}
for(int pos = 0; pos < 4; pos++) {
cmd_set_pass[1 + pos] ^= password[3 - pos];
}
ReturnCode ret = rfalNfcvPollerTransceiveReq(
ISO15693_CMD_NXP_SET_PASSWORD,
+2 -2
View File
@@ -14,6 +14,6 @@ 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(uint8_t* rand);
ReturnCode slix_l_unlock(uint32_t id, uint8_t* rand, uint32_t password);
ReturnCode slix_l_get_random(NfcVData* data);
ReturnCode slix_l_unlock(NfcVData* data, uint32_t password_id);