mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-16 04:24:45 -07:00
Initial structure for UL-C dictionary attacks
This commit is contained in:
@@ -166,15 +166,26 @@ static void nfc_scene_read_on_enter_mf_ultralight(NfcApp* instance) {
|
||||
|
||||
bool nfc_scene_read_on_event_mf_ultralight(NfcApp* instance, SceneManagerEvent event) {
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventCardDetected) {
|
||||
nfc_unlock_helper_card_detected_handler(instance);
|
||||
} else if(event.event == NfcCustomEventPollerIncomplete) {
|
||||
notification_message(instance->notifications, &sequence_semi_success);
|
||||
if(event.event == NfcCustomEventPollerSuccess) {
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
|
||||
dolphin_deed(DolphinDeedNfcReadSuccess);
|
||||
return true;
|
||||
} else if(event.event == NfcCustomEventPollerIncomplete) {
|
||||
const MfUltralightData* data =
|
||||
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
|
||||
if(data->type == MfUltralightTypeMfulC) {
|
||||
// Start dict attack for MFUL C cards
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightCDictAttack);
|
||||
} else {
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
|
||||
dolphin_deed(DolphinDeedNfcReadSuccess);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void nfc_scene_read_and_saved_menu_on_enter_mf_ultralight(NfcApp* instance) {
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <lib/nfc/nfc.h>
|
||||
#include <lib/nfc/protocols/iso14443_3a/iso14443_3a.h>
|
||||
#include <lib/nfc/protocols/iso14443_3a/iso14443_3a_listener.h>
|
||||
#include <lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.h>
|
||||
#include <lib/nfc/protocols/mf_ultralight/mf_ultralight_listener.h>
|
||||
|
||||
#include <nfc/nfc_poller.h>
|
||||
@@ -80,6 +81,10 @@
|
||||
#define NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH (NFC_APP_FOLDER "/assets/mf_classic_dict.nfc")
|
||||
#define NFC_APP_MF_CLASSIC_DICT_SYSTEM_NESTED_PATH \
|
||||
(NFC_APP_FOLDER "/assets/mf_classic_dict_nested.nfc")
|
||||
#define NFC_APP_MF_ULTRALIGHT_C_DICT_USER_PATH \
|
||||
(NFC_APP_FOLDER "/assets/mf_ultralight_c_dict_user.nfc")
|
||||
#define NFC_APP_MF_ULTRALIGHT_C_DICT_SYSTEM_PATH \
|
||||
(NFC_APP_FOLDER "/assets/mf_ultralight_c_dict.nfc")
|
||||
|
||||
typedef enum {
|
||||
NfcRpcStateIdle,
|
||||
@@ -105,6 +110,14 @@ typedef struct {
|
||||
bool enhanced_dict;
|
||||
} NfcMfClassicDictAttackContext;
|
||||
|
||||
typedef struct {
|
||||
KeysDict* dict;
|
||||
bool auth_success;
|
||||
bool is_card_present;
|
||||
size_t dict_keys_total;
|
||||
size_t dict_keys_current;
|
||||
} NfcMfUltralightCDictContext;
|
||||
|
||||
struct NfcApp {
|
||||
DialogsApp* dialogs;
|
||||
Storage* storage;
|
||||
@@ -143,6 +156,7 @@ struct NfcApp {
|
||||
MfUltralightAuth* mf_ul_auth;
|
||||
SlixUnlock* slix_unlock;
|
||||
NfcMfClassicDictAttackContext nfc_dict_context;
|
||||
NfcMfUltralightCDictContext mf_ultralight_c_dict_context;
|
||||
Mfkey32Logger* mfkey32_logger;
|
||||
MfUserDict* mf_user_dict;
|
||||
MfClassicKeyCache* mfc_key_cache;
|
||||
|
||||
@@ -25,6 +25,7 @@ ADD_SCENE(nfc, retry_confirm, RetryConfirm)
|
||||
ADD_SCENE(nfc, exit_confirm, ExitConfirm)
|
||||
ADD_SCENE(nfc, save_confirm, SaveConfirm)
|
||||
|
||||
ADD_SCENE(nfc, mf_ultralight_c_dict_attack, MfUltralightCDictAttack)
|
||||
ADD_SCENE(nfc, mf_ultralight_write, MfUltralightWrite)
|
||||
ADD_SCENE(nfc, mf_ultralight_write_success, MfUltralightWriteSuccess)
|
||||
ADD_SCENE(nfc, mf_ultralight_write_fail, MfUltralightWriteFail)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexReadCardType,
|
||||
SubmenuIndexMfClassicKeys,
|
||||
SubmenuIndexMfUlCKeys,
|
||||
SubmenuIndexMfUltralightUnlock,
|
||||
SubmenuIndexSlixUnlock,
|
||||
};
|
||||
@@ -29,6 +30,12 @@ void nfc_scene_extra_actions_on_enter(void* context) {
|
||||
SubmenuIndexMfClassicKeys,
|
||||
nfc_scene_extra_actions_submenu_callback,
|
||||
instance);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"MIFARE Ultralight C Keys",
|
||||
SubmenuIndexMfUlCKeys,
|
||||
nfc_scene_extra_actions_submenu_callback,
|
||||
instance);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Unlock NTAG/Ultralight",
|
||||
@@ -54,6 +61,9 @@ bool nfc_scene_extra_actions_on_event(void* context, SceneManagerEvent event) {
|
||||
if(event.event == SubmenuIndexMfClassicKeys) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicKeys);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexMfUlCKeys) {
|
||||
// TODO: Add MFUL C key management scene here
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexMfUltralightUnlock) {
|
||||
mf_ultralight_auth_reset(instance->mf_ul_auth);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightUnlockMenu);
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
#include "../nfc_app_i.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
#define TAG "NfcMfUlCDictAttack"
|
||||
|
||||
enum {
|
||||
DictAttackStateUserDictInProgress,
|
||||
DictAttackStateSystemDictInProgress,
|
||||
};
|
||||
|
||||
NfcCommand nfc_mf_ultralight_c_dict_attack_worker_callback(NfcGenericEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
furi_assert(event.event_data);
|
||||
furi_assert(event.protocol == NfcProtocolMfUltralight);
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
NfcApp* instance = context;
|
||||
MfUltralightPollerEvent* poller_event = event.event_data;
|
||||
|
||||
if(poller_event->type == MfUltralightPollerEventTypeRequestMode) {
|
||||
poller_event->data->poller_mode = MfUltralightPollerModeDictAttack;
|
||||
command = NfcCommandContinue;
|
||||
} else if(poller_event->type == MfUltralightPollerEventTypeRequestKey) {
|
||||
MfUltralightC3DesAuthKey key = {};
|
||||
if(keys_dict_get_next_key(
|
||||
instance->mf_ultralight_c_dict_context.dict,
|
||||
key.data,
|
||||
sizeof(MfUltralightC3DesAuthKey))) {
|
||||
poller_event->data->key_request_data.key = key;
|
||||
poller_event->data->key_request_data.key_provided = true;
|
||||
instance->mf_ultralight_c_dict_context.dict_keys_current++;
|
||||
|
||||
if(instance->mf_ultralight_c_dict_context.dict_keys_current % 10 == 0) {
|
||||
view_dispatcher_send_custom_event(
|
||||
instance->view_dispatcher, NfcCustomEventDictAttackDataUpdate);
|
||||
}
|
||||
} else {
|
||||
poller_event->data->key_request_data.key_provided = false;
|
||||
}
|
||||
} else if(poller_event->type == MfUltralightPollerEventTypeReadSuccess) {
|
||||
nfc_device_set_data(
|
||||
instance->nfc_device, NfcProtocolMfUltralight, nfc_poller_get_data(instance->poller));
|
||||
view_dispatcher_send_custom_event(
|
||||
instance->view_dispatcher, NfcCustomEventDictAttackComplete);
|
||||
command = NfcCommandStop;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_c_dict_attack_dict_attack_result_callback(
|
||||
DictAttackEvent event,
|
||||
void* context) {
|
||||
furi_assert(context);
|
||||
NfcApp* instance = context;
|
||||
if(event == DictAttackEventSkipPressed) {
|
||||
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventDictAttackSkip);
|
||||
}
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_c_dict_attack_prepare_view(NfcApp* instance) {
|
||||
uint32_t state =
|
||||
scene_manager_get_scene_state(instance->scene_manager, NfcSceneMfUltralightCDictAttack);
|
||||
if(state == DictAttackStateUserDictInProgress) {
|
||||
do {
|
||||
if(!keys_dict_check_presence(NFC_APP_MF_ULTRALIGHT_C_DICT_USER_PATH)) {
|
||||
state = DictAttackStateSystemDictInProgress;
|
||||
break;
|
||||
}
|
||||
instance->mf_ultralight_c_dict_context.dict = keys_dict_alloc(
|
||||
NFC_APP_MF_ULTRALIGHT_C_DICT_USER_PATH,
|
||||
KeysDictModeOpenAlways,
|
||||
sizeof(MfUltralightC3DesAuthKey));
|
||||
if(keys_dict_get_total_keys(instance->mf_ultralight_c_dict_context.dict) == 0) {
|
||||
keys_dict_free(instance->mf_ultralight_c_dict_context.dict);
|
||||
state = DictAttackStateSystemDictInProgress;
|
||||
break;
|
||||
}
|
||||
dict_attack_set_header(instance->dict_attack, "MFUL C User Dictionary");
|
||||
} while(false);
|
||||
}
|
||||
if(state == DictAttackStateSystemDictInProgress) {
|
||||
instance->mf_ultralight_c_dict_context.dict = keys_dict_alloc(
|
||||
NFC_APP_MF_ULTRALIGHT_C_DICT_SYSTEM_PATH,
|
||||
KeysDictModeOpenExisting,
|
||||
sizeof(MfUltralightC3DesAuthKey));
|
||||
dict_attack_set_header(instance->dict_attack, "MFUL C System Dictionary");
|
||||
}
|
||||
|
||||
instance->mf_ultralight_c_dict_context.dict_keys_total =
|
||||
keys_dict_get_total_keys(instance->mf_ultralight_c_dict_context.dict);
|
||||
dict_attack_set_total_dict_keys(
|
||||
instance->dict_attack, instance->mf_ultralight_c_dict_context.dict_keys_total);
|
||||
instance->mf_ultralight_c_dict_context.dict_keys_current = 0;
|
||||
dict_attack_set_callback(
|
||||
instance->dict_attack,
|
||||
nfc_scene_mf_ultralight_c_dict_attack_dict_attack_result_callback,
|
||||
instance);
|
||||
scene_manager_set_scene_state(instance->scene_manager, NfcSceneMfUltralightCDictAttack, state);
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_c_dict_attack_on_enter(void* context) {
|
||||
NfcApp* instance = context;
|
||||
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfUltralightCDictAttack,
|
||||
DictAttackStateUserDictInProgress);
|
||||
nfc_scene_mf_ultralight_c_dict_attack_prepare_view(instance);
|
||||
|
||||
// Setup and start worker
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfUltralight);
|
||||
nfc_poller_start(instance->poller, nfc_mf_ultralight_c_dict_attack_worker_callback, instance);
|
||||
|
||||
nfc_blink_read_start(instance);
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ul_c_dict_attack_update_view(NfcApp* instance) {
|
||||
dict_attack_set_card_state(
|
||||
instance->dict_attack, instance->mf_ultralight_c_dict_context.is_card_present);
|
||||
dict_attack_set_current_dict_key(
|
||||
instance->dict_attack, instance->mf_ultralight_c_dict_context.dict_keys_current);
|
||||
}
|
||||
|
||||
bool nfc_scene_mf_ultralight_c_dict_attack_on_event(void* context, SceneManagerEvent event) {
|
||||
NfcApp* instance = context;
|
||||
bool consumed = false;
|
||||
|
||||
uint32_t state =
|
||||
scene_manager_get_scene_state(instance->scene_manager, NfcSceneMfUltralightCDictAttack);
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == NfcCustomEventDictAttackComplete) {
|
||||
if(state == DictAttackStateUserDictInProgress) {
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
keys_dict_free(instance->mf_ultralight_c_dict_context.dict);
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfUltralightCDictAttack,
|
||||
DictAttackStateSystemDictInProgress);
|
||||
nfc_scene_mf_ultralight_c_dict_attack_prepare_view(instance);
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfUltralight);
|
||||
nfc_poller_start(
|
||||
instance->poller, nfc_mf_ultralight_c_dict_attack_worker_callback, instance);
|
||||
consumed = true;
|
||||
} else {
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
|
||||
dolphin_deed(DolphinDeedNfcReadSuccess);
|
||||
consumed = true;
|
||||
}
|
||||
} else if(event.event == NfcCustomEventDictAttackDataUpdate) {
|
||||
dict_attack_set_current_dict_key(
|
||||
instance->dict_attack, instance->mf_ultralight_c_dict_context.dict_keys_current);
|
||||
consumed = true;
|
||||
} else if(event.event == NfcCustomEventDictAttackSkip) {
|
||||
if(instance->mf_ultralight_c_dict_context.is_card_present) {
|
||||
if(state == DictAttackStateUserDictInProgress) {
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
keys_dict_free(instance->mf_ultralight_c_dict_context.dict);
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfUltralightCDictAttack,
|
||||
DictAttackStateSystemDictInProgress);
|
||||
nfc_scene_mf_ultralight_c_dict_attack_prepare_view(instance);
|
||||
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfUltralight);
|
||||
nfc_poller_start(
|
||||
instance->poller,
|
||||
nfc_mf_ultralight_c_dict_attack_worker_callback,
|
||||
instance);
|
||||
} else {
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
notification_message(instance->notifications, &sequence_success);
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneReadSuccess);
|
||||
dolphin_deed(DolphinDeedNfcReadSuccess);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
scene_manager_next_scene(instance->scene_manager, NfcSceneExitConfirm);
|
||||
consumed = true;
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void nfc_scene_mf_ultralight_c_dict_attack_on_exit(void* context) {
|
||||
NfcApp* instance = context;
|
||||
nfc_poller_stop(instance->poller);
|
||||
nfc_poller_free(instance->poller);
|
||||
scene_manager_set_scene_state(
|
||||
instance->scene_manager,
|
||||
NfcSceneMfUltralightCDictAttack,
|
||||
DictAttackStateUserDictInProgress);
|
||||
keys_dict_free(instance->mf_ultralight_c_dict_context.dict);
|
||||
instance->mf_ultralight_c_dict_context.dict_keys_total = 0;
|
||||
instance->mf_ultralight_c_dict_context.dict_keys_current = 0;
|
||||
instance->mf_ultralight_c_dict_context.auth_success = false;
|
||||
instance->mf_ultralight_c_dict_context.is_card_present = false;
|
||||
nfc_blink_stop(instance);
|
||||
}
|
||||
@@ -181,6 +181,10 @@ MfUltralightPoller* mf_ultralight_poller_alloc(Iso14443_3aPoller* iso14443_3a_po
|
||||
instance->general_event.protocol = NfcProtocolMfUltralight;
|
||||
instance->general_event.event_data = &instance->mfu_event;
|
||||
instance->general_event.instance = instance;
|
||||
|
||||
instance->dict_attack_ctx.auth_success = false;
|
||||
instance->dict_attack_ctx.is_card_present = false;
|
||||
|
||||
mbedtls_des3_init(&instance->des_context);
|
||||
return instance;
|
||||
}
|
||||
@@ -521,7 +525,7 @@ static NfcCommand mf_ultralight_poller_handler_read_pages(MfUltralightPoller* in
|
||||
} else {
|
||||
if(instance->data->type == MfUltralightTypeMfulC &&
|
||||
!mf_ultralight_3des_key_valid(instance->data)) {
|
||||
instance->state = MfUltralightPollerStateCheckMfulCAuthStatus;
|
||||
instance->state = MfUltralightPollerStateDictAttack;
|
||||
} else {
|
||||
FURI_LOG_D(TAG, "Read page %d failed", instance->pages_read);
|
||||
if(instance->pages_read) {
|
||||
@@ -730,6 +734,63 @@ static NfcCommand mf_ultralight_poller_handler_write_success(MfUltralightPoller*
|
||||
return command;
|
||||
}
|
||||
|
||||
static NfcCommand mf_ultralight_poller_handler_dict_attack(MfUltralightPoller* instance) {
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
const MfUltralightData* tag_data = instance->data;
|
||||
uint32_t features = mf_ultralight_get_feature_support_set(tag_data->type);
|
||||
FURI_LOG_D(TAG, "Dict Attack");
|
||||
do {
|
||||
if(!mf_ultralight_support_feature(features, MfUltralightFeatureSupportAuthenticate)) {
|
||||
instance->error = MfUltralightErrorProtocol;
|
||||
instance->state = MfUltralightPollerStateReadFailed;
|
||||
break;
|
||||
}
|
||||
|
||||
instance->dict_attack_ctx.is_card_present = true;
|
||||
instance->mfu_event.type = MfUltralightPollerEventTypeRequestKey;
|
||||
command = instance->callback(instance->general_event, instance->context);
|
||||
if(!instance->mfu_event.data->key_request_data.key_provided) {
|
||||
instance->state = MfUltralightPollerStateReadSuccess;
|
||||
break;
|
||||
}
|
||||
|
||||
FURI_LOG_D(TAG, "Trying next 3DES key");
|
||||
instance->error = MfUltralightErrorNone;
|
||||
instance->auth_context.auth_success = false;
|
||||
instance->auth_context.tdes_key = instance->mfu_event.data->key_request_data.key;
|
||||
do {
|
||||
uint8_t output[MF_ULTRALIGHT_C_AUTH_DATA_SIZE];
|
||||
uint8_t RndA[MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE] = {0};
|
||||
furi_hal_random_fill_buf(RndA, sizeof(RndA));
|
||||
instance->error = mf_ultralight_poller_authenticate_start(instance, RndA, output);
|
||||
if(instance->error != MfUltralightErrorNone) break;
|
||||
|
||||
uint8_t decoded_shifted_RndA[MF_ULTRALIGHT_C_AUTH_RND_BLOCK_SIZE] = {0};
|
||||
const uint8_t* RndB = output + MF_ULTRALIGHT_C_AUTH_RND_B_BLOCK_OFFSET;
|
||||
instance->error = mf_ultralight_poller_authenticate_end(
|
||||
instance, RndB, output, decoded_shifted_RndA);
|
||||
if(instance->error != MfUltralightErrorNone) break;
|
||||
|
||||
mf_ultralight_3des_shift_data(RndA);
|
||||
instance->auth_context.auth_success =
|
||||
(memcmp(RndA, decoded_shifted_RndA, sizeof(decoded_shifted_RndA)) == 0);
|
||||
if(instance->auth_context.auth_success) {
|
||||
FURI_LOG_D(TAG, "Dict attack success");
|
||||
instance->state = MfUltralightPollerStateReadPages;
|
||||
instance->dict_attack_ctx.auth_success = true;
|
||||
break;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
if(!instance->auth_context.auth_success) {
|
||||
FURI_LOG_D(TAG, "Dict attack auth failed");
|
||||
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
|
||||
}
|
||||
} while(false);
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
static const MfUltralightPollerReadHandler
|
||||
mf_ultralight_poller_read_handler[MfUltralightPollerStateNum] = {
|
||||
[MfUltralightPollerStateIdle] = mf_ultralight_poller_handler_idle,
|
||||
@@ -755,6 +816,7 @@ static const MfUltralightPollerReadHandler
|
||||
[MfUltralightPollerStateWritePages] = mf_ultralight_poller_handler_write_pages,
|
||||
[MfUltralightPollerStateWriteFail] = mf_ultralight_poller_handler_write_fail,
|
||||
[MfUltralightPollerStateWriteSuccess] = mf_ultralight_poller_handler_write_success,
|
||||
[MfUltralightPollerStateDictAttack] = mf_ultralight_poller_handler_dict_attack,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ typedef enum {
|
||||
MfUltralightPollerEventTypeCardLocked, /**< Presented card is locked by password, AUTH0 or lock bytes. */
|
||||
MfUltralightPollerEventTypeWriteSuccess, /**< Poller wrote card successfully. */
|
||||
MfUltralightPollerEventTypeWriteFail, /**< Poller failed to write card. */
|
||||
MfUltralightPollerEventTypeRequestKey, /**< Poller requests key for dict attack. */
|
||||
} MfUltralightPollerEventType;
|
||||
|
||||
/**
|
||||
@@ -35,6 +36,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
MfUltralightPollerModeRead, /**< Poller will only read card. It's a default mode. */
|
||||
MfUltralightPollerModeWrite, /**< Poller will write already saved card to another presented card. */
|
||||
MfUltralightPollerModeDictAttack, /**< Poller will perform dictionary attack against card. */
|
||||
} MfUltralightPollerMode;
|
||||
|
||||
/**
|
||||
@@ -42,20 +44,29 @@ typedef enum {
|
||||
*/
|
||||
typedef struct {
|
||||
MfUltralightAuthPassword password; /**< Password to be used for authentication. */
|
||||
MfUltralightC3DesAuthKey tdes_key;
|
||||
MfUltralightAuthPack pack; /**< Pack received on successfull authentication. */
|
||||
MfUltralightC3DesAuthKey tdes_key; /**< 3DES key to be used for authentication. */
|
||||
MfUltralightAuthPack pack; /**< Pack received on successful authentication. */
|
||||
bool auth_success; /**< Set to true if authentication succeeded, false otherwise. */
|
||||
bool skip_auth; /**< Set to true if authentication should be skipped, false otherwise. */
|
||||
} MfUltralightPollerAuthContext;
|
||||
|
||||
/**
|
||||
* @brief MfUltralight poller key request data.
|
||||
*/
|
||||
typedef struct {
|
||||
MfUltralightC3DesAuthKey key; /**< Key to try. */
|
||||
bool key_provided; /**< Set to true if key was provided, false to stop attack. */
|
||||
} MfUltralightPollerKeyRequestData;
|
||||
|
||||
/**
|
||||
* @brief MfUltralight poller event data.
|
||||
*/
|
||||
typedef union {
|
||||
MfUltralightPollerAuthContext auth_context; /**< Authentication context. */
|
||||
MfUltralightError error; /**< Error code indicating reading fail reason. */
|
||||
const MfUltralightData* write_data;
|
||||
MfUltralightPollerMode poller_mode;
|
||||
const MfUltralightData* write_data; /**< Data to be written to card. */
|
||||
MfUltralightPollerMode poller_mode; /**< Mode to operate in. */
|
||||
MfUltralightPollerKeyRequestData key_request_data; /**< Key request data. */
|
||||
} MfUltralightPollerEventData;
|
||||
|
||||
/**
|
||||
@@ -64,7 +75,7 @@ typedef union {
|
||||
* Upon emission of an event, an instance of this struct will be passed to the callback.
|
||||
*/
|
||||
typedef struct {
|
||||
MfUltralightPollerEventType type; /**< Type of emmitted event. */
|
||||
MfUltralightPollerEventType type; /**< Type of emitted event. */
|
||||
MfUltralightPollerEventData* data; /**< Pointer to event specific data. */
|
||||
} MfUltralightPollerEvent;
|
||||
|
||||
|
||||
@@ -68,10 +68,17 @@ typedef enum {
|
||||
MfUltralightPollerStateWritePages,
|
||||
MfUltralightPollerStateWriteFail,
|
||||
MfUltralightPollerStateWriteSuccess,
|
||||
MfUltralightPollerStateDictAttack,
|
||||
|
||||
MfUltralightPollerStateNum,
|
||||
} MfUltralightPollerState;
|
||||
|
||||
typedef struct {
|
||||
uint8_t sectors_total;
|
||||
bool auth_success;
|
||||
bool is_card_present;
|
||||
} MfUltralightPollerDictAttackContext;
|
||||
|
||||
struct MfUltralightPoller {
|
||||
Iso14443_3aPoller* iso14443_3a_poller;
|
||||
MfUltralightPollerState state;
|
||||
@@ -89,6 +96,7 @@ struct MfUltralightPoller {
|
||||
uint8_t tearing_flag_total;
|
||||
uint16_t current_page;
|
||||
MfUltralightError error;
|
||||
MfUltralightPollerDictAttackContext dict_attack_ctx;
|
||||
mbedtls_des3_context des_context;
|
||||
|
||||
NfcGenericEvent general_event;
|
||||
|
||||
Reference in New Issue
Block a user