From e5f9af3b43cf9fbafc495e1af9ba61191114a42f Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 25 Apr 2024 18:13:52 +0100 Subject: [PATCH 1/5] mf desfire: fix incorrect long files reading --- .../mf_desfire/mf_desfire_poller_i.c | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c b/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c index 2b86318491..504ab79e06 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c @@ -75,10 +75,10 @@ MfDesfireError mf_desfire_send_chunks( const size_t rx_capacity_remaining = bit_buffer_get_capacity_bytes(rx_buffer) - bit_buffer_get_size_bytes(rx_buffer); - if(rx_size <= rx_capacity_remaining) { + if(rx_size - 1 <= rx_capacity_remaining) { bit_buffer_append_right(rx_buffer, instance->rx_buffer, sizeof(uint8_t)); } else { - FURI_LOG_W(TAG, "RX buffer overflow: ignoring %zu bytes", rx_size); + FURI_LOG_W(TAG, "RX buffer overflow: ignoring %zu bytes", rx_size - 1); } } } while(false); @@ -336,23 +336,40 @@ MfDesfireError mf_desfire_poller_read_file_data( furi_check(instance); furi_check(data); - bit_buffer_reset(instance->input_buffer); - bit_buffer_append_byte(instance->input_buffer, MF_DESFIRE_CMD_READ_DATA); - bit_buffer_append_byte(instance->input_buffer, id); - bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)&offset, 3); - bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)&size, 3); + MfDesfireError error = MfDesfireErrorNone; + simple_array_init(data->data, size); - MfDesfireError error; + size_t buffer_capacity = bit_buffer_get_capacity_bytes(instance->result_buffer); + uint32_t current_offset = offset; + uint32_t bytes_read = 0; - do { - error = mf_desfire_send_chunks(instance, instance->input_buffer, instance->result_buffer); + while(bytes_read < size) { + size_t bytes_to_read = MIN(buffer_capacity, size - bytes_read); + bit_buffer_reset(instance->input_buffer); + bit_buffer_append_byte(instance->input_buffer, MF_DESFIRE_CMD_READ_DATA); + bit_buffer_append_byte(instance->input_buffer, id); + bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)¤t_offset, 3); + bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)&bytes_to_read, 3); + error = mf_desfire_send_chunks(instance, instance->input_buffer, instance->result_buffer); if(error != MfDesfireErrorNone) break; - if(!mf_desfire_file_data_parse(data, instance->result_buffer)) { + size_t bytes_received = bit_buffer_get_size_bytes(instance->result_buffer); + if(bytes_received != bytes_to_read) { + FURI_LOG_W(TAG, "Read %zu out of %zu bytes", bytes_received, bytes_to_read); error = MfDesfireErrorProtocol; + break; } - } while(false); + + uint8_t* file_data = simple_array_get_data(data->data); + bit_buffer_write_bytes(instance->result_buffer, &file_data[current_offset], bytes_to_read); + bytes_read += bytes_to_read; + current_offset += bytes_to_read; + } + + if(error != MfDesfireErrorNone) { + simple_array_reset(data->data); + } return error; } From f544aa8eb65a8d3532e28b8e04ac52ac30f89260 Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 25 Apr 2024 19:55:35 +0100 Subject: [PATCH 2/5] nfc app: trim record size for mf desfire render --- .../mf_desfire/mf_desfire_render.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/applications/main/nfc/helpers/protocol_support/mf_desfire/mf_desfire_render.c b/applications/main/nfc/helpers/protocol_support/mf_desfire/mf_desfire_render.c index f8eacd51a2..23a1a3b69a 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_desfire/mf_desfire_render.c +++ b/applications/main/nfc/helpers/protocol_support/mf_desfire/mf_desfire_render.c @@ -2,6 +2,8 @@ #include "../iso14443_4a/iso14443_4a_render.h" +#define MF_DESFIRE_RENDER_MAX_RECORD_SIZE (256U) + void nfc_render_mf_desfire_info( const MfDesfireData* data, NfcProtocolFormatType format_type, @@ -212,8 +214,6 @@ void nfc_render_mf_desfire_file_settings_data( uint32_t record_count = 1; uint32_t record_size = 0; - const uint32_t total_size = simple_array_get_count(data->data); - switch(settings->type) { case MfDesfireFileTypeStandard: case MfDesfireFileTypeBackup: @@ -257,17 +257,14 @@ void nfc_render_mf_desfire_file_settings_data( return; } + // Limit record size + bool trim_data = record_size > MF_DESFIRE_RENDER_MAX_RECORD_SIZE; + if(trim_data) { + record_size = MF_DESFIRE_RENDER_MAX_RECORD_SIZE; + } + for(uint32_t rec = 0; rec < record_count; rec++) { - const uint32_t size_offset = rec * record_size; - const uint32_t size_remaining = total_size > size_offset ? total_size - size_offset : 0; - - if(size_remaining < record_size) { - furi_string_cat_printf( - str, "record %lu (partial %lu of %lu)\n", rec, size_remaining, record_size); - record_size = size_remaining; - } else { - furi_string_cat_printf(str, "record %lu\n", rec); - } + furi_string_cat_printf(str, "record %lu\n", rec); for(uint32_t ch = 0; ch < record_size; ch += 4) { furi_string_cat_printf(str, "%03lx|", ch); @@ -296,6 +293,9 @@ void nfc_render_mf_desfire_file_settings_data( furi_string_push_back(str, '\n'); } + if(trim_data) { + furi_string_cat_str(str, "..."); + } furi_string_push_back(str, '\n'); } From 0e3cbb49118d5db51e8d52539bdb9a4df1043710 Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 25 Apr 2024 20:01:32 +0100 Subject: [PATCH 3/5] mf desfire: rework reading long record files --- .../mf_desfire/mf_desfire_poller_i.c | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c b/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c index 504ab79e06..deae2fa071 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_poller_i.c @@ -327,9 +327,10 @@ MfDesfireError mf_desfire_poller_read_file_settings_multi( return error; } -MfDesfireError mf_desfire_poller_read_file_data( +static MfDesfireError mf_desfire_poller_read_file( MfDesfirePoller* instance, MfDesfireFileId id, + uint8_t read_cmd, uint32_t offset, size_t size, MfDesfireFileData* data) { @@ -346,7 +347,7 @@ MfDesfireError mf_desfire_poller_read_file_data( while(bytes_read < size) { size_t bytes_to_read = MIN(buffer_capacity, size - bytes_read); bit_buffer_reset(instance->input_buffer); - bit_buffer_append_byte(instance->input_buffer, MF_DESFIRE_CMD_READ_DATA); + bit_buffer_append_byte(instance->input_buffer, read_cmd); bit_buffer_append_byte(instance->input_buffer, id); bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)¤t_offset, 3); bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)&bytes_to_read, 3); @@ -374,6 +375,15 @@ MfDesfireError mf_desfire_poller_read_file_data( return error; } +MfDesfireError mf_desfire_poller_read_file_data( + MfDesfirePoller* instance, + MfDesfireFileId id, + uint32_t offset, + size_t size, + MfDesfireFileData* data) { + return mf_desfire_poller_read_file(instance, id, MF_DESFIRE_CMD_READ_DATA, offset, size, data); +} + MfDesfireError mf_desfire_poller_read_file_value( MfDesfirePoller* instance, MfDesfireFileId id, @@ -406,28 +416,8 @@ MfDesfireError mf_desfire_poller_read_file_records( uint32_t offset, size_t size, MfDesfireFileData* data) { - furi_check(instance); - furi_check(data); - - bit_buffer_reset(instance->input_buffer); - bit_buffer_append_byte(instance->input_buffer, MF_DESFIRE_CMD_READ_RECORDS); - bit_buffer_append_byte(instance->input_buffer, id); - bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)&offset, 3); - bit_buffer_append_bytes(instance->input_buffer, (const uint8_t*)&size, 3); - - MfDesfireError error; - - do { - error = mf_desfire_send_chunks(instance, instance->input_buffer, instance->result_buffer); - - if(error != MfDesfireErrorNone) break; - - if(!mf_desfire_file_data_parse(data, instance->result_buffer)) { - error = MfDesfireErrorProtocol; - } - } while(false); - - return error; + return mf_desfire_poller_read_file( + instance, id, MF_DESFIRE_CMD_READ_RECORDS, offset, size, data); } MfDesfireError mf_desfire_poller_read_file_data_multi( From 42c69b076a9b283c18e3379e52d1217b015609c7 Mon Sep 17 00:00:00 2001 From: Astra Date: Fri, 26 Apr 2024 19:07:51 +0900 Subject: [PATCH 4/5] iButton: fix crash when deleting some keys --- lib/ibutton/protocols/misc/protocol_group_misc.c | 11 +++++++++++ lib/toolbox/protocols/protocol_dict.c | 9 +++++++++ lib/toolbox/protocols/protocol_dict.h | 2 ++ targets/f18/api_symbols.csv | 3 ++- targets/f7/api_symbols.csv | 3 ++- 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/ibutton/protocols/misc/protocol_group_misc.c b/lib/ibutton/protocols/misc/protocol_group_misc.c index 20534602d1..ddbbf6bd80 100644 --- a/lib/ibutton/protocols/misc/protocol_group_misc.c +++ b/lib/ibutton/protocols/misc/protocol_group_misc.c @@ -200,6 +200,16 @@ static bool ibutton_protocol_group_misc_load( } } +static void ibutton_protocol_group_misc_render_uid( + iButtonProtocolGroupMisc* group, + const iButtonProtocolData* data, + iButtonProtocolLocalId id, + FuriString* result) { + const size_t data_size = protocol_dict_get_data_size(group->dict, id); + protocol_dict_set_data(group->dict, id, data, data_size); + protocol_dict_render_uid(group->dict, result, id); +} + static void ibutton_protocol_group_misc_render_data( iButtonProtocolGroupMisc* group, const iButtonProtocolData* data, @@ -283,6 +293,7 @@ const iButtonProtocolGroupBase ibutton_protocol_group_misc = { .save = (iButtonProtocolGroupSaveFunc)ibutton_protocol_group_misc_save, .load = (iButtonProtocolGroupLoadFunc)ibutton_protocol_group_misc_load, + .render_uid = (iButtonProtocolGroupRenderFunc)ibutton_protocol_group_misc_render_uid, .render_data = (iButtonProtocolGroupRenderFunc)ibutton_protocol_group_misc_render_data, .render_brief_data = (iButtonProtocolGroupRenderFunc)ibutton_protocol_group_misc_render_brief_data, diff --git a/lib/toolbox/protocols/protocol_dict.c b/lib/toolbox/protocols/protocol_dict.c index e8da4b1cd0..b66d35335f 100644 --- a/lib/toolbox/protocols/protocol_dict.c +++ b/lib/toolbox/protocols/protocol_dict.c @@ -198,6 +198,15 @@ LevelDuration protocol_dict_encoder_yield(ProtocolDict* dict, size_t protocol_in } } +void protocol_dict_render_uid(ProtocolDict* dict, FuriString* result, size_t protocol_index) { + furi_check(protocol_index < dict->count); + ProtocolRenderData fn = dict->base[protocol_index]->render_uid; + + if(fn) { + return fn(dict->data[protocol_index], result); + } +} + void protocol_dict_render_data(ProtocolDict* dict, FuriString* result, size_t protocol_index) { furi_check(protocol_index < dict->count); ProtocolRenderData fn = dict->base[protocol_index]->render_data; diff --git a/lib/toolbox/protocols/protocol_dict.h b/lib/toolbox/protocols/protocol_dict.h index cd8503952b..dd0711732d 100644 --- a/lib/toolbox/protocols/protocol_dict.h +++ b/lib/toolbox/protocols/protocol_dict.h @@ -58,6 +58,8 @@ bool protocol_dict_encoder_start(ProtocolDict* dict, size_t protocol_index); LevelDuration protocol_dict_encoder_yield(ProtocolDict* dict, size_t protocol_index); +void protocol_dict_render_uid(ProtocolDict* dict, FuriString* result, size_t protocol_index); + void protocol_dict_render_data(ProtocolDict* dict, FuriString* result, size_t protocol_index); void protocol_dict_render_brief_data(ProtocolDict* dict, FuriString* result, size_t protocol_index); diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 7cc7639bd4..3cee044aa7 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,61.1,, +Version,+,61.2,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2251,6 +2251,7 @@ Function,+,protocol_dict_get_validate_count,uint32_t,"ProtocolDict*, size_t" Function,+,protocol_dict_get_write_data,_Bool,"ProtocolDict*, size_t, void*" Function,+,protocol_dict_render_brief_data,void,"ProtocolDict*, FuriString*, size_t" Function,+,protocol_dict_render_data,void,"ProtocolDict*, FuriString*, size_t" +Function,+,protocol_dict_render_uid,void,"ProtocolDict*, FuriString*, size_t" Function,+,protocol_dict_set_data,void,"ProtocolDict*, size_t, const uint8_t*, size_t" Function,-,pulse_reader_alloc,PulseReader*,"const GpioPin*, uint32_t" Function,-,pulse_reader_free,void,PulseReader* diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 727a512c90..c886747a31 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,61.1,, +Version,+,61.2,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -2849,6 +2849,7 @@ Function,+,protocol_dict_get_validate_count,uint32_t,"ProtocolDict*, size_t" Function,+,protocol_dict_get_write_data,_Bool,"ProtocolDict*, size_t, void*" Function,+,protocol_dict_render_brief_data,void,"ProtocolDict*, FuriString*, size_t" Function,+,protocol_dict_render_data,void,"ProtocolDict*, FuriString*, size_t" +Function,+,protocol_dict_render_uid,void,"ProtocolDict*, FuriString*, size_t" Function,+,protocol_dict_set_data,void,"ProtocolDict*, size_t, const uint8_t*, size_t" Function,-,pulse_reader_alloc,PulseReader*,"const GpioPin*, uint32_t" Function,-,pulse_reader_free,void,PulseReader* From 379e8d2a6a410380bdc772541ea420ac6467f3a1 Mon Sep 17 00:00:00 2001 From: Astra Date: Sat, 27 Apr 2024 15:53:19 +0900 Subject: [PATCH 5/5] Fix cyfral crashes --- lib/ibutton/protocols/misc/protocol_cyfral.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/ibutton/protocols/misc/protocol_cyfral.c b/lib/ibutton/protocols/misc/protocol_cyfral.c index d38865bae2..e43d0c6adb 100644 --- a/lib/ibutton/protocols/misc/protocol_cyfral.c +++ b/lib/ibutton/protocols/misc/protocol_cyfral.c @@ -325,7 +325,7 @@ static LevelDuration protocol_cyfral_encoder_yield(ProtocolCyfral* proto) { return result; } -static void protocol_cyfral_render_uid(FuriString* result, ProtocolCyfral* proto) { +static void protocol_cyfral_render_uid(ProtocolCyfral* proto, FuriString* result) { furi_string_cat_printf(result, "ID: "); for(size_t i = 0; i < CYFRAL_DATA_SIZE; ++i) { furi_string_cat_printf(result, "%02X ", ((uint8_t*)&proto->data)[i]); @@ -333,10 +333,7 @@ static void protocol_cyfral_render_uid(FuriString* result, ProtocolCyfral* proto } static void protocol_cyfral_render_brief_data(ProtocolCyfral* proto, FuriString* result) { - furi_string_cat_printf(result, "ID: "); - for(size_t i = 0; i < CYFRAL_DATA_SIZE; ++i) { - furi_string_cat_printf(result, "%02X ", ((uint8_t*)&proto->data)[i]); - } + protocol_cyfral_render_uid(proto, result); } const ProtocolBase ibutton_protocol_misc_cyfral = {