From e4f373dd65b8d908d15eef5389d779b8a272e65e Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Fri, 13 Oct 2023 21:54:07 +0800 Subject: [PATCH 1/4] Finished configcard implementation for keyroll cards Finalized implementation of configcard generation for keyroll when cardhelper is not present. Results need to be compared with cardhelper output. --- CHANGELOG.md | 7 +-- client/src/cmdhficlass.c | 106 ++++++++++++++++++++++++++++----------- 2 files changed, 82 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16037543b..652445723 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,15 +7,16 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `hf iclass wrbl` - pagemap bit map for secured is now handled better (@iceman1001) - Changed `hf iclass view/decrypt` to detect SIO lengths better and show if legacy credentials are encrypted (@nvx) - Changed the json file formats for mfc, 14b, 15, legic, cryptorf, ndef (@iceman1001) - - Depricated the EML file format when saving dump files. (@iceman1001) + - Deprecated the EML file format when saving dump files. (@iceman1001) - Added `sim014.bin` - new sim module firmware v4.42 with improved ISO7816 Protocol T0 support (@gentilkiwi) - Added datasheet for sim module (@iceman1001) - Changed `smart raw --timeout` - allows for a custom timeout (@iceman1001) - Changed `lf t55 detectp1` - now also accepts 0xE039 Silicon Craft Tech as valid card (@iceman1001) - Fixed `utils.lua` library function "convertdectohex" wasn't working (@iceman1001) - Added `hf iclass creditepurse` command to allow crediting the epurse debit value (@nvx) - - Modified `hf iclass configcard` to only support online mode @ATK - - Modified `hf iclass configcard` command to generate config cards without a cardhelper module by porting the contents of blocks 7 & 7 from nfc-iclass @ATK + - Modified `hf iclass configcard` to only support online mode (@Antiklesys) + - Modified `hf iclass configcard` command to generate config cards without a cardhelper module by porting the contents of blocks 6 & 7 from nfc-iclass (@Antiklesys) + - Finalized implementation of configcard generation for keyroll when cardhelper is not present (@Antiklesys) ## [Raccoon.4.17140][2023-09-09] - Changed text and adjust pm3_test case for mf_aes_brute (@doegox) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 1030c8ee9..8ff742847 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -274,6 +274,16 @@ static void print_config_card(const iclass_config_card_item_t *o) { } } +static void iclass_encrypt_block_data(uint8_t *blk_data, uint8_t *key) { + uint8_t encrypted_data[16]; + uint8_t *encrypted = encrypted_data; + mbedtls_des3_context ctx; + mbedtls_des3_set2key_enc(&ctx, key); + mbedtls_des3_crypt_ecb(&ctx, blk_data, encrypted); + memcpy(blk_data, encrypted, 8); + mbedtls_des3_free(&ctx); +} + static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *key, bool got_kr) { if (check_config_card(o) == false) { return PM3_EINVARG; @@ -353,11 +363,35 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke SetFlushAfterWrite(true); // KEYROLL need to encrypt + uint8_t key_en[16] = {0}; + uint8_t *keyptr_en = NULL; + if (IsCardHelperPresent(false) == false){ + size_t keylen = 0; + int res_key = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr_en, &keylen); + if (res_key != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Failed to find iclass_decryptionkey.bin"); + return PM3_EINVARG; + } + + if (keylen != 16) { + PrintAndLogEx(ERR, "Failed to load transport key from file"); + free(keyptr_en); + return PM3_EINVARG; + } + memcpy(key_en, keyptr_en, sizeof(key_en)); + free(keyptr_en); + } + PrintAndLogEx(INFO, "Setting up encryption... " NOLF); uint8_t ffs[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - if (Encrypt(ffs, ffs) == false) { - PrintAndLogEx(WARNING, "failed to encrypt FF"); - } else { + if (IsCardHelperPresent(false) != false){ + if (Encrypt(ffs, ffs) == false) { + PrintAndLogEx(WARNING, "failed to encrypt FF"); + } else { + PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); + } + }else{ + iclass_encrypt_block_data(ffs, key_en); PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); } @@ -366,9 +400,14 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke uint8_t lkey[8]; memcpy(lkey, key, sizeof(lkey)); uint8_t enckey1[8]; - if (Encrypt(lkey, enckey1) == false) { - PrintAndLogEx(WARNING, "failed to encrypt key1"); - } else { + if (IsCardHelperPresent(false) != false){ + if (Encrypt(lkey, enckey1) == false) { + PrintAndLogEx(WARNING, "failed to encrypt key1"); + } else { + PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); + } + }else{ + iclass_encrypt_block_data(lkey, key_en); PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); } @@ -377,9 +416,13 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke memcpy(data + (6 * 8), o->data, sizeof(o->data)); // encrypted keyroll key 0D - memcpy(data + (0xD * 8), enckey1, sizeof(enckey1)); + if (IsCardHelperPresent(false) != false){ + memcpy(data + (0x0D * 8), enckey1, sizeof(enckey1)); + } else { + memcpy(data + (0x0D * 8), lkey, sizeof(enckey1)); + } // encrypted 0xFF - for (uint8_t i = 0xD; i < 0x14; i++) { + for (uint8_t i = 0x0D; i < 0x14; i++) { memcpy(data + (i * 8), ffs, sizeof(ffs)); } PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); @@ -387,24 +430,37 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke // encrypted partial keyroll key 14 PrintAndLogEx(INFO, "Setting encrypted partial key14... " NOLF); uint8_t foo[8] = {0x15}; - memcpy(foo + 1, lkey, 7); + memcpy(foo + 1, key, 7); uint8_t enckey2[8]; - if (Encrypt(foo, enckey2) == false) { - PrintAndLogEx(WARNING, "failed to encrypt partial 1"); + if (IsCardHelperPresent(false) != false){ + if (Encrypt(foo, enckey2) == false) { + PrintAndLogEx(WARNING, "failed to encrypt partial 1"); + } else { + PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); + memcpy(data + (0x14 * 8), enckey2, sizeof(enckey2)); + } + }else{ + iclass_encrypt_block_data(foo, key_en); + PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); + memcpy(data + (0x14 * 8), foo, sizeof(enckey2)); } - memcpy(data + (0x14 * 8), enckey2, sizeof(enckey2)); - PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); - // encrypted partial keyroll key 15 PrintAndLogEx(INFO, "Setting encrypted partial key15... " NOLF); memset(foo, 0xFF, sizeof(foo)); foo[0] = lkey[7]; - if (Encrypt(foo, enckey2) == false) { - PrintAndLogEx(WARNING, "failed to encrypt partial 2"); + if (IsCardHelperPresent(false) != false){ + if (Encrypt(foo, enckey2) == false) { + PrintAndLogEx(WARNING, "failed to encrypt partial 2"); + } else { + PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); + memcpy(data + (0x15 * 8), enckey2, sizeof(enckey2)); + } + }else{ + iclass_encrypt_block_data(foo, key_en); + PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); + memcpy(data + (0x15 * 8), foo, sizeof(enckey2)); } - memcpy(data + (0x15 * 8), enckey2, sizeof(enckey2)); - PrintAndLogEx(NORMAL, "( " _GREEN_("ok") " )"); // encrypted 0xFF PrintAndLogEx(INFO, "Setting 0xFF's... " NOLF); @@ -1547,16 +1603,6 @@ static int CmdHFiClassDecrypt(const char *Cmd) { return PM3_SUCCESS; } -static void iclass_encrypt_block_data(uint8_t *blk_data, uint8_t *key) { - uint8_t encrypted_data[16]; - uint8_t *encrypted = encrypted_data; - mbedtls_des3_context ctx; - mbedtls_des3_set2key_enc(&ctx, key); - mbedtls_des3_crypt_ecb(&ctx, blk_data, encrypted); - memcpy(blk_data, encrypted, 8); - mbedtls_des3_free(&ctx); -} - static int CmdHFiClassEncryptBlk(const char *Cmd) { CLIParserContext *clictx; CLIParserInit(&clictx, "hf iclass encrypt", @@ -4376,6 +4422,10 @@ static int CmdHFiClassConfigCard(const char *Cmd) { return PM3_EINVARG; } } + if(ccidx < -1 && ccidx > 12 && IsCardHelperPresent(false) == false){ + PrintAndLogEx(ERR, "Please specify a configuration between 0 and 12!"); + return PM3_EINVARG; + } generate_config_card(item, key, got_kr); } From 7b4af95a404a3775f587a8e1d84a04e7cbc9725c Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Fri, 13 Oct 2023 22:16:10 +0800 Subject: [PATCH 2/4] Update cmdhficlass.c --- client/src/cmdhficlass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 8ff742847..3bb4db080 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -225,7 +225,7 @@ static bool check_config_card(const iclass_config_card_item_t *o) { static int load_config_cards(void) { PrintAndLogEx(INFO, "detecting cardhelper..."); - if (IsCardHelperPresent(false) == false) { + if (IsCardHelperPresent(false)) { PrintAndLogEx(FAILED, "failed to detect cardhelper"); return PM3_ENODATA; } @@ -365,7 +365,7 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke // KEYROLL need to encrypt uint8_t key_en[16] = {0}; uint8_t *keyptr_en = NULL; - if (IsCardHelperPresent(false) == false){ + if (IsCardHelperPresent(false)){ size_t keylen = 0; int res_key = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr_en, &keylen); if (res_key != PM3_SUCCESS) { @@ -4422,7 +4422,7 @@ static int CmdHFiClassConfigCard(const char *Cmd) { return PM3_EINVARG; } } - if(ccidx < -1 && ccidx > 12 && IsCardHelperPresent(false) == false){ + if(ccidx < -1 && ccidx > 12 && IsCardHelperPresent(false)){ PrintAndLogEx(ERR, "Please specify a configuration between 0 and 12!"); return PM3_EINVARG; } From 0692af842505321820bad81f68f17ceaeab59969 Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Fri, 13 Oct 2023 22:22:10 +0800 Subject: [PATCH 3/4] Update cmdhficlass.c Reverted changes as otherwise the check is ignored. --- client/src/cmdhficlass.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 3bb4db080..8ff742847 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -225,7 +225,7 @@ static bool check_config_card(const iclass_config_card_item_t *o) { static int load_config_cards(void) { PrintAndLogEx(INFO, "detecting cardhelper..."); - if (IsCardHelperPresent(false)) { + if (IsCardHelperPresent(false) == false) { PrintAndLogEx(FAILED, "failed to detect cardhelper"); return PM3_ENODATA; } @@ -365,7 +365,7 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke // KEYROLL need to encrypt uint8_t key_en[16] = {0}; uint8_t *keyptr_en = NULL; - if (IsCardHelperPresent(false)){ + if (IsCardHelperPresent(false) == false){ size_t keylen = 0; int res_key = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&keyptr_en, &keylen); if (res_key != PM3_SUCCESS) { @@ -4422,7 +4422,7 @@ static int CmdHFiClassConfigCard(const char *Cmd) { return PM3_EINVARG; } } - if(ccidx < -1 && ccidx > 12 && IsCardHelperPresent(false)){ + if(ccidx < -1 && ccidx > 12 && IsCardHelperPresent(false) == false){ PrintAndLogEx(ERR, "Please specify a configuration between 0 and 12!"); return PM3_EINVARG; } From 28c4f66c0b21c23dc8c0f2d7c95067de2c4caa87 Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Fri, 13 Oct 2023 22:53:29 +0800 Subject: [PATCH 4/4] Update cmdhficlass.c --- client/src/cmdhficlass.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 8ff742847..f93d73b20 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -4422,10 +4422,6 @@ static int CmdHFiClassConfigCard(const char *Cmd) { return PM3_EINVARG; } } - if(ccidx < -1 && ccidx > 12 && IsCardHelperPresent(false) == false){ - PrintAndLogEx(ERR, "Please specify a configuration between 0 and 12!"); - return PM3_EINVARG; - } generate_config_card(item, key, got_kr); }