From 5be15152ebccaafe750db78aa293515779fed640 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Wed, 8 Mar 2023 03:46:30 -0800 Subject: [PATCH] PicoPass: auth cleanup (#2470) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove redundant auth methods * Move picopass keys to new file * CTF key * Format sources * PicoPass: add pragma once to picopass_keys.h Co-authored-by: あく --- applications/plugins/picopass/picopass_keys.c | 8 ++ applications/plugins/picopass/picopass_keys.h | 10 +++ .../plugins/picopass/picopass_worker.c | 81 ++----------------- .../plugins/picopass/picopass_worker.h | 1 + .../picopass/scenes/picopass_scene_key_menu.c | 6 +- .../scenes/picopass_scene_read_card.c | 3 +- .../picopass_scene_read_factory_success.c | 3 +- .../picopass/assets/iclass_elite_dict.txt | 2 + 8 files changed, 31 insertions(+), 83 deletions(-) create mode 100644 applications/plugins/picopass/picopass_keys.c create mode 100644 applications/plugins/picopass/picopass_keys.h diff --git a/applications/plugins/picopass/picopass_keys.c b/applications/plugins/picopass/picopass_keys.c new file mode 100644 index 00000000..43dfc631 --- /dev/null +++ b/applications/plugins/picopass/picopass_keys.c @@ -0,0 +1,8 @@ +#include "picopass_keys.h" + +const uint8_t picopass_iclass_key[] = {0xaf, 0xa7, 0x85, 0xa7, 0xda, 0xb3, 0x33, 0x78}; +const uint8_t picopass_factory_credit_key[] = {0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00}; +const uint8_t picopass_factory_debit_key[] = {0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87}; +const uint8_t picopass_xice_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88}; +const uint8_t picopass_xicl_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88}; +const uint8_t picopass_xics_key[] = {0x66, 0x66, 0x20, 0x20, 0x66, 0x66, 0x88, 0x88}; diff --git a/applications/plugins/picopass/picopass_keys.h b/applications/plugins/picopass/picopass_keys.h new file mode 100644 index 00000000..2b5dba66 --- /dev/null +++ b/applications/plugins/picopass/picopass_keys.h @@ -0,0 +1,10 @@ +#pragma once + +#include "picopass_device.h" + +extern const uint8_t picopass_iclass_key[PICOPASS_BLOCK_LEN]; +extern const uint8_t picopass_factory_credit_key[PICOPASS_BLOCK_LEN]; +extern const uint8_t picopass_factory_debit_key[PICOPASS_BLOCK_LEN]; +extern const uint8_t picopass_xice_key[PICOPASS_BLOCK_LEN]; +extern const uint8_t picopass_xicl_key[PICOPASS_BLOCK_LEN]; +extern const uint8_t picopass_xics_key[PICOPASS_BLOCK_LEN]; diff --git a/applications/plugins/picopass/picopass_worker.c b/applications/plugins/picopass/picopass_worker.c index 024c5112..f2e9e82b 100644 --- a/applications/plugins/picopass/picopass_worker.c +++ b/applications/plugins/picopass/picopass_worker.c @@ -4,13 +4,6 @@ #define TAG "PicopassWorker" -const uint8_t picopass_iclass_key[] = {0xaf, 0xa7, 0x85, 0xa7, 0xda, 0xb3, 0x33, 0x78}; -const uint8_t picopass_factory_credit_key[] = {0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00}; -const uint8_t picopass_factory_debit_key[] = {0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87}; -const uint8_t picopass_xice_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88}; -const uint8_t picopass_xicl_key[] = {0x20, 0x20, 0x66, 0x66, 0x66, 0x66, 0x88, 0x88}; -const uint8_t picopass_xics_key[] = {0x66, 0x66, 0x20, 0x20, 0x66, 0x66, 0x88, 0x88}; - static void picopass_worker_enable_field() { furi_hal_nfc_ll_txrx_on(); furi_hal_nfc_exit_sleep(); @@ -179,50 +172,6 @@ ReturnCode picopass_read_preauth(PicopassBlock* AA1) { return ERR_NONE; } -static ReturnCode picopass_auth_standard(uint8_t* csn, uint8_t* div_key) { - rfalPicoPassReadCheckRes rcRes; - rfalPicoPassCheckRes chkRes; - - ReturnCode err; - - uint8_t mac[4] = {0}; - uint8_t ccnr[12] = {0}; - - err = rfalPicoPassPollerReadCheck(&rcRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err); - return err; - } - memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0 - - loclass_iclass_calc_div_key(csn, (uint8_t*)picopass_iclass_key, div_key, false); - loclass_opt_doReaderMAC(ccnr, div_key, mac); - - return rfalPicoPassPollerCheck(mac, &chkRes); -} - -static ReturnCode picopass_auth_factory(uint8_t* csn, uint8_t* div_key) { - rfalPicoPassReadCheckRes rcRes; - rfalPicoPassCheckRes chkRes; - - ReturnCode err; - - uint8_t mac[4] = {0}; - uint8_t ccnr[12] = {0}; - - err = rfalPicoPassPollerReadCheck(&rcRes); - if(err != ERR_NONE) { - FURI_LOG_E(TAG, "rfalPicoPassPollerReadCheck error %d", err); - return err; - } - memcpy(ccnr, rcRes.CCNR, sizeof(rcRes.CCNR)); // last 4 bytes left 0 - - loclass_iclass_calc_div_key(csn, (uint8_t*)picopass_factory_debit_key, div_key, false); - loclass_opt_doReaderMAC(ccnr, div_key, mac); - - return rfalPicoPassPollerCheck(mac, &chkRes); -} - static ReturnCode picopass_auth_dict( uint8_t* csn, PicopassPacs* pacs, @@ -291,19 +240,14 @@ static ReturnCode picopass_auth_dict( ReturnCode picopass_auth(PicopassBlock* AA1, PicopassPacs* pacs) { ReturnCode err; - FURI_LOG_I(TAG, "Trying standard legacy key"); - err = picopass_auth_standard( - AA1[PICOPASS_CSN_BLOCK_INDEX].data, AA1[PICOPASS_KD_BLOCK_INDEX].data); + FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]"); + err = picopass_auth_dict( + AA1[PICOPASS_CSN_BLOCK_INDEX].data, + pacs, + AA1[PICOPASS_KD_BLOCK_INDEX].data, + IclassEliteDictTypeFlipper, + false); if(err == ERR_NONE) { - memcpy(pacs->key, picopass_iclass_key, PICOPASS_BLOCK_LEN); - return ERR_NONE; - } - - FURI_LOG_I(TAG, "Trying factory default key"); - err = picopass_auth_factory( - AA1[PICOPASS_CSN_BLOCK_INDEX].data, AA1[PICOPASS_KD_BLOCK_INDEX].data); - if(err == ERR_NONE) { - memcpy(pacs->key, picopass_factory_debit_key, PICOPASS_BLOCK_LEN); return ERR_NONE; } @@ -329,17 +273,6 @@ ReturnCode picopass_auth(PicopassBlock* AA1, PicopassPacs* pacs) { return ERR_NONE; } - FURI_LOG_I(TAG, "Starting system dictionary attack [Standard KDF]"); - err = picopass_auth_dict( - AA1[PICOPASS_CSN_BLOCK_INDEX].data, - pacs, - AA1[PICOPASS_KD_BLOCK_INDEX].data, - IclassEliteDictTypeFlipper, - false); - if(err == ERR_NONE) { - return ERR_NONE; - } - return err; } diff --git a/applications/plugins/picopass/picopass_worker.h b/applications/plugins/picopass/picopass_worker.h index 02b088b2..f5e9f303 100644 --- a/applications/plugins/picopass/picopass_worker.h +++ b/applications/plugins/picopass/picopass_worker.h @@ -1,6 +1,7 @@ #pragma once #include "picopass_device.h" +#include "picopass_keys.h" typedef struct PicopassWorker PicopassWorker; diff --git a/applications/plugins/picopass/scenes/picopass_scene_key_menu.c b/applications/plugins/picopass/scenes/picopass_scene_key_menu.c index b1db37f8..8aac6cb2 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_key_menu.c +++ b/applications/plugins/picopass/scenes/picopass_scene_key_menu.c @@ -1,4 +1,5 @@ #include "../picopass_i.h" +#include "../picopass_keys.h" enum SubmenuIndex { SubmenuIndexWriteStandard, @@ -8,11 +9,6 @@ enum SubmenuIndex { SubmenuIndexWriteCustom, //TODO: user input of key }; -extern const uint8_t picopass_xice_key[]; -extern const uint8_t picopass_xicl_key[]; -extern const uint8_t picopass_xics_key[]; -extern const uint8_t picopass_iclass_key[]; - void picopass_scene_key_menu_submenu_callback(void* context, uint32_t index) { Picopass* picopass = context; diff --git a/applications/plugins/picopass/scenes/picopass_scene_read_card.c b/applications/plugins/picopass/scenes/picopass_scene_read_card.c index c62cba8e..96ec7c66 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_read_card.c +++ b/applications/plugins/picopass/scenes/picopass_scene_read_card.c @@ -1,7 +1,6 @@ #include "../picopass_i.h" #include - -extern const uint8_t picopass_factory_debit_key[]; +#include "../picopass_keys.h" void picopass_read_card_worker_callback(PicopassWorkerEvent event, void* context) { UNUSED(event); diff --git a/applications/plugins/picopass/scenes/picopass_scene_read_factory_success.c b/applications/plugins/picopass/scenes/picopass_scene_read_factory_success.c index b98951dc..bc07bb95 100644 --- a/applications/plugins/picopass/scenes/picopass_scene_read_factory_success.c +++ b/applications/plugins/picopass/scenes/picopass_scene_read_factory_success.c @@ -1,7 +1,6 @@ #include "../picopass_i.h" #include - -extern const uint8_t picopass_iclass_key[]; +#include "../picopass_keys.h" void picopass_scene_read_factory_success_widget_callback( GuiButtonType result, diff --git a/assets/resources/apps_data/picopass/assets/iclass_elite_dict.txt b/assets/resources/apps_data/picopass/assets/iclass_elite_dict.txt index 46808ef6..5da2a2fa 100644 --- a/assets/resources/apps_data/picopass/assets/iclass_elite_dict.txt +++ b/assets/resources/apps_data/picopass/assets/iclass_elite_dict.txt @@ -45,3 +45,5 @@ C1B74D7478053AE2 # default iCLASS RFIDeas 6B65797374726B72 + +5C100DF7042EAE64