Skip to content

Commit

Permalink
Merge pull request #2126 from Antiklesys/master
Browse files Browse the repository at this point in the history
Finished configcard implementation for keyroll cards
  • Loading branch information
iceman1001 authored Oct 14, 2023
2 parents 8f62e80 + 80ac797 commit e0f73d4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 32 deletions.
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...

## [unreleased][unreleased]
- Changed the timeout of local TCP connections (@wh201906)
- Finalized implementation of configcard generation for keyroll when cardhelper is not present (@Antiklesys)
- Added documentation for compiling on iOS (@The-SamminAter)
- 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
- Changed the timeout of local TCP connections (@wh201906)
- 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)

## [Raccoon.4.17140][2023-09-09]
- Changed text and adjust pm3_test case for mf_aes_brute (@doegox)
Expand Down
102 changes: 74 additions & 28 deletions client/src/cmdhficlass.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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") " )");
}

Expand All @@ -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") " )");
}

Expand All @@ -377,34 +416,51 @@ 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") " )");

// 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);
Expand Down Expand Up @@ -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",
Expand Down

0 comments on commit e0f73d4

Please sign in to comment.