mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Feedback from Iceman.
Now respecting quiet flag for continuous reads. Return Correct PM3 _* return codes.
This commit is contained in:
+16
-20
@@ -39,9 +39,9 @@
|
||||
static int CmdHelp(const char *cmd);
|
||||
|
||||
// Application ID for the Gallagher Card Application Directory
|
||||
static const uint32_t DESFIRE_CAD_AID = 0x2F81F4;
|
||||
static const uint32_t CLASSIC_CAD_AID = 0x4811;
|
||||
static const uint16_t CLASSIC_CRED_AID = 0x4812;
|
||||
#define DESFIRE_CAD_AID 0x2F81F4
|
||||
#define CLASSIC_CAD_AID 0x4811
|
||||
#define CLASSIC_CRED_AID 0x4812
|
||||
|
||||
// Default MIFARE site key (16 bytes)
|
||||
static const uint8_t DEFAULT_SITE_KEY[] = {
|
||||
@@ -887,14 +887,14 @@ static int hfgal_read_desfire_card(uint32_t aid, uint8_t *site_key, bool verbose
|
||||
|
||||
|
||||
// Gallagher MIFARE Classic fixed keys
|
||||
static const uint8_t GALLAGHER_MFC_KEY_A[MIFARE_KEY_SIZE] = {0x16, 0x0A, 0x91, 0xD2, 0x9A, 0x9C};
|
||||
static const uint8_t GALLAGHER_MFC_KEY_B[MIFARE_KEY_SIZE] = {0xB7, 0xBF, 0x0C, 0x13, 0x06, 0x6E};
|
||||
static const uint8_t GALLAGHER_MFC_KEY_A[] = {0x16, 0x0A, 0x91, 0xD2, 0x9A, 0x9C};
|
||||
static const uint8_t GALLAGHER_MFC_KEY_B[] = {0xB7, 0xBF, 0x0C, 0x13, 0x06, 0x6E};
|
||||
|
||||
// Gallagher MIFARE Classic access bits: 0x787788
|
||||
static const uint8_t GALLAGHER_ACCESS_BITS[3] = {0x78, 0x77, 0x88};
|
||||
static const uint8_t GALLAGHER_ACCESS_BITS[] = {0x78, 0x77, 0x88};
|
||||
|
||||
// "www.cardax.com " string for block 1
|
||||
static const uint8_t CARDAX_STRING[MFBLOCK_SIZE] = {
|
||||
static const uint8_t CARDAX_STRING[] = {
|
||||
0x77, 0x77, 0x77, 0x2E, 0x63, 0x61, 0x72, 0x64,
|
||||
0x61, 0x78, 0x2E, 0x63, 0x6F, 0x6D, 0x20, 0x20
|
||||
};
|
||||
@@ -1180,8 +1180,10 @@ static int hfgal_read_classic_card(uint8_t *site_key, bool verbose, bool quiet)
|
||||
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
|
||||
PrintAndLogEx(DEBUG, "iso14443a card select timeout");
|
||||
return 0;
|
||||
if (!quiet) {
|
||||
PrintAndLogEx(DEBUG, "iso14443a card select timeout");
|
||||
}
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
iso14a_card_select_t card;
|
||||
@@ -1196,23 +1198,17 @@ static int hfgal_read_classic_card(uint8_t *site_key, bool verbose, bool quiet)
|
||||
uint64_t select_status = resp.oldarg[0];
|
||||
|
||||
if (select_status == 0) {
|
||||
PrintAndLogEx(DEBUG, "iso14443a card select failed");
|
||||
if (!quiet) {
|
||||
PrintAndLogEx(DEBUG, "iso14443a card select failed");
|
||||
}
|
||||
return select_status;
|
||||
}
|
||||
|
||||
// card.uid, card.uidlen
|
||||
|
||||
// Read MAD
|
||||
|
||||
// Read CAD
|
||||
|
||||
// Check credential count
|
||||
|
||||
// Read credentials
|
||||
// Brute Force reading all blocks and printing credentials,
|
||||
for (uint8_t i = 0; i < MIFARE_1K_MAXSECTOR; i++) {
|
||||
hfgal_read_site_specific_sector(i, creds, card.uid, site_key, true);
|
||||
}
|
||||
return PM3_ENOTIMPL;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdGallagherReader(const char *cmd) {
|
||||
|
||||
@@ -74,7 +74,7 @@ static void descramble(uint8_t *arr, uint8_t len) {
|
||||
int gallagher_diversify_classic_key(uint8_t *site_key, uint8_t *csn, size_t csn_len, uint8_t *key_output) {
|
||||
memcpy(key_output, site_key, 16);
|
||||
for (int i = 0; i < csn_len; i++) {
|
||||
key_output[i] = site_key[i] ^ csn[i];
|
||||
key_output[i] ^= csn[i];
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ int gallagher_construct_credential(GallagherCredentials_t *creds, uint8_t region
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int gallagher_read_cad(uint8_t *cad, uint8_t region, uint16_t facility) {
|
||||
int gallagher_parse_cad(uint8_t *cad, uint8_t region, uint16_t facility) {
|
||||
// CAD entries are 3.5 bytes each (28 bits: 4-bit RC, 16-bit FC, 8-bit sector).
|
||||
// Packed in pairs of 7 bytes starting at byte 4, up to 6 pairs (12 entries).
|
||||
for (int pair = 0; pair < 6; pair++) {
|
||||
@@ -155,6 +155,12 @@ void gallagher_encode_creds(uint8_t *eight_bytes, GallagherCredentials_t *creds)
|
||||
}
|
||||
|
||||
int gallagher_encode_mes(uint8_t *sixteen_bytes, GallagherCredentials_t *creds) {
|
||||
|
||||
if (creds->csn_len > 4) {
|
||||
PrintAndLogEx(ERR, "Credential could not be encoded into a Mifare Enhanced Encryption block. only 4 byte UUID's are supported");
|
||||
return PM3_ENOTIMPL;
|
||||
}
|
||||
|
||||
// unknown parameters from the research these might be for UUID's longer than 4 bytes?
|
||||
uint8_t UB = 0x00;
|
||||
uint8_t UC = 0x00;
|
||||
@@ -167,11 +173,6 @@ int gallagher_encode_mes(uint8_t *sixteen_bytes, GallagherCredentials_t *creds)
|
||||
uint8_t mes[16];
|
||||
uint8_t diversified_site_key[16];
|
||||
|
||||
if (creds->csn_len > 4) {
|
||||
PrintAndLogEx(ERR, "Credential could not be encoded into a Mifare Enhanced Encryption block. only 4 byte UUID's are supported");
|
||||
return PM3_ENOTIMPL;
|
||||
}
|
||||
|
||||
mes[0] = 0x01;
|
||||
mes[1] = (creds->card_number & 0xFF0000) >> 16;
|
||||
mes[2] = (creds->card_number & 0x00FF00) >> 8;
|
||||
@@ -195,8 +196,13 @@ int gallagher_encode_mes(uint8_t *sixteen_bytes, GallagherCredentials_t *creds)
|
||||
|
||||
mbedtls_aes_context actx;
|
||||
mbedtls_aes_init(&actx);
|
||||
if (mbedtls_aes_setkey_enc(&actx, diversified_site_key, 128) != 0) return PM3_ENOKEY;
|
||||
if (mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_ENCRYPT, mes, sixteen_bytes) != 0) return PM3_ENOKEY;;
|
||||
if (mbedtls_aes_setkey_enc(&actx, diversified_site_key, 128) != 0) {
|
||||
return PM3_ENOKEY;
|
||||
}
|
||||
|
||||
if (mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_ENCRYPT, mes, sixteen_bytes) != 0) {
|
||||
return PM3_ENOKEY;
|
||||
}
|
||||
mbedtls_aes_free(&actx);
|
||||
|
||||
PrintAndLogEx(DEBUG, "MES after encryption %s", sprint_hex_ascii(sixteen_bytes, 16));
|
||||
@@ -223,8 +229,12 @@ int gallagher_decode_mes(uint8_t *block, GallagherCredentials_t *creds) {
|
||||
// AES decrypt 16 bytes
|
||||
mbedtls_aes_context actx;
|
||||
mbedtls_aes_init(&actx);
|
||||
if (mbedtls_aes_setkey_dec(&actx, diversified_site_key, 128) != 0) return PM3_ENOKEY;
|
||||
if (mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_DECRYPT, block, mes) != 0) return PM3_ENOKEY;;
|
||||
if (mbedtls_aes_setkey_dec(&actx, diversified_site_key, 128) != 0) {
|
||||
return PM3_ENOKEY;
|
||||
}
|
||||
if (mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_DECRYPT, block, mes) != 0) {
|
||||
return PM3_ENOKEY;
|
||||
}
|
||||
mbedtls_aes_free(&actx);
|
||||
|
||||
PrintAndLogEx(DEBUG, "MES after decryption %s", sprint_hex_ascii(mes, 16));
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef struct {
|
||||
|
||||
int gallagher_diversify_classic_key(uint8_t *site_key, uint8_t *csn, size_t csn_len, uint8_t *key_output);
|
||||
|
||||
int gallagher_read_cad(uint8_t *cad, uint8_t region, uint16_t facility);
|
||||
int gallagher_parse_cad(uint8_t *cad, uint8_t region, uint16_t facility);
|
||||
|
||||
void gallagher_encode_creds(uint8_t *eight_bytes, GallagherCredentials_t *creds);
|
||||
|
||||
|
||||
@@ -23,21 +23,21 @@ static bool test_CAD(void) {
|
||||
};
|
||||
|
||||
// Entry 0: RC=0xC, FC=0x1337, Sector=0x0F
|
||||
int result = gallagher_read_cad(cad, 0xC, 0x1337);
|
||||
int result = gallagher_parse_cad(cad, 0xC, 0x1337);
|
||||
if (result != 0x0F) {
|
||||
PrintAndLogEx(INFO, "Gallagher CAD test 1 failed: expected sector 0x0F, got 0x%02X", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Entry 1: RC=0xD, FC=0x1338, Sector=0x0D
|
||||
result = gallagher_read_cad(cad, 0xD, 0x1338);
|
||||
result = gallagher_parse_cad(cad, 0xD, 0x1338);
|
||||
if (result != 0x0D) {
|
||||
PrintAndLogEx(INFO, "Gallagher CAD test 2 failed: expected sector 0x0D, got 0x%02X", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Non-existent entry should return -1
|
||||
result = gallagher_read_cad(cad, 0xA, 0x1234);
|
||||
result = gallagher_parse_cad(cad, 0xA, 0x1234);
|
||||
if (result != -1) {
|
||||
PrintAndLogEx(INFO, "Gallagher CAD test 3 failed: expected -1, got %d", result);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user