Force card types in extra actions (#1961)

* Mifare Classic forced read
* Add all the needed card types
* nfc: remove unused scene
* nfc: remove unused worker state
* nfc: fix read card type scene state usage
* nfc: move NfcReadMode to NfcDevData struct
* nfc: fix bank card reading and scene navigation
* nfc magic: fix magic deactifate function

Co-authored-by: gornekich <n.gorbadey@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Astra 2022-11-10 18:29:57 +02:00 committed by GitHub
parent 820afd2aec
commit e7c4b40dbe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 213 additions and 5 deletions

View file

@ -60,3 +60,4 @@ ADD_SCENE(nfc, detect_reader, DetectReader)
ADD_SCENE(nfc, mfkey_nonces_info, MfkeyNoncesInfo)
ADD_SCENE(nfc, mfkey_complete, MfkeyComplete)
ADD_SCENE(nfc, nfc_data_info, NfcDataInfo)
ADD_SCENE(nfc, read_card_type, ReadCardType)

View file

@ -29,8 +29,13 @@ bool nfc_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) {
if(event.event == DialogExResultRight) {
consumed = scene_manager_previous_scene(nfc->scene_manager);
} else if(event.event == DialogExResultLeft) {
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneStart);
if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneReadCardType)) {
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneReadCardType);
} else {
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneStart);
}
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = true;

View file

@ -1,6 +1,7 @@
#include "../nfc_i.h"
enum SubmenuIndex {
SubmenuIndexReadCardType,
SubmenuIndexMfClassicKeys,
SubmenuIndexMfUltralightUnlock,
};
@ -15,6 +16,12 @@ void nfc_scene_extra_actions_on_enter(void* context) {
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(
submenu,
"Read Specific Card Type",
SubmenuIndexReadCardType,
nfc_scene_extra_actions_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Mifare Classic Keys",
@ -44,9 +51,15 @@ bool nfc_scene_extra_actions_on_event(void* context, SceneManagerEvent event) {
consumed = true;
} else if(event.event == SubmenuIndexMfUltralightUnlock) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockMenu);
consumed = true;
} else if(event.event == SubmenuIndexReadCardType) {
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneReadCardType, 0);
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardType);
consumed = true;
}
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneExtraActions, event.event);
}
return consumed;
}

View file

@ -0,0 +1,97 @@
#include "../nfc_i.h"
#include "nfc_worker_i.h"
enum SubmenuIndex {
SubmenuIndexReadMifareClassic,
SubmenuIndexReadMifareDesfire,
SubmenuIndexReadMfUltralight,
SubmenuIndexReadEMV,
SubmenuIndexReadNFCA,
};
void nfc_scene_read_card_type_submenu_callback(void* context, uint32_t index) {
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
}
void nfc_scene_read_card_type_on_enter(void* context) {
Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
submenu_add_item(
submenu,
"Read Mifare Classic",
SubmenuIndexReadMifareClassic,
nfc_scene_read_card_type_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Read Mifare DESFire",
SubmenuIndexReadMifareDesfire,
nfc_scene_read_card_type_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Read NTAG/Ultralight",
SubmenuIndexReadMfUltralight,
nfc_scene_read_card_type_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Read EMV card",
SubmenuIndexReadEMV,
nfc_scene_read_card_type_submenu_callback,
nfc);
submenu_add_item(
submenu,
"Read NFC-A data",
SubmenuIndexReadNFCA,
nfc_scene_read_card_type_submenu_callback,
nfc);
uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadCardType);
submenu_set_selected_item(submenu, state);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
bool nfc_scene_read_card_type_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexReadMifareClassic) {
nfc->dev->dev_data.read_mode = NfcReadModeMfClassic;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
consumed = true;
}
if(event.event == SubmenuIndexReadMifareDesfire) {
nfc->dev->dev_data.read_mode = NfcReadModeMfDesfire;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
consumed = true;
}
if(event.event == SubmenuIndexReadMfUltralight) {
nfc->dev->dev_data.read_mode = NfcReadModeMfUltralight;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
consumed = true;
}
if(event.event == SubmenuIndexReadEMV) {
nfc->dev->dev_data.read_mode = NfcReadModeEMV;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
consumed = true;
}
if(event.event == SubmenuIndexReadNFCA) {
nfc->dev->dev_data.read_mode = NfcReadModeNFCA;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
consumed = true;
}
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneReadCardType, event.event);
}
return consumed;
}
void nfc_scene_read_card_type_on_exit(void* context) {
Nfc* nfc = context;
submenu_reset(nfc->submenu);
}

View file

@ -1,4 +1,5 @@
#include "../nfc_i.h"
#include "nfc_worker_i.h"
#include <dolphin/dolphin.h>
enum SubmenuIndex {
@ -47,6 +48,7 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexRead) {
nfc->dev->dev_data.read_mode = NfcReadModeAuto;
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
DOLPHIN_DEED(DolphinDeedNfcRead);
consumed = true;

View file

@ -210,5 +210,5 @@ bool magic_wipe() {
void magic_deactivate() {
furi_hal_nfc_ll_txrx_off();
furi_hal_nfc_start_sleep();
furi_hal_nfc_sleep();
}

View file

@ -167,7 +167,6 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) {
if(!magic_data_access_cmd()) continue;
if(!magic_write_blk(0, &block)) continue;
nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context);
magic_deactivate();
break;
}
magic_deactivate();

View file

@ -51,9 +51,19 @@ typedef struct {
MfClassicDict* dict;
} NfcMfClassicDictAttackData;
typedef enum {
NfcReadModeAuto,
NfcReadModeMfClassic,
NfcReadModeMfUltralight,
NfcReadModeMfDesfire,
NfcReadModeEMV,
NfcReadModeNFCA,
} NfcReadMode;
typedef struct {
FuriHalNfcDevData nfc_data;
NfcProtocol protocol;
NfcReadMode read_mode;
union {
NfcReaderRequestData reader_data;
NfcMfClassicDictAttackData mf_classic_dict_attack_data;

View file

@ -90,7 +90,11 @@ int32_t nfc_worker_task(void* context) {
furi_hal_nfc_exit_sleep();
if(nfc_worker->state == NfcWorkerStateRead) {
nfc_worker_read(nfc_worker);
if(nfc_worker->dev_data->read_mode == NfcReadModeAuto) {
nfc_worker_read(nfc_worker);
} else {
nfc_worker_read_type(nfc_worker);
}
} else if(nfc_worker->state == NfcWorkerStateUidEmulate) {
nfc_worker_emulate_uid(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateEmulateApdu) {
@ -394,6 +398,81 @@ void nfc_worker_read(NfcWorker* nfc_worker) {
}
}
void nfc_worker_read_type(NfcWorker* nfc_worker) {
furi_assert(nfc_worker);
furi_assert(nfc_worker->callback);
NfcReadMode read_mode = nfc_worker->dev_data->read_mode;
nfc_device_data_clear(nfc_worker->dev_data);
NfcDeviceData* dev_data = nfc_worker->dev_data;
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
FuriHalNfcTxRxContext tx_rx = {};
NfcWorkerEvent event = 0;
bool card_not_detected_notified = false;
while(nfc_worker->state == NfcWorkerStateRead) {
if(furi_hal_nfc_detect(nfc_data, 300)) {
FURI_LOG_D(TAG, "Card detected");
furi_hal_nfc_sleep();
// Process first found device
nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
card_not_detected_notified = false;
if(nfc_data->type == FuriHalNfcTypeA) {
if(read_mode == NfcReadModeMfClassic) {
nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic;
nfc_worker->dev_data->mf_classic_data.type = mf_classic_get_classic_type(
nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak);
if(nfc_worker_read_mf_classic(nfc_worker, &tx_rx)) {
FURI_LOG_D(TAG, "Card read");
dev_data->protocol = NfcDeviceProtocolMifareClassic;
event = NfcWorkerEventReadMfClassicDone;
break;
} else {
FURI_LOG_D(TAG, "Card read failed");
dev_data->protocol = NfcDeviceProtocolMifareClassic;
event = NfcWorkerEventReadMfClassicDictAttackRequired;
break;
}
} else if(read_mode == NfcReadModeMfUltralight) {
FURI_LOG_I(TAG, "Mifare Ultralight / NTAG");
nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl;
if(nfc_worker_read_mf_ultralight(nfc_worker, &tx_rx)) {
event = NfcWorkerEventReadMfUltralight;
break;
}
} else if(read_mode == NfcReadModeMfDesfire) {
nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareDesfire;
if(nfc_worker_read_mf_desfire(nfc_worker, &tx_rx)) {
event = NfcWorkerEventReadMfDesfire;
break;
}
} else if(read_mode == NfcReadModeEMV) {
nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV;
if(nfc_worker_read_bank_card(nfc_worker, &tx_rx)) {
event = NfcWorkerEventReadBankCard;
break;
}
} else if(read_mode == NfcReadModeNFCA) {
nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown;
event = NfcWorkerEventReadUidNfcA;
break;
}
} else {
if(!card_not_detected_notified) {
nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
card_not_detected_notified = true;
}
}
}
furi_hal_nfc_sleep();
furi_delay_ms(100);
}
// Notify caller and exit
if(event > NfcWorkerEventReserved) {
nfc_worker->callback(event, nfc_worker->context);
}
}
void nfc_worker_emulate_uid(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {};
FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data;

View file

@ -35,6 +35,8 @@ int32_t nfc_worker_task(void* context);
void nfc_worker_read(NfcWorker* nfc_worker);
void nfc_worker_read_type(NfcWorker* nfc_worker);
void nfc_worker_emulate_uid(NfcWorker* nfc_worker);
void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker);