diff --git a/applications/main/nfc/helpers/protocol_support/iso14443_3a/iso14443_3a.c b/applications/main/nfc/helpers/protocol_support/iso14443_3a/iso14443_3a.c index 164278d4a2a..316ab2ba7b2 100644 --- a/applications/main/nfc/helpers/protocol_support/iso14443_3a/iso14443_3a.c +++ b/applications/main/nfc/helpers/protocol_support/iso14443_3a/iso14443_3a.c @@ -68,15 +68,18 @@ static NfcCommand Iso14443_3aListenerEvent* iso14443_3a_event = event.event_data; if(iso14443_3a_event->type == Iso14443_3aListenerEventTypeReceivedStandardFrame) { - furi_string_cat_printf(nfc->text_box_store, "R:"); - for(size_t i = 0; i < bit_buffer_get_size_bytes(iso14443_3a_event->data->buffer); i++) { - furi_string_cat_printf( - nfc->text_box_store, - " %02X", - bit_buffer_get_byte(iso14443_3a_event->data->buffer, i)); + if(furi_string_size(nfc->text_box_store) < NFC_LOG_SIZE_MAX) { + furi_string_cat_printf(nfc->text_box_store, "R:"); + for(size_t i = 0; i < bit_buffer_get_size_bytes(iso14443_3a_event->data->buffer); + i++) { + furi_string_cat_printf( + nfc->text_box_store, + " %02X", + bit_buffer_get_byte(iso14443_3a_event->data->buffer, i)); + } + furi_string_push_back(nfc->text_box_store, '\n'); + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } - furi_string_push_back(nfc->text_box_store, '\n'); - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } return NfcCommandContinue; diff --git a/applications/main/nfc/helpers/protocol_support/iso14443_4a/iso14443_4a.c b/applications/main/nfc/helpers/protocol_support/iso14443_4a/iso14443_4a.c index 74cedf566e1..12681445316 100644 --- a/applications/main/nfc/helpers/protocol_support/iso14443_4a/iso14443_4a.c +++ b/applications/main/nfc/helpers/protocol_support/iso14443_4a/iso14443_4a.c @@ -72,15 +72,18 @@ NfcCommand nfc_scene_emulate_listener_callback_iso14443_4a(NfcGenericEvent event Iso14443_4aListenerEvent* iso14443_4a_event = event.event_data; if(iso14443_4a_event->type == Iso14443_4aListenerEventTypeReceivedData) { - furi_string_cat_printf(nfc->text_box_store, "R:"); - for(size_t i = 0; i < bit_buffer_get_size_bytes(iso14443_4a_event->data->buffer); i++) { - furi_string_cat_printf( - nfc->text_box_store, - " %02X", - bit_buffer_get_byte(iso14443_4a_event->data->buffer, i)); + if(furi_string_size(nfc->text_box_store) < NFC_LOG_SIZE_MAX) { + furi_string_cat_printf(nfc->text_box_store, "R:"); + for(size_t i = 0; i < bit_buffer_get_size_bytes(iso14443_4a_event->data->buffer); + i++) { + furi_string_cat_printf( + nfc->text_box_store, + " %02X", + bit_buffer_get_byte(iso14443_4a_event->data->buffer, i)); + } + furi_string_push_back(nfc->text_box_store, '\n'); + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } - furi_string_push_back(nfc->text_box_store, '\n'); - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } return NfcCommandContinue; diff --git a/applications/main/nfc/helpers/protocol_support/iso15693_3/iso15693_3.c b/applications/main/nfc/helpers/protocol_support/iso15693_3/iso15693_3.c index 7823f03ea6b..cc39980a995 100644 --- a/applications/main/nfc/helpers/protocol_support/iso15693_3/iso15693_3.c +++ b/applications/main/nfc/helpers/protocol_support/iso15693_3/iso15693_3.c @@ -69,15 +69,17 @@ static NfcCommand Iso15693_3ListenerEvent* iso15693_3_event = event.event_data; if(iso15693_3_event->type == Iso15693_3ListenerEventTypeCustomCommand) { - furi_string_cat_printf(nfc->text_box_store, "R:"); - for(size_t i = 0; i < bit_buffer_get_size_bytes(iso15693_3_event->data->buffer); i++) { - furi_string_cat_printf( - nfc->text_box_store, - " %02X", - bit_buffer_get_byte(iso15693_3_event->data->buffer, i)); + if(furi_string_size(nfc->text_box_store) < NFC_LOG_SIZE_MAX) { + furi_string_cat_printf(nfc->text_box_store, "R:"); + for(size_t i = 0; i < bit_buffer_get_size_bytes(iso15693_3_event->data->buffer); i++) { + furi_string_cat_printf( + nfc->text_box_store, + " %02X", + bit_buffer_get_byte(iso15693_3_event->data->buffer, i)); + } + furi_string_push_back(nfc->text_box_store, '\n'); + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } - furi_string_push_back(nfc->text_box_store, '\n'); - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } return NfcCommandContinue; diff --git a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c index c52d597152e..0d4915fb7fa 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c +++ b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c @@ -99,7 +99,7 @@ static void nfc_scene_read_on_enter_mf_ultralight(NfcApp* instance) { nfc_poller_start(instance->poller, nfc_scene_read_poller_callback_mf_ultralight, instance); } -static void nfc_scene_read_menu_on_enter_mf_ultralight(NfcApp* instance) { +static void nfc_scene_read_and_saved_menu_on_enter_mf_ultralight(NfcApp* instance) { Submenu* submenu = instance->submenu; const MfUltralightData* data = @@ -140,21 +140,6 @@ static void nfc_scene_read_success_on_enter_mf_ultralight(NfcApp* instance) { furi_string_free(temp_str); } -static void nfc_scene_saved_menu_on_enter_mf_ultralight(NfcApp* instance) { - Submenu* submenu = instance->submenu; - const MfUltralightData* data = - nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight); - - if(!mf_ultralight_is_all_data_read(data)) { - submenu_add_item( - submenu, - "Unlock", - SubmenuIndexUnlock, - nfc_protocol_support_common_submenu_callback, - instance); - } -} - static void nfc_scene_emulate_on_enter_mf_ultralight(NfcApp* instance) { const MfUltralightData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight); @@ -171,7 +156,8 @@ static bool nfc_scene_info_on_event_mf_ultralight(NfcApp* instance, uint32_t eve return false; } -static bool nfc_unlock_item_pressed_process(NfcApp* instance, uint32_t event) { +static bool + nfc_scene_read_and_saved_menu_on_event_mf_ultralight(NfcApp* instance, uint32_t event) { if(event == SubmenuIndexUnlock) { scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightUnlockMenu); return true; @@ -179,14 +165,6 @@ static bool nfc_unlock_item_pressed_process(NfcApp* instance, uint32_t event) { return false; } -static bool nfc_scene_read_menu_on_event_mf_ultralight(NfcApp* instance, uint32_t event) { - return nfc_unlock_item_pressed_process(instance, event); -} - -static bool nfc_scene_saved_menu_on_event_mf_ultralight(NfcApp* instance, uint32_t event) { - return nfc_unlock_item_pressed_process(instance, event); -} - const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = { .features = NfcProtocolFeatureEmulateFull, @@ -207,8 +185,8 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = { }, .scene_read_menu = { - .on_enter = nfc_scene_read_menu_on_enter_mf_ultralight, - .on_event = nfc_scene_read_menu_on_event_mf_ultralight, + .on_enter = nfc_scene_read_and_saved_menu_on_enter_mf_ultralight, + .on_event = nfc_scene_read_and_saved_menu_on_event_mf_ultralight, }, .scene_read_success = { @@ -217,8 +195,8 @@ const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = { }, .scene_saved_menu = { - .on_enter = nfc_scene_saved_menu_on_enter_mf_ultralight, - .on_event = nfc_scene_saved_menu_on_event_mf_ultralight, + .on_enter = nfc_scene_read_and_saved_menu_on_enter_mf_ultralight, + .on_event = nfc_scene_read_and_saved_menu_on_event_mf_ultralight, }, .scene_save_name = { diff --git a/applications/main/nfc/helpers/protocol_support/slix/slix.c b/applications/main/nfc/helpers/protocol_support/slix/slix.c index d8f6c4e1f73..bf1ff073e72 100644 --- a/applications/main/nfc/helpers/protocol_support/slix/slix.c +++ b/applications/main/nfc/helpers/protocol_support/slix/slix.c @@ -67,13 +67,17 @@ static NfcCommand nfc_scene_emulate_listener_callback_slix(NfcGenericEvent event SlixListenerEvent* slix_event = event.event_data; if(slix_event->type == SlixListenerEventTypeCustomCommand) { - furi_string_cat_printf(nfc->text_box_store, "R:"); - for(size_t i = 0; i < bit_buffer_get_size_bytes(slix_event->data->buffer); i++) { - furi_string_cat_printf( - nfc->text_box_store, " %02X", bit_buffer_get_byte(slix_event->data->buffer, i)); + if(furi_string_size(nfc->text_box_store) < NFC_LOG_SIZE_MAX) { + furi_string_cat_printf(nfc->text_box_store, "R:"); + for(size_t i = 0; i < bit_buffer_get_size_bytes(slix_event->data->buffer); i++) { + furi_string_cat_printf( + nfc->text_box_store, + " %02X", + bit_buffer_get_byte(slix_event->data->buffer, i)); + } + furi_string_push_back(nfc->text_box_store, '\n'); + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } - furi_string_push_back(nfc->text_box_store, '\n'); - view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventListenerUpdate); } return NfcCommandContinue; diff --git a/applications/main/nfc/nfc_app_i.h b/applications/main/nfc/nfc_app_i.h index 9a3ac77cae9..3c0092007af 100644 --- a/applications/main/nfc/nfc_app_i.h +++ b/applications/main/nfc/nfc_app_i.h @@ -61,6 +61,7 @@ #define NFC_NAME_SIZE 22 #define NFC_TEXT_STORE_SIZE 128 #define NFC_BYTE_INPUT_STORE_SIZE 10 +#define NFC_LOG_SIZE_MAX (1024) #define NFC_APP_FOLDER ANY_PATH("nfc") #define NFC_APP_EXTENSION ".nfc" #define NFC_APP_SHADOW_EXTENSION ".shd" @@ -87,6 +88,7 @@ typedef struct { size_t dict_keys_current; bool is_key_attack; uint8_t key_attack_current_sector; + bool is_card_present; } NfcMfClassicDictAttackContext; struct NfcApp { diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_detect_reader.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_detect_reader.c index d7263ac046f..aa45f19e01a 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_detect_reader.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_detect_reader.c @@ -97,8 +97,11 @@ bool nfc_scene_mf_classic_detect_reader_on_event(void* context, SceneManagerEven detect_reader_set_state(instance->detect_reader, DetectReaderStateReaderDetected); detect_reader_set_nonces_collected(instance->detect_reader, nonces_pairs); if(nonces_pairs >= NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { - nfc_listener_stop(instance->listener); - nfc_listener_free(instance->listener); + if(instance->listener) { + nfc_listener_stop(instance->listener); + nfc_listener_free(instance->listener); + instance->listener = NULL; + } detect_reader_set_state(instance->detect_reader, DetectReaderStateDone); nfc_blink_stop(instance); notification_message(instance->notifications, &sequence_single_vibro); @@ -112,14 +115,19 @@ bool nfc_scene_mf_classic_detect_reader_on_event(void* context, SceneManagerEven nfc_blink_stop(instance); notification_message(instance->notifications, &sequence_detect_reader); } else if(event.event == NfcCustomEventViewExit) { + if(instance->listener) { + nfc_listener_stop(instance->listener); + nfc_listener_free(instance->listener); + instance->listener = NULL; + } scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicMfkeyNoncesInfo); consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { - size_t nonces_pairs = 2 * mfkey32_logger_get_params_num(instance->mfkey32_logger); - if(nonces_pairs < NFC_SCENE_DETECT_READER_PAIR_NONCES_MAX) { + if(instance->listener) { nfc_listener_stop(instance->listener); nfc_listener_free(instance->listener); + instance->listener = NULL; } mfkey32_logger_free(instance->mfkey32_logger); } diff --git a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c index c211a348529..ff7af9e1e8b 100644 --- a/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c +++ b/applications/main/nfc/scenes/nfc_scene_mf_classic_dict_attack.c @@ -21,8 +21,10 @@ NfcCommand nfc_dict_attack_worker_callback(NfcGenericEvent event, void* context) NfcApp* instance = context; if(mfc_event->type == MfClassicPollerEventTypeCardDetected) { + instance->nfc_dict_context.is_card_present = true; view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected); } else if(mfc_event->type == MfClassicPollerEventTypeCardLost) { + instance->nfc_dict_context.is_card_present = false; view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardLost); } else if(mfc_event->type == MfClassicPollerEventTypeRequestMode) { const MfClassicData* mfc_data = @@ -210,16 +212,22 @@ bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent const MfClassicData* mfc_data = nfc_poller_get_data(instance->poller); nfc_device_set_data(instance->nfc_device, NfcProtocolMfClassic, mfc_data); if(state == DictAttackStateUserDictInProgress) { - nfc_poller_stop(instance->poller); - nfc_poller_free(instance->poller); - nfc_dict_free(instance->nfc_dict_context.dict); - scene_manager_set_scene_state( - instance->scene_manager, - NfcSceneMfClassicDictAttack, - DictAttackStateSystemDictInProgress); - nfc_scene_mf_classic_dict_attack_prepare_view(instance); - instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic); - nfc_poller_start(instance->poller, nfc_dict_attack_worker_callback, instance); + if(instance->nfc_dict_context.is_card_present) { + nfc_poller_stop(instance->poller); + nfc_poller_free(instance->poller); + nfc_dict_free(instance->nfc_dict_context.dict); + scene_manager_set_scene_state( + instance->scene_manager, + NfcSceneMfClassicDictAttack, + DictAttackStateSystemDictInProgress); + nfc_scene_mf_classic_dict_attack_prepare_view(instance); + instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic); + nfc_poller_start(instance->poller, nfc_dict_attack_worker_callback, instance); + } else { + notification_message(instance->notifications, &sequence_success); + scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess); + dolphin_deed(DolphinDeedNfcReadSuccess); + } consumed = true; } else if(state == DictAttackStateSystemDictInProgress) { notification_message(instance->notifications, &sequence_success); @@ -255,6 +263,7 @@ void nfc_scene_mf_classic_dict_attack_on_exit(void* context) { instance->nfc_dict_context.dict_keys_current = 0; instance->nfc_dict_context.is_key_attack = false; instance->nfc_dict_context.key_attack_current_sector = 0; + instance->nfc_dict_context.is_card_present = false; nfc_blink_stop(instance); notification_message(instance->notifications, &sequence_display_backlight_enforce_auto); diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 109111ca825..6b1fbff5450 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -154,6 +154,7 @@ Header,+,lib/music_worker/music_worker.h,, Header,+,lib/nanopb/pb.h,, Header,+,lib/nanopb/pb_decode.h,, Header,+,lib/nanopb/pb_encode.h,, +Header,+,lib/nfc/helpers/iso13239_crc.h,, Header,+,lib/nfc/helpers/iso14443_crc.h,, Header,+,lib/nfc/helpers/nfc_data_generator.h,, Header,+,lib/nfc/helpers/nfc_dict.h,, @@ -1283,6 +1284,7 @@ Function,+,furi_hal_mpu_protect_read_only,void,"FuriHalMpuRegion, uint32_t, Furi Function,+,furi_hal_nfc_abort,FuriHalNfcError, Function,+,furi_hal_nfc_acquire,FuriHalNfcError, Function,+,furi_hal_nfc_event_start,FuriHalNfcError, +Function,+,furi_hal_nfc_event_stop,FuriHalNfcError, Function,+,furi_hal_nfc_field_detect_start,FuriHalNfcError, Function,+,furi_hal_nfc_field_detect_stop,FuriHalNfcError, Function,+,furi_hal_nfc_field_is_present,_Bool, @@ -1841,6 +1843,9 @@ Function,-,islower,int,int Function,-,islower_l,int,"int, locale_t" Function,-,isnan,int,double Function,-,isnanf,int,float +Function,+,iso13239_crc_append,void,"Iso13239CrcType, BitBuffer*" +Function,+,iso13239_crc_check,_Bool,"Iso13239CrcType, const BitBuffer*" +Function,+,iso13239_crc_trim,void,BitBuffer* Function,+,iso14443_3a_alloc,Iso14443_3aData*, Function,+,iso14443_3a_copy,void,"Iso14443_3aData*, const Iso14443_3aData*" Function,+,iso14443_3a_free,void,Iso14443_3aData* diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index 93ae9632185..3d7fd38549e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -18,6 +18,7 @@ FuriHalNfc furi_hal_nfc; static FuriHalNfcError furi_hal_nfc_turn_on_osc(FuriHalSpiBusHandle* handle) { FuriHalNfcError error = FuriHalNfcErrorNone; + furi_hal_nfc_event_start(); if(!st25r3916_check_reg( handle, @@ -282,6 +283,7 @@ FuriHalNfcError furi_hal_nfc_low_power_mode_start() { ST25R3916_REG_OP_CONTROL_en_fd_mask)); furi_hal_nfc_deinit_gpio_isr(); furi_hal_nfc_timers_deinit(); + furi_hal_nfc_event_stop(); return error; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc_event.c b/firmware/targets/f7/furi_hal/furi_hal_nfc_event.c index 61530aa34b7..cce16c5dc9b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc_event.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc_event.c @@ -15,6 +15,14 @@ FuriHalNfcError furi_hal_nfc_event_start() { return FuriHalNfcErrorNone; } +FuriHalNfcError furi_hal_nfc_event_stop() { + furi_assert(furi_hal_nfc_event); + + furi_hal_nfc_event->thread = NULL; + + return FuriHalNfcErrorNone; +} + void furi_hal_nfc_event_set(FuriHalNfcEventInternalType event) { furi_assert(furi_hal_nfc_event); furi_assert(furi_hal_nfc_event->thread); diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc_iso15693.c b/firmware/targets/f7/furi_hal/furi_hal_nfc_iso15693.c index f5a325c4420..944dbe98dc4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc_iso15693.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc_iso15693.c @@ -19,6 +19,7 @@ #define FURI_HAL_NFC_ISO15693_RESP_PATTERN_1 (0x02U) // Derived experimentally +#define FURI_HAL_NFC_ISO15693_POLLER_FWT_COMP_FC (-1300) #define FURI_HAL_NFC_ISO15693_LISTENER_FDT_COMP_FC (2735) #define BITS_IN_BYTE (8U) @@ -429,7 +430,7 @@ const FuriHalNfcTechBase furi_hal_nfc_iso15693 = { .compensation = { .fdt = FURI_HAL_NFC_POLLER_FDT_COMP_FC, - .fwt = FURI_HAL_NFC_POLLER_FWT_COMP_FC, + .fwt = FURI_HAL_NFC_ISO15693_POLLER_FWT_COMP_FC, }, .init = furi_hal_nfc_iso15693_poller_init, .deinit = furi_hal_nfc_iso15693_poller_deinit, diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc_timer.c b/firmware/targets/f7/furi_hal/furi_hal_nfc_timer.c index ca9953e0411..32c08457424 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc_timer.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc_timer.c @@ -85,9 +85,9 @@ static void furi_hal_nfc_timer_init(FuriHalNfcTimer timer) { LL_TIM_SetClockSource(furi_hal_nfc_timers[timer].timer, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_GenerateEvent_UPDATE(furi_hal_nfc_timers[timer].timer); + LL_TIM_ClearFlag_UPDATE(furi_hal_nfc_timers[timer].timer); LL_TIM_EnableIT_UPDATE(furi_hal_nfc_timers[timer].timer); - furi_hal_interrupt_set_isr( furi_hal_nfc_timers[timer].irq_id, furi_hal_nfc_timer_irq_callback, diff --git a/firmware/targets/furi_hal_include/furi_hal_nfc.h b/firmware/targets/furi_hal_include/furi_hal_nfc.h index f63e258b947..3d34bb8b3fc 100644 --- a/firmware/targets/furi_hal_include/furi_hal_nfc.h +++ b/firmware/targets/furi_hal_include/furi_hal_nfc.h @@ -221,6 +221,12 @@ FuriHalNfcError furi_hal_nfc_trx_reset(); */ FuriHalNfcError furi_hal_nfc_event_start(); +/** Stop Nfc HAL events + * + * @return FuriHalNfcError + */ +FuriHalNfcError furi_hal_nfc_event_stop(); + /** Emit Abort event * * @return FuriHalNfcError diff --git a/lib/digital_signal/presets/nfc/iso15693_signal.c b/lib/digital_signal/presets/nfc/iso15693_signal.c index 72754d55de0..1292bd44893 100644 --- a/lib/digital_signal/presets/nfc/iso15693_signal.c +++ b/lib/digital_signal/presets/nfc/iso15693_signal.c @@ -182,7 +182,6 @@ void iso15693_signal_tx( furi_assert(instance); furi_assert(data_rate < Iso15693SignalDataRateNum); furi_assert(tx_data); - furi_assert(tx_data_size / BITS_IN_BYTE); FURI_CRITICAL_ENTER(); digital_sequence_clear(instance->tx_sequence); diff --git a/lib/drivers/st25r3916.c b/lib/drivers/st25r3916.c index 960b9cf4b5b..47726121358 100644 --- a/lib/drivers/st25r3916.c +++ b/lib/drivers/st25r3916.c @@ -54,25 +54,28 @@ bool st25r3916_read_fifo( bool read_success = false; - uint8_t fifo_status[2] = {}; - st25r3916_read_burst_regs(handle, ST25R3916_REG_FIFO_STATUS1, fifo_status, 2); - size_t bytes = ((fifo_status[1] & ST25R3916_REG_FIFO_STATUS2_fifo_b_mask) >> - ST25R3916_REG_FIFO_STATUS2_fifo_b_shift) | - fifo_status[0]; - uint8_t bits = - ((fifo_status[1] & ST25R3916_REG_FIFO_STATUS2_fifo_lb_mask) >> - ST25R3916_REG_FIFO_STATUS2_fifo_lb_shift); - - if(bytes <= buff_size) { + do { + uint8_t fifo_status[2] = {}; + st25r3916_read_burst_regs(handle, ST25R3916_REG_FIFO_STATUS1, fifo_status, 2); + size_t bytes = ((fifo_status[1] & ST25R3916_REG_FIFO_STATUS2_fifo_b_mask) >> + ST25R3916_REG_FIFO_STATUS2_fifo_b_shift) | + fifo_status[0]; + uint8_t bits = + ((fifo_status[1] & ST25R3916_REG_FIFO_STATUS2_fifo_lb_mask) >> + ST25R3916_REG_FIFO_STATUS2_fifo_lb_shift); + + if(bytes == 0) break; + if(bytes > buff_size) break; + st25r3916_reg_read_fifo(handle, buff, bytes); - read_success = true; - } - if(bits) { - *buff_bits = (bytes - 1) * 8 + bits; - } else { - *buff_bits = bytes * 8; - } + if(bits) { + *buff_bits = (bytes - 1) * 8 + bits; + } else { + *buff_bits = bytes * 8; + } + read_success = true; + } while(false); return read_success; } diff --git a/lib/nfc/SConscript b/lib/nfc/SConscript index e2fee65cb0f..3e3a73b5a71 100644 --- a/lib/nfc/SConscript +++ b/lib/nfc/SConscript @@ -40,6 +40,7 @@ env.Append( # Misc File("helpers/nfc_util.h"), File("helpers/iso14443_crc.h"), + File("helpers/iso13239_crc.h"), File("helpers/nfc_data_generator.h"), File("helpers/nfc_dict.h"), ], diff --git a/lib/nfc/nfc.c b/lib/nfc/nfc.c index 032febaff18..dd8c15796ba 100644 --- a/lib/nfc/nfc.c +++ b/lib/nfc/nfc.c @@ -319,8 +319,8 @@ void nfc_start(Nfc* instance, NfcEventCallback callback, void* context) { } else { furi_thread_set_callback(instance->worker_thread, nfc_worker_listener); } - furi_thread_start(instance->worker_thread); instance->comm_state = NfcCommStateIdle; + furi_thread_start(instance->worker_thread); } void nfc_stop(Nfc* instance) { @@ -448,6 +448,12 @@ NfcError nfc_iso14443a_poller_trx_custom_parity( ret = nfc_process_hal_error(error); break; } + if(instance->rx_bits >= 9) { + if((instance->rx_bits % 9) != 0) { + ret = NfcErrorDataFormat; + break; + } + } bit_buffer_copy_bytes_with_parity(rx_buffer, instance->rx_buffer, instance->rx_bits); } while(false); diff --git a/lib/nfc/protocols/felica/felica.h b/lib/nfc/protocols/felica/felica.h index 671a7220de2..da9d2294ee8 100644 --- a/lib/nfc/protocols/felica/felica.h +++ b/lib/nfc/protocols/felica/felica.h @@ -29,6 +29,7 @@ typedef enum { FelicaErrorCommunication, FelicaErrorFieldOff, FelicaErrorWrongCrc, + FelicaErrorProtocol, FelicaErrorTimeout, } FelicaError; diff --git a/lib/nfc/protocols/felica/felica_poller_i.c b/lib/nfc/protocols/felica/felica_poller_i.c index 7e9bb42bae2..d8015fdfade 100644 --- a/lib/nfc/protocols/felica/felica_poller_i.c +++ b/lib/nfc/protocols/felica/felica_poller_i.c @@ -57,25 +57,38 @@ FelicaError felica_poller_async_polling( furi_assert(cmd); furi_assert(resp); - bit_buffer_set_size_bytes(instance->tx_buffer, 2); - // Set frame len - // TODO Set length in felica_poller_frame_exchange() ? - bit_buffer_set_byte(instance->tx_buffer, 0, sizeof(FelicaPollerPollingCommand) + 2); - // Set command code - bit_buffer_set_byte(instance->tx_buffer, 1, FELICA_POLLER_CMD_POLLING_CODE); - // Set other data - bit_buffer_append_bytes( - instance->tx_buffer, (uint8_t*)cmd, sizeof(FelicaPollerPollingCommand)); - - FelicaError error = felica_poller_frame_exchange( - instance, instance->tx_buffer, instance->rx_buffer, FELICA_POLLER_POLLING_FWT); - - if(error == FelicaErrorNone) { - // TODO extract length in felica_poller_frame_exchange() ? + FelicaError error = FelicaErrorNone; + + do { + bit_buffer_set_size_bytes(instance->tx_buffer, 2); + // Set frame len + bit_buffer_set_byte( + instance->tx_buffer, 0, sizeof(FelicaPollerPollingCommand) + FELICA_CRC_SIZE); + // Set command code + bit_buffer_set_byte(instance->tx_buffer, 1, FELICA_POLLER_CMD_POLLING_REQ_CODE); + // Set other data + bit_buffer_append_bytes( + instance->tx_buffer, (uint8_t*)cmd, sizeof(FelicaPollerPollingCommand)); + + error = felica_poller_frame_exchange( + instance, instance->tx_buffer, instance->rx_buffer, FELICA_POLLER_POLLING_FWT); + + if(error != FelicaErrorNone) break; + if(bit_buffer_get_byte(instance->rx_buffer, 1) != FELICA_POLLER_CMD_POLLING_RESP_CODE) { + error = FelicaErrorProtocol; + break; + } + if(bit_buffer_get_size_bytes(instance->rx_buffer) < + sizeof(FelicaIDm) + sizeof(FelicaPMm) + 1) { + error = FelicaErrorProtocol; + break; + } + bit_buffer_write_bytes_mid(instance->rx_buffer, resp->idm.data, 2, sizeof(FelicaIDm)); bit_buffer_write_bytes_mid( instance->rx_buffer, resp->pmm.data, sizeof(FelicaIDm) + 2, sizeof(FelicaPMm)); - } + + } while(false); return error; } diff --git a/lib/nfc/protocols/felica/felica_poller_i.h b/lib/nfc/protocols/felica/felica_poller_i.h index d458c9bb462..e12f0147269 100644 --- a/lib/nfc/protocols/felica/felica_poller_i.h +++ b/lib/nfc/protocols/felica/felica_poller_i.h @@ -12,7 +12,8 @@ extern "C" { #define FELICA_POLLER_POLLING_FWT (200000U) -#define FELICA_POLLER_CMD_POLLING_CODE (0x00U) +#define FELICA_POLLER_CMD_POLLING_REQ_CODE (0x00U) +#define FELICA_POLLER_CMD_POLLING_RESP_CODE (0x01U) typedef enum { FelicaPollerStateIdle, diff --git a/lib/nfc/protocols/mf_classic/mf_classic_poller.c b/lib/nfc/protocols/mf_classic/mf_classic_poller.c index 2369b8767b5..3eba6ee5694 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_poller.c +++ b/lib/nfc/protocols/mf_classic/mf_classic_poller.c @@ -810,7 +810,7 @@ NfcCommand mf_classic_poller_handler_key_reuse_read_sector(MfClassicPoller* inst } } while(false); - uint8_t sec_tr_block_num = + uint16_t sec_tr_block_num = mf_classic_get_sector_trailer_num_by_sector(dict_attack_ctx->reuse_key_sector); dict_attack_ctx->current_block++; if(dict_attack_ctx->current_block > sec_tr_block_num) { diff --git a/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h b/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h index f9b74455394..c6f4ccf7f0e 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h +++ b/lib/nfc/protocols/mf_classic/mf_classic_poller_i.h @@ -55,7 +55,7 @@ typedef enum { typedef struct { uint8_t current_sector; MfClassicSectorTrailer sec_tr; - uint8_t current_block; + uint16_t current_block; bool is_value_block; MfClassicKeyType key_type_read; MfClassicKeyType key_type_write; @@ -68,7 +68,7 @@ typedef struct { MfClassicKey current_key; MfClassicKeyType current_key_type; bool auth_passed; - uint8_t current_block; + uint16_t current_block; uint8_t reuse_key_sector; } MfClassicPollerDictAttackContext; diff --git a/lib/nfc/protocols/slix/slix_poller.c b/lib/nfc/protocols/slix/slix_poller.c index 7cc50185bfe..9731bfc6b83 100644 --- a/lib/nfc/protocols/slix/slix_poller.c +++ b/lib/nfc/protocols/slix/slix_poller.c @@ -74,6 +74,7 @@ static NfcCommand slix_poller_handler_read_signature(SlixPoller* instance) { static NfcCommand slix_poller_handler_error(SlixPoller* instance) { instance->slix_event_data.error = instance->error; + instance->slix_event.type = SlixPollerEventTypeError; NfcCommand command = instance->callback(instance->general_event, instance->context); instance->poller_state = SlixPollerStateIdle; return command; @@ -127,7 +128,7 @@ static NfcCommand slix_poller_run(NfcGenericEvent event, void* context) { static bool slix_poller_detect(NfcGenericEvent event, void* context) { furi_assert(event.protocol == NfcProtocolIso15693_3); - const SlixPoller* instance = context; + SlixPoller* instance = context; furi_assert(instance); const Iso15693_3PollerEvent* iso15693_3_event = event.event_data; @@ -138,7 +139,11 @@ static bool slix_poller_detect(NfcGenericEvent event, void* context) { bool protocol_detected = false; if(iso15693_3_event->type == Iso15693_3PollerEventTypeReady) { - protocol_detected = slix_get_type(instance->data) < SlixTypeCount; + if(slix_get_type(instance->data) < SlixTypeCount) { + SlixSystemInfo system_info = {}; + SlixError error = slix_poller_async_get_nxp_system_info(instance, &system_info); + protocol_detected = (error == SlixErrorNone); + } } return protocol_detected;