From e2fe92ee3df1c3be16bf3ffe45bd4f883d9e7e36 Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 13 May 2022 17:37:11 +1000 Subject: [PATCH 1/3] Fix gallagher desfire kdf for default application card master key --- common/generator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/generator.c b/common/generator.c index 4856327e2..4b23d30ce 100644 --- a/common/generator.c +++ b/common/generator.c @@ -482,8 +482,8 @@ int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint3 } int len = 0; - // If the keyNo == 1, then omit the UID. - if (keyNo != 1) { + // If the keyNo == 1 or the aid is 000000, then omit the UID. + if (keyNo != 1 && aid != 0x000000) { if (*kdfInputLen < (4 + uidLen)) { return PM3_EINVARG; } From c36395f2ccee9ee56c0a5f644e59592607e26a02 Mon Sep 17 00:00:00 2001 From: nvx Date: Wed, 20 Jul 2022 17:47:39 +1000 Subject: [PATCH 2/3] Add hf gallagher decode command --- client/src/cmdhfgallagher.c | 67 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfgallagher.c b/client/src/cmdhfgallagher.c index 0872e8681..ee51464a8 100644 --- a/client/src/cmdhfgallagher.c +++ b/client/src/cmdhfgallagher.c @@ -840,9 +840,10 @@ static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool q uint32_t current_aid = cad_aid_byte_to_uint(&cad[i + 3]); if (verbose) { - if (region_code > 0 || facility_code > 0) { - PrintAndLogEx(INFO, "Reading AID: " _YELLOW_("%06X") ", region: " _YELLOW_("%u") ", facility: " _YELLOW_("%u"), + if (region_code > 0 || facility_code > 0 || current_aid > 0) { + PrintAndLogEx(INFO, "Reading AID: " _YELLOW_("%06X") ", region: " _YELLOW_("%c") " (" _YELLOW_("%u") "), facility: " _YELLOW_("%u"), current_aid, + 'A' + region_code, region_code, facility_code ); @@ -860,11 +861,12 @@ static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool q } PM3_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading card application credentials"); - PrintAndLogEx(SUCCESS, "Gallagher (AID %06X) - region: " _GREEN_("%u") + PrintAndLogEx(SUCCESS, "Gallagher (AID %06X) - region: " _GREEN_("%c") " (" _GREEN_("%u") ")" ", facility: " _GREEN_("%u") ", card number: " _GREEN_("%u") ", issue level: " _GREEN_("%u"), current_aid, + 'A' + creds.region_code, creds.region_code, creds.facility_code, creds.card_number, @@ -1252,12 +1254,71 @@ static int CmdGallagherDiversify(const char *cmd) { return PM3_SUCCESS; } +static int CmdGallagherDecode(const char *cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf gallagher decode", + "Decode Gallagher credential block\n" + "Credential block can be specified with or without the bitwise inverse.", + "hf gallagher decode --data A3B4B0C151B0A31B" + ); + + void *argtable[] = { + arg_param_begin, + arg_str1(NULL, "data", "", "Credential block (8 or 16 bytes)"), + arg_param_end + }; + CLIExecWithReturn(ctx, cmd, argtable, false); + + int data_len = 0; + uint8_t data_buf[16] = {0}; + CLIGetHexWithReturn(ctx, 1, data_buf, &data_len); + if (data_len != 8 && data_len != 16) { + PM3_RET_ERR_FREE(PM3_EINVARG, "--data must be 8 or 16 bytes"); + } + CLIParserFree(ctx); + + if (data_len == 16) { + // Check second half of file is the bitwise inverse of the first half + for (uint8_t i = 8; i < 16; i++) { + data_buf[i] ^= 0xFF; + } + + if (memcmp(data_buf, &data_buf[8], 8) != 0) { + PM3_RET_ERR(PM3_EFAILED, "Invalid cardholder data, last 8 bytes should be bitwise inverse of first 16 bytes. Received %s", + sprint_hex_inrow(data_buf, 16) + ); + } + } else { + for (uint8_t i = 0; i < 8; i++) { + data_buf[i + 8] = data_buf[i] ^ 0xFF; + } + PrintAndLogEx(INFO, "Full credential block with bitwise inverse: " _YELLOW_("%s"), sprint_hex_inrow(data_buf, 16)); + } + + GallagherCredentials_t creds = {0}; + gallagher_decode_creds(data_buf, &creds); + + PrintAndLogEx(SUCCESS, "Gallagher - region: " _GREEN_("%c") " (" _GREEN_("%u") ")" + ", facility: " _GREEN_("%u") + ", card number: " _GREEN_("%u") + ", issue level: " _GREEN_("%u"), + 'A' + creds.region_code, + creds.region_code, + creds.facility_code, + creds.card_number, + creds.issue_level + ); + + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"reader", CmdGallagherReader, IfPm3Iso14443, "Read & decode all Gallagher credentials on a DESFire card"}, {"clone", CmdGallagherClone, IfPm3Iso14443, "Add Gallagher credentials to a DESFire card"}, {"delete", CmdGallagherDelete, IfPm3Iso14443, "Delete Gallagher credentials from a DESFire card"}, {"diversifykey", CmdGallagherDiversify, AlwaysAvailable, "Diversify Gallagher key"}, + {"decode", CmdGallagherDecode, AlwaysAvailable, "Decode Gallagher credential block"}, {NULL, NULL, NULL, NULL} }; From 503ca0641cf39525f70f67d161a7e0a6aeb7748d Mon Sep 17 00:00:00 2001 From: nvx Date: Wed, 20 Jul 2022 18:14:00 +1000 Subject: [PATCH 3/3] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3d91adf..9757a2952 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx) - Added mmbit-002 (kibi-002, kb5004xk1) russian tag to `hf texkom read` command (@merlokk) - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) - Added `hf fudan` skeleton commands (@iceman1001)