Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Picopass save written key #126

Merged
merged 7 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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: 1 addition & 1 deletion picopass/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++) {
bettse marked this conversation as resolved.
Show resolved Hide resolved
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/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 picopass/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 picopass/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 picopass/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 picopass/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 picopass/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 picopass/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
9 changes: 9 additions & 0 deletions picopass/scenes/picopass_scene_write_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ 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);

// 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)) {
IclassEliteDict* dict = iclass_elite_dict_alloc(IclassEliteDictTypeUser);
iclass_elite_dict_add_key(dict, picopass->write_key_context.key_to_write);
bettse marked this conversation as resolved.
Show resolved Hide resolved
iclass_elite_dict_free(dict);
}
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
Loading