Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions picopass/.catalog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ There are some situations when the offline loclass may not find a key, such as:

Due to the nature of how secure picopass works, it is possible to emulate some public fields from a card and capture the reader's response, which can be used to authenticate. Two of the pieces involved in this are the NR and MAC.

These instructions are intended to be performed all at the same time. If you use the card with the reader between Card Part 1 and Card Part 2, then Card Part 2 will fail.

## Card Part 1

1. Place card against Flipper Zero
Expand Down
11 changes: 10 additions & 1 deletion picopass/picopass_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ static bool picopass_device_save_file(
FuriString* temp_str;
temp_str = furi_string_alloc();

if(dev->format == PicopassDeviceSaveFormatPartial) {
// Clear key that may have been set when doing key tests for legacy
memset(AA1[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0, PICOPASS_BLOCK_LEN);
}

do {
if(use_load_path && !furi_string_empty(dev->load_path)) {
// Get directory name
Expand All @@ -178,7 +183,8 @@ static bool picopass_device_save_file(
furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension);
}

if(dev->format == PicopassDeviceSaveFormatHF) {
if(dev->format == PicopassDeviceSaveFormatHF ||
dev->format == PicopassDeviceSaveFormatPartial) {
// Open file
if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break;

Expand Down Expand Up @@ -229,6 +235,9 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) {
} else if(dev->format == PicopassDeviceSaveFormatSeader) {
return picopass_device_save_file(
dev, dev_name, EXT_PATH("apps_data/seader"), ".credential", true);
} else if(dev->format == PicopassDeviceSaveFormatPartial) {
return picopass_device_save_file(
dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, PICOPASS_APP_EXTENSION, true);
}

return false;
Expand Down
1 change: 1 addition & 0 deletions picopass/picopass_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef enum {
PicopassDeviceSaveFormatHF,
PicopassDeviceSaveFormatLF,
PicopassDeviceSaveFormatSeader,
PicopassDeviceSaveFormatPartial,
} PicopassDeviceSaveFormat;

typedef enum {
Expand Down
14 changes: 9 additions & 5 deletions picopass/protocol/picopass_poller.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,9 @@ NfcCommand picopass_poller_check_security(PicopassPoller* instance) {

if(instance->data->pacs.se_enabled) {
FURI_LOG_D(TAG, "SE enabled");
instance->state = PicopassPollerStateNrMacAuth;
} else {
instance->state = PicopassPollerStateAuth;
}
// Always try the NR-MAC auth in case we have the file.
instance->state = PicopassPollerStateNrMacAuth;
return command;
}

Expand Down Expand Up @@ -221,8 +220,13 @@ NfcCommand picopass_poller_nr_mac_auth(PicopassPoller* instance) {
FURI_LOG_D(TAG, "Looking for %s", furi_string_get_cstr(temp_str));
uint8_t nr_mac[PICOPASS_BLOCK_LEN];

// Presume failure unless all steps are successful and the state is made "read block"
instance->state = PicopassPollerStateFail;
// Set next state so breaking do/while will jump to it. If successful, do/while will set to ReadBlock
if(instance->data->pacs.se_enabled) {
instance->state = PicopassPollerStateFail;
} else {
// For non-SE, run through normal key check
instance->state = PicopassPollerStateAuth;
}
do {
//check for file
if(!flipper_format_file_open_existing(file, furi_string_get_cstr(temp_str))) break;
Expand Down
2 changes: 1 addition & 1 deletion picopass/scenes/picopass_scene_card_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
scene_manager_set_scene_state(
picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexSave);
scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
picopass->dev->format = PicopassDeviceSaveFormatHF;
picopass->dev->format = PicopassDeviceSaveFormatPartial;
consumed = true;
} else if(event.event == SubmenuIndexSaveAsSeader) {
scene_manager_set_scene_state(
Expand Down