Skip to content

Commit

Permalink
NFC: Add write support for password-protected mf ultralight tag
Browse files Browse the repository at this point in the history
  • Loading branch information
nekolab committed Jan 14, 2024
1 parent 3fd5f15 commit dcbd51b
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 13 deletions.
16 changes: 15 additions & 1 deletion applications/main/nfc/scenes/nfc_scene_mf_ultralight_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ NfcCommand nfc_scene_mf_ultralight_write_worker_callback(NfcGenericEvent event,
mfu_event->data->poller_mode = MfUltralightPollerModeWrite;
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventCardDetected);
} else if(mfu_event->type == MfUltralightPollerEventTypeAuthRequest) {
mfu_event->data->auth_context.skip_auth = true;
const MfUltralightData* mfu_ref_data =
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
MfUltralightConfigPages* config = NULL;
mf_ultralight_get_config_page(mfu_ref_data, &config);
if(config->auth0 <= mfu_ref_data->pages_total - 1) {
uint8_t pwd_page_idx = mf_ultralight_get_pwd_page_num(mfu_ref_data->type);
memcpy(
mfu_event->data->auth_context.password.data,
mfu_ref_data->page[pwd_page_idx].data,
sizeof(MfUltralightAuthPassword));
} else {
mfu_event->data->auth_context.skip_auth = true;
}
} else if(mfu_event->type == MfUltralightPollerEventTypeRequestWriteData) {
mfu_event->data->write_data =
nfc_device_get_data(instance->nfc_device, NfcProtocolMfUltralight);
Expand All @@ -31,6 +43,8 @@ NfcCommand nfc_scene_mf_ultralight_write_worker_callback(NfcGenericEvent event,
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
command = NfcCommandStop;
} else if(mfu_event->type == MfUltralightPollerEventTypeWriteFail) {
FURI_LOG_D("MfUltralightWrite", "Write failed with %d", mfu_event->data->error);
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure);
command = NfcCommandStop;
} else if(mfu_event->type == MfUltralightPollerEventTypeWriteSuccess) {
view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void nfc_scene_mf_ultralight_write_fail_on_enter(void* context) {
AlignLeft,
AlignTop,
FontSecondary,
"Card protected by\npassword, AUTH0\nor lock bits");
"Wrong password or\ncard protected by\nlock bits");

widget_add_button_element(
widget,
Expand Down
19 changes: 8 additions & 11 deletions lib/nfc/protocols/mf_ultralight/mf_ultralight_poller.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,7 @@ static NfcCommand mf_ultralight_poller_handler_read_tearing_flags(MfUltralightPo
NfcCommand command = NfcCommandContinue;

if(mf_ultralight_support_feature(
instance->feature_set,
MfUltralightFeatureSupportCheckTearingFlag | MfUltralightFeatureSupportSingleCounter)) {
instance->feature_set, MfUltralightFeatureSupportCheckTearingFlag)) {
if(instance->tearing_flag_read == instance->tearing_flag_total) {
instance->state = MfUltralightPollerStateTryDefaultPass;
command = NfcCommandReset;
Expand Down Expand Up @@ -436,7 +435,11 @@ static NfcCommand mf_ultralight_poller_handler_auth(MfUltralightPoller* instance
}
}
}
instance->state = MfUltralightPollerStateReadPages;
if(instance->mode == MfUltralightPollerModeRead) {
instance->state = MfUltralightPollerStateReadPages;
} else {
instance->state = MfUltralightPollerStateRequestWriteData;
}

return command;
}
Expand Down Expand Up @@ -543,14 +546,8 @@ static NfcCommand mf_ultralight_poller_handler_read_success(MfUltralightPoller*
FURI_LOG_D(TAG, "Read success");
instance->mfu_event.type = MfUltralightPollerEventTypeReadSuccess;
NfcCommand command = instance->callback(instance->general_event, instance->context);

if(instance->mode == MfUltralightPollerModeRead) {
iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->state = MfUltralightPollerStateIdle;
} else {
instance->state = MfUltralightPollerStateRequestWriteData;
}

iso14443_3a_poller_halt(instance->iso14443_3a_poller);
instance->state = MfUltralightPollerStateIdle;
return command;
}

Expand Down
5 changes: 5 additions & 0 deletions lib/nfc/protocols/mf_ultralight/mf_ultralight_poller_i.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ MfUltralightError mf_ultralight_poller_write_page(
break;
}
if(!bit_buffer_starts_with_byte(instance->rx_buffer, MF_ULTRALIGHT_CMD_ACK)) {
FURI_LOG_D(
TAG,
"Write page %u NAK'd with %u",
page,
bit_buffer_get_byte(instance->rx_buffer, 0));
ret = MfUltralightErrorProtocol;
break;
}
Expand Down

0 comments on commit dcbd51b

Please sign in to comment.