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

Finished configcard implementation for keyroll cards #2126

Merged
merged 5 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
106 changes: 78 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 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);
Dismissed Show dismissed Hide dismissed
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 @@
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 @@
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 @@
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 @@
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 Expand Up @@ -4376,6 +4422,10 @@
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);
}

Expand Down
Loading