Skip to content

Commit

Permalink
Picopass save written key (#126)
Browse files Browse the repository at this point in the history
Co-authored-by: あく <alleteam@gmail.com>
  • Loading branch information
bettse and skotopes committed Feb 17, 2024
1 parent d6f32ef commit adff126
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 13 deletions.
2 changes: 1 addition & 1 deletion helpers/iclass_elite_dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ bool iclass_elite_dict_add_key(IclassEliteDict* dict, uint8_t* key) {
furi_assert(dict->stream);

FuriString* key_str = furi_string_alloc();
for(size_t i = 0; i < 6; i++) {
for(size_t i = 0; i < ICLASS_ELITE_KEY_LEN; i++) {
furi_string_cat_printf(key_str, "%02X", key[i]);
}
furi_string_cat_printf(key_str, "\n");
Expand Down
8 changes: 6 additions & 2 deletions picopass_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,17 @@ static bool picopass_device_save_file(
if(!flipper_format_write_comment_cstr(file, "Picopass blocks")) break;
bool block_saved = true;

size_t app_limit = card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0] < PICOPASS_MAX_APP_LIMIT ?
size_t app_limit = card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0] <
PICOPASS_MAX_APP_LIMIT ?
card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0] :
PICOPASS_MAX_APP_LIMIT;
for(size_t i = 0; i < app_limit; i++) {
furi_string_printf(temp_str, "Block %d", i);
if(!flipper_format_write_hex(
file, furi_string_get_cstr(temp_str), card_data[i].data, PICOPASS_BLOCK_LEN)) {
file,
furi_string_get_cstr(temp_str),
card_data[i].data,
PICOPASS_BLOCK_LEN)) {
block_saved = false;
break;
}
Expand Down
13 changes: 10 additions & 3 deletions protocol/picopass_listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ static void picopass_listener_loclass_update_csn(PicopassListener* instance) {

uint8_t key[PICOPASS_BLOCK_LEN] = {};
loclass_iclass_calc_div_key(csn, picopass_iclass_key, key, false);
memcpy(instance->data->card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, key, sizeof(PicopassBlock));
memcpy(
instance->data->card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data,
key,
sizeof(PicopassBlock));

picopass_listener_init_cipher_state_key(instance, key);
}
Expand Down Expand Up @@ -176,7 +179,9 @@ PicopassListenerCommand
}
} else {
bit_buffer_copy_bytes(
instance->tx_buffer, instance->data->card_data[block_num].data, sizeof(PicopassBlock));
instance->tx_buffer,
instance->data->card_data[block_num].data,
sizeof(PicopassBlock));
}
PicopassError error = picopass_listener_send_frame(instance, instance->tx_buffer);
if(error != PicopassErrorNone) {
Expand Down Expand Up @@ -530,7 +535,9 @@ PicopassListenerCommand
}
} else {
bit_buffer_copy_bytes(
instance->tx_buffer, instance->data->card_data[block_num].data, sizeof(PicopassBlock));
instance->tx_buffer,
instance->data->card_data[block_num].data,
sizeof(PicopassBlock));
}

PicopassError error = picopass_listener_send_frame(instance, instance->tx_buffer);
Expand Down
4 changes: 3 additions & 1 deletion protocol/picopass_listener_i.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ static PicopassError picopass_listener_process_error(NfcError error) {
void picopass_listener_init_cipher_state_key(PicopassListener* instance, const uint8_t* key) {
uint8_t cc[PICOPASS_BLOCK_LEN] = {};
memcpy(
cc, instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data, sizeof(PicopassBlock));
cc,
instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data,
sizeof(PicopassBlock));

instance->cipher_state = loclass_opt_doTagMAC_1(cc, key);
}
Expand Down
4 changes: 3 additions & 1 deletion protocol/picopass_poller.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,9 @@ NfcCommand picopass_poller_read_block_handler(PicopassPoller* instance) {
block.data[6],
block.data[7]);
memcpy(
instance->data->card_data[instance->current_block].data, block.data, sizeof(PicopassBlock));
instance->data->card_data[instance->current_block].data,
block.data,
sizeof(PicopassBlock));
instance->current_block++;
} while(false);

Expand Down
4 changes: 2 additions & 2 deletions scenes/picopass_scene_card_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ void picopass_scene_card_menu_on_enter(void* context) {
bool zero_config = picopass_is_memset(
card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data, 0x00, PICOPASS_BLOCK_LEN);
bool no_credential = picopass_is_memset(pacs->credential, 0x00, sizeof(pacs->credential));
bool no_key =
picopass_is_memset(card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN);
bool no_key = picopass_is_memset(
card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN);

if(secured && zero_config) {
submenu_add_item(
Expand Down
3 changes: 2 additions & 1 deletion scenes/picopass_scene_more_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ void picopass_scene_more_info_on_enter(void* context) {

for(size_t i = 0; i < app_limit; i++) {
for(size_t j = 0; j < PICOPASS_BLOCK_LEN; j += 2) {
furi_string_cat_printf(str, "%02X%02X ", card_data[i].data[j], card_data[i].data[j + 1]);
furi_string_cat_printf(
str, "%02X%02X ", card_data[i].data[j], card_data[i].data[j + 1]);
}
}

Expand Down
4 changes: 2 additions & 2 deletions scenes/picopass_scene_read_card_success.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ void picopass_scene_read_card_success_on_enter(void* context) {
furi_string_cat_printf(credential_str, " +SIO");
}

bool no_key =
picopass_is_memset(card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN);
bool no_key = picopass_is_memset(
card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN);

if(no_key) {
furi_string_cat_printf(key_str, "No Key: used NR-MAC");
Expand Down
12 changes: 12 additions & 0 deletions scenes/picopass_scene_write_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ NfcCommand picopass_scene_write_key_poller_callback(PicopassPollerEvent event, v
event.data->req_write_key.key,
picopass->write_key_context.key_to_write,
PICOPASS_KEY_LEN);

event.data->req_write_key.is_elite_key = picopass->write_key_context.is_elite;
} else if(event.type == PicopassPollerEventTypeSuccess) {
view_dispatcher_send_custom_event(
Expand Down Expand Up @@ -44,6 +45,17 @@ void picopass_scene_write_key_on_enter(void* context) {
view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup);
picopass_blink_start(picopass);

// If there is no user dictionary, create it with the key they entered
// Prevent people who set all 0's from bricking their card
// TODO: Consider checking the elite user dict, when it exists, for the key
if(!iclass_elite_dict_check_presence(IclassEliteDictTypeUser)) {
storage_simply_mkdir(picopass->dev->storage, STORAGE_APP_DATA_PATH_PREFIX);
storage_simply_mkdir(picopass->dev->storage, APP_DATA_PATH("assets"));
IclassEliteDict* dict = iclass_elite_dict_alloc(IclassEliteDictTypeUser);
iclass_elite_dict_add_key(dict, picopass->write_key_context.key_to_write);
iclass_elite_dict_free(dict);
}

picopass->poller = picopass_poller_alloc(picopass->nfc);
picopass_poller_start(picopass->poller, picopass_scene_write_key_poller_callback, picopass);
}
Expand Down

0 comments on commit adff126

Please sign in to comment.