Mifare Ultralight authentication (#1365)

* mifare ultralight auth prototype
* it works!
* Reference source
* use countof
* rework everything
* oops forgot scenes
* build: revert changes in manifest, stack size
* build: fix buid, format sources
* nfc: update unlock ultralight GUI
* nfc: fix byte input header
* nfc: add new scenes for locked ultralight
* nfc: add data read to ultralights
* nfc: add unlock option in mf ultralight menu
* nfc: add data read init in ultralight generation
* nfc: lin sources, fix unlocked save
* nfc: format python sources
* nfc: clean up

Co-authored-by: gornekich <n.gorbadey@gmail.com>
This commit is contained in:
Vitaliya Chumakova
2022-08-07 18:09:00 +03:00
committed by GitHub
parent d147190d61
commit 9ffcc52ada
22 changed files with 717 additions and 73 deletions

View File

@@ -101,6 +101,8 @@ int32_t nfc_worker_task(void* context) {
nfc_worker_emulate_mf_ultralight(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateMfClassicEmulate) {
nfc_worker_emulate_mf_classic(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) {
nfc_worker_mf_ultralight_read_auth(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
nfc_worker_mf_classic_dict_attack(nfc_worker);
}
@@ -416,10 +418,7 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
return;
}
FURI_LOG_D(
TAG,
"Start Dictionary attack, Key Count %d",
mf_classic_dict_get_total_keys(dict));
FURI_LOG_D(TAG, "Start Dictionary attack, Key Count %d", mf_classic_dict_get_total_keys(dict));
for(size_t i = 0; i < total_sectors; i++) {
FURI_LOG_I(TAG, "Sector %d", i);
nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context);
@@ -462,20 +461,17 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
}
}
if(is_key_a_found && is_key_b_found) break;
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack)
break;
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
} else {
if(!card_removed_notified) {
nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
card_removed_notified = true;
card_found_notified = false;
}
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack)
break;
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
}
}
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack)
break;
if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
mf_classic_read_sector(&tx_rx, data, i);
mf_classic_dict_rewind(dict);
}
@@ -518,3 +514,57 @@ void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker) {
rfal_platform_spi_release();
}
void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) {
furi_assert(nfc_worker);
furi_assert(nfc_worker->callback);
MfUltralightData* data = &nfc_worker->dev_data->mf_ul_data;
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
FuriHalNfcTxRxContext tx_rx = {};
MfUltralightReader reader = {};
mf_ul_reset(data);
uint32_t key = 0;
uint16_t pack = 0;
while(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) {
furi_hal_nfc_sleep();
if(furi_hal_nfc_detect(nfc_data, 300) && nfc_data->type == FuriHalNfcTypeA) {
if(mf_ul_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) {
nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
if(data->auth_method == MfUltralightAuthMethodManual) {
nfc_worker->callback(NfcWorkerEventMfUltralightPassKey, nfc_worker->context);
key = nfc_util_bytes2num(data->auth_key, 4);
} else if(data->auth_method == MfUltralightAuthMethodAmeebo) {
key = mf_ul_pwdgen_amiibo(nfc_data);
} else if(data->auth_method == MfUltralightAuthMethodXiaomi) {
key = mf_ul_pwdgen_xiaomi(nfc_data);
} else {
FURI_LOG_E(TAG, "Incorrect auth method");
break;
}
data->auth_success = mf_ultralight_authenticate(&tx_rx, key, &pack);
mf_ul_read_card(&tx_rx, &reader, data);
if(data->auth_success) {
MfUltralightConfigPages* config_pages = mf_ultralight_get_config_pages(data);
if(config_pages != NULL) {
config_pages->auth_data.pwd.value = REVERSE_BYTES_U32(key);
config_pages->auth_data.pack.value = pack;
}
nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context);
break;
} else {
nfc_worker->callback(NfcWorkerEventFail, nfc_worker->context);
break;
}
} else {
nfc_worker->callback(NfcWorkerEventWrongCardDetected, nfc_worker->context);
furi_delay_ms(10);
}
} else {
nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
furi_delay_ms(10);
}
}
}