Merge pull request #2126 from Antiklesys/master

Finished configcard implementation for keyroll cards
This commit is contained in:
Iceman 2023-10-14 09:53:02 +02:00 committed by GitHub
commit e0f73d4576
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 32 deletions

View file

@ -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)

View file

@ -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,33 +363,66 @@ 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 (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") " )");
}
// local key copy
PrintAndLogEx(INFO, "Encrypting local key... " NOLF);
uint8_t lkey[8];
memcpy(lkey, key, sizeof(lkey));
uint8_t enckey1[8];
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") " )");
}
PrintAndLogEx(INFO, "Copy data... " NOLF);
memcpy(data, cc, sizeof(picopass_hdr_t));
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 (IsCardHelperPresent(false) != false){
if (Encrypt(foo, enckey2) == false) {
PrintAndLogEx(WARNING, "failed to encrypt partial 1");
}
memcpy(data + (0x14 * 8), enckey2, sizeof(enckey2));
} 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));
}
// encrypted partial keyroll key 15
PrintAndLogEx(INFO, "Setting encrypted partial key15... " NOLF);
memset(foo, 0xFF, sizeof(foo));
foo[0] = lkey[7];
if (IsCardHelperPresent(false) != false){
if (Encrypt(foo, enckey2) == false) {
PrintAndLogEx(WARNING, "failed to encrypt partial 2");
}
memcpy(data + (0x15 * 8), enckey2, sizeof(enckey2));
} 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));
}
// 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",