mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
Reorder function definitions
Order is roughly: - exported helpers - helpers - read -> create -> delete - exported commands
This commit is contained in:
parent
02e5fb6b1c
commit
82cd44e99f
1 changed files with 210 additions and 211 deletions
|
@ -32,42 +32,6 @@ static const uint8_t DEFAULT_SITE_KEY[] = {
|
|||
0x34, 0x30, 0x2E, 0xB2, 0x99, 0xAA, 0xB4, 0x56,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Reverses the bytes in AID. Used when parsing CLI args
|
||||
* (because Proxmark displays AIDs in reverse byte order).
|
||||
*/
|
||||
static void reverse_aid(uint8_t *aid) {
|
||||
uint8_t tmp = aid[0];
|
||||
aid[0] = aid[2];
|
||||
aid[2] = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts a Card Application Directory format application ID to an integer.
|
||||
* Note that the CAD stores AIDs in reverse order, so this function is different to DesfireAIDByteToUint().
|
||||
*/
|
||||
static uint32_t cad_aid_byte_to_uint(uint8_t *data) {
|
||||
return data[2] + (data[1] << 8) + (data[0] << 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts an integer application ID to Card Application Directory format.
|
||||
* Note that the CAD stores AIDs in reverse order, so this function is different to DesfireAIDUintToByte().
|
||||
*/
|
||||
static void cad_aid_uint_to_byte(uint32_t aid, uint8_t *data) {
|
||||
data[2] = aid & 0xff;
|
||||
data[1] = (aid >> 8) & 0xff;
|
||||
data[0] = (aid >> 16) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the Card Application Directory entry
|
||||
* is for the specified region & facility, false otherwise.
|
||||
*/
|
||||
static bool cad_facility_match(uint8_t *entry, uint8_t region_code, uint16_t facility_code) {
|
||||
return entry[0] == region_code && (entry[1] << 8) + entry[2] == facility_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create Gallagher Application Master Key by diversifying
|
||||
* the MIFARE Site Key with card UID, key number, and application ID.
|
||||
|
@ -104,6 +68,42 @@ int hfgal_diversify_key(uint8_t *site_key, uint8_t *uid, uint8_t uid_len,
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reverses the bytes in AID. Used when parsing CLI args
|
||||
* (because Proxmark displays AIDs in reverse byte order).
|
||||
*/
|
||||
static void reverse_aid(uint8_t *aid) {
|
||||
uint8_t tmp = aid[0];
|
||||
aid[0] = aid[2];
|
||||
aid[2] = tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts a Card Application Directory format application ID to an integer.
|
||||
* Note that the CAD stores AIDs in reverse order, so this function is different to DesfireAIDByteToUint().
|
||||
*/
|
||||
static uint32_t cad_aid_byte_to_uint(uint8_t *data) {
|
||||
return data[2] + (data[1] << 8) + (data[0] << 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts an integer application ID to Card Application Directory format.
|
||||
* Note that the CAD stores AIDs in reverse order, so this function is different to DesfireAIDUintToByte().
|
||||
*/
|
||||
static void cad_aid_uint_to_byte(uint32_t aid, uint8_t *data) {
|
||||
data[2] = aid & 0xff;
|
||||
data[1] = (aid >> 8) & 0xff;
|
||||
data[0] = (aid >> 16) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the Card Application Directory entry
|
||||
* is for the specified region & facility, false otherwise.
|
||||
*/
|
||||
static bool cad_facility_match(uint8_t *entry, uint8_t region_code, uint16_t facility_code) {
|
||||
return entry[0] == region_code && (entry[1] << 8) + entry[2] == facility_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select application ID.
|
||||
*/
|
||||
|
@ -195,51 +195,25 @@ static uint32_t find_available_gallagher_aid(DesfireContext_t *ctx, bool verbose
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Read Gallagher Card Application Directory from card.
|
||||
* @brief Delete the CAD or an application that contains cardholder credentials.
|
||||
*
|
||||
* @param dest_buf Buffer to copy Card Application Directory into.
|
||||
* @param dest_buf_len Size of dest_buf. Must be at least 108 bytes.
|
||||
* @param num_entries Will be set to the number of entries in the Card Application Directory.
|
||||
* @param site_key MIFARE site key.
|
||||
* @param aid Application ID to remove.
|
||||
*/
|
||||
static int hfgal_read_cad(DesfireContext_t *ctx, uint8_t *dest_buf,
|
||||
uint8_t dest_buf_len, uint8_t *num_entries, bool verbose) {
|
||||
if (dest_buf_len < 3 * 36) {
|
||||
PrintAndLogEx(ERR, "hfgal_read_cad destination buffer is incorrectly sized. "
|
||||
"Received length %d, must be at least %d", dest_buf_len, 3 * 36);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
static int hfgal_delete_app(DesfireContext_t *ctx, uint8_t *site_key,
|
||||
uint32_t aid, bool verbose) {
|
||||
// Select application & authenticate
|
||||
DesfireSetKeyNoClear(ctx, 0, T_AES, site_key);
|
||||
DesfireSetKdf(ctx, MFDES_KDF_ALGO_GALLAGHER, NULL, 0);
|
||||
int res = select_aid_and_authenticate(ctx, aid, verbose);
|
||||
HFGAL_RET_IF_ERR(res);
|
||||
|
||||
// Get card AIDs from Card Application Directory (which contains 1 to 3 files)
|
||||
int res = select_aid(ctx, CAD_AID, verbose);
|
||||
HFGAL_RET_IF_ERR_WITH_MSG(res, "Failed selecting Card Application Directory, does AID %06X exist?", CAD_AID);
|
||||
|
||||
// Read up to 3 files with 6x 6-byte entries each
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
size_t read_len;
|
||||
res = DesfireReadFile(ctx, i, 0, 36, &dest_buf[i * 36], &read_len);
|
||||
if (res != PM3_SUCCESS && res != PM3_EAPDU_FAIL)
|
||||
HFGAL_RET_ERR(res, "Failed reading file %d in Card Application Directory (AID %06X)", i, CAD_AID);
|
||||
|
||||
// end if the last entry is NULL
|
||||
if (memcmp(&dest_buf[36 * i + 30], "\0\0\0\0\0\0", 6) == 0) break;
|
||||
}
|
||||
|
||||
// Count number of entries (i.e. count until we hit a NULL entry)
|
||||
*num_entries = 0;
|
||||
for (uint8_t i = 0; i < dest_buf_len; i += 6) {
|
||||
if (memcmp(&dest_buf[i], "\0\0\0\0\0\0", 6) == 0) break;
|
||||
*num_entries += 1;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
// Print what we found
|
||||
PrintAndLogEx(SUCCESS, "Card Application Directory contains:" NOLF);
|
||||
for (int i = 0; i < *num_entries; i++)
|
||||
PrintAndLogEx(NORMAL, "%s %06X" NOLF, (i == 0) ? "" : ",",
|
||||
cad_aid_byte_to_uint(&dest_buf[i * 6 + 3]));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
// Delete application
|
||||
DesfireSetCommMode(ctx, DCMMACed);
|
||||
res = DesfireDeleteApplication(ctx, aid);
|
||||
HFGAL_RET_IF_ERR_WITH_MSG(res, "Failed deleting AID %06X", aid);
|
||||
|
||||
PrintAndLogEx(INFO, "Successfully deleted AID %06X", aid);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -250,7 +224,7 @@ static int hfgal_read_cad(DesfireContext_t *ctx, uint8_t *dest_buf,
|
|||
* @param site_key MIFARE site key.
|
||||
* @param creds Decoded credentials will be stored in this structure.
|
||||
*/
|
||||
static int hfgal_read_app_creds(DesfireContext_t *ctx, uint32_t aid, uint8_t *site_key,
|
||||
static int hfgal_read_creds_app(DesfireContext_t *ctx, uint32_t aid, uint8_t *site_key,
|
||||
GallagherCredentials_t *creds, bool verbose) {
|
||||
// Check that card UID has been set
|
||||
if (ctx->uidlen == 0)
|
||||
|
@ -287,137 +261,6 @@ static int hfgal_read_app_creds(DesfireContext_t *ctx, uint32_t aid, uint8_t *si
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read credentials from a Gallagher card.
|
||||
*
|
||||
* @param aid Application ID to read. If 0, then the Card Application Directory will be queried and all entries will be read.
|
||||
* @param site_key MIFARE site key.
|
||||
* @param quiet Suppress error messages. Used when in continuous reader mode.
|
||||
*/
|
||||
static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool quiet) {
|
||||
DropField();
|
||||
clearCommandBuffer();
|
||||
|
||||
// Set up context
|
||||
DesfireContext_t dctx = {0};
|
||||
DesfireClearContext(&dctx);
|
||||
|
||||
// Get card UID (for key diversification)
|
||||
int res = DesfireGetCardUID(&dctx);
|
||||
HFGAL_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed retrieving card UID");
|
||||
|
||||
// Find AIDs to process (from CLI args or the Card Application Directory)
|
||||
uint8_t cad[36 * 3] = {0};
|
||||
uint8_t num_entries = 0;
|
||||
if (aid != 0) {
|
||||
cad_aid_uint_to_byte(aid, &cad[3]);
|
||||
num_entries = 1;
|
||||
} else {
|
||||
res = hfgal_read_cad(&dctx, cad, ARRAYLEN(cad), &num_entries, verbose);
|
||||
HFGAL_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading Card Application Directory");
|
||||
}
|
||||
|
||||
// Loop through each application in the CAD
|
||||
for (uint8_t i = 0; i < num_entries * 6; i += 6) {
|
||||
uint16_t region_code = cad[i + 0];
|
||||
uint16_t facility_code = (cad[i + 1] << 8) + cad[i + 2];
|
||||
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: %06X, region: %u, facility: %u", current_aid, region_code, facility_code);
|
||||
else
|
||||
PrintAndLogEx(INFO, "Reading AID: %06X", current_aid);
|
||||
}
|
||||
|
||||
// Read & decode credentials
|
||||
GallagherCredentials_t creds = {0};
|
||||
res = hfgal_read_app_creds(&dctx, current_aid, site_key, &creds, verbose);
|
||||
HFGAL_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading card application credentials");
|
||||
|
||||
PrintAndLogEx(SUCCESS, "GALLAGHER (AID %06X) - Region: " _GREEN_("%u") ", Facility: " _GREEN_("%u")
|
||||
", Card No.: " _GREEN_("%u") ", Issue Level: " _GREEN_("%u"), current_aid,
|
||||
creds.region_code, creds.facility_code, creds.card_number, creds.issue_level);
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdGallagherReader(const char *cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf gallagher reader",
|
||||
"Read a GALLAGHER tag",
|
||||
"hf gallagher reader --aid 2081f4 --sitekey 00112233445566778899aabbccddeeff"
|
||||
" -> act as a reader that skips reading the Card Application Directory and uses a non-default site key\n"
|
||||
"hf gallagher reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID to read (3 bytes)"),
|
||||
arg_str0("k", "sitekey", "<hex>", "Master site key to compute diversified keys (16 bytes) [default=3112B738D8862CCD34302EB299AAB456]"),
|
||||
arg_lit0(NULL, "apdu", "Show APDU requests and responses"),
|
||||
arg_lit0("v", "verbose", "Verbose mode"),
|
||||
arg_lit0("@", "continuous", "Continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
int aid_len = 0;
|
||||
uint8_t aid_buf[3] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, aid_buf, &aid_len);
|
||||
if (aid_len > 0 && aid_len != 3)
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "--aid must be 3 bytes");
|
||||
|
||||
reverse_aid(aid_buf); // PM3 displays AIDs backwards
|
||||
uint32_t aid = DesfireAIDByteToUint(aid_buf);
|
||||
|
||||
int site_key_len = 0;
|
||||
uint8_t site_key[16] = {0};
|
||||
memcpy(site_key, DEFAULT_SITE_KEY, ARRAYLEN(site_key));
|
||||
CLIGetHexWithReturn(ctx, 2, site_key, &site_key_len);
|
||||
if (site_key_len > 0 && site_key_len != 16)
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "--sitekey must be 16 bytes");
|
||||
|
||||
SetAPDULogging(arg_get_lit(ctx, 3));
|
||||
bool verbose = arg_get_lit(ctx, 4);
|
||||
bool continuous_mode = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!continuous_mode)
|
||||
// Read single card
|
||||
return hfgal_read_card(aid, site_key, verbose, false);
|
||||
|
||||
// Loop until <Enter> is pressed
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
while (!kbd_enter_pressed())
|
||||
hfgal_read_card(aid, site_key, verbose, !verbose);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete the CAD or an application that contains cardholder credentials.
|
||||
*
|
||||
* @param site_key MIFARE site key.
|
||||
* @param aid Application ID to remove.
|
||||
*/
|
||||
static int hfgal_delete_app(DesfireContext_t *ctx, uint8_t *site_key,
|
||||
uint32_t aid, bool verbose) {
|
||||
// Select application & authenticate
|
||||
DesfireSetKeyNoClear(ctx, 0, T_AES, site_key);
|
||||
DesfireSetKdf(ctx, MFDES_KDF_ALGO_GALLAGHER, NULL, 0);
|
||||
int res = select_aid_and_authenticate(ctx, aid, verbose);
|
||||
HFGAL_RET_IF_ERR(res);
|
||||
|
||||
// Delete application
|
||||
DesfireSetCommMode(ctx, DCMMACed);
|
||||
res = DesfireDeleteApplication(ctx, aid);
|
||||
HFGAL_RET_IF_ERR_WITH_MSG(res, "Failed deleting AID %06X", aid);
|
||||
|
||||
PrintAndLogEx(INFO, "Successfully deleted AID %06X", aid);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new application to store Gallagher cardholder credentials.
|
||||
*
|
||||
|
@ -535,6 +378,55 @@ static int hfgal_create_creds_file(DesfireContext_t *ctx, uint8_t *site_key, uin
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read Gallagher Card Application Directory from card.
|
||||
*
|
||||
* @param dest_buf Buffer to copy Card Application Directory into.
|
||||
* @param dest_buf_len Size of dest_buf. Must be at least 108 bytes.
|
||||
* @param num_entries Will be set to the number of entries in the Card Application Directory.
|
||||
*/
|
||||
static int hfgal_read_cad(DesfireContext_t *ctx, uint8_t *dest_buf,
|
||||
uint8_t dest_buf_len, uint8_t *num_entries, bool verbose) {
|
||||
if (dest_buf_len < 3 * 36) {
|
||||
PrintAndLogEx(ERR, "hfgal_read_cad destination buffer is incorrectly sized. "
|
||||
"Received length %d, must be at least %d", dest_buf_len, 3 * 36);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
// Get card AIDs from Card Application Directory (which contains 1 to 3 files)
|
||||
int res = select_aid(ctx, CAD_AID, verbose);
|
||||
HFGAL_RET_IF_ERR_WITH_MSG(res, "Failed selecting Card Application Directory, does AID %06X exist?", CAD_AID);
|
||||
|
||||
// Read up to 3 files with 6x 6-byte entries each
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
size_t read_len;
|
||||
res = DesfireReadFile(ctx, i, 0, 36, &dest_buf[i * 36], &read_len);
|
||||
if (res != PM3_SUCCESS && res != PM3_EAPDU_FAIL)
|
||||
HFGAL_RET_ERR(res, "Failed reading file %d in Card Application Directory (AID %06X)", i, CAD_AID);
|
||||
|
||||
// end if the last entry is NULL
|
||||
if (memcmp(&dest_buf[36 * i + 30], "\0\0\0\0\0\0", 6) == 0) break;
|
||||
}
|
||||
|
||||
// Count number of entries (i.e. count until we hit a NULL entry)
|
||||
*num_entries = 0;
|
||||
for (uint8_t i = 0; i < dest_buf_len; i += 6) {
|
||||
if (memcmp(&dest_buf[i], "\0\0\0\0\0\0", 6) == 0) break;
|
||||
*num_entries += 1;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
// Print what we found
|
||||
PrintAndLogEx(SUCCESS, "Card Application Directory contains:" NOLF);
|
||||
for (int i = 0; i < *num_entries; i++)
|
||||
PrintAndLogEx(NORMAL, "%s %06X" NOLF, (i == 0) ? "" : ",",
|
||||
cad_aid_byte_to_uint(&dest_buf[i * 6 + 3]));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create the Gallagher Card Application Directory.
|
||||
*
|
||||
|
@ -698,8 +590,7 @@ static int hfgal_remove_aid_from_cad(DesfireContext_t *ctx, uint8_t *site_key,
|
|||
uint8_t cad[36 * 3] = {0};
|
||||
uint8_t num_entries = 0;
|
||||
|
||||
int res = hfgal_read_cad(
|
||||
ctx, cad, ARRAYLEN(cad), &num_entries, verbose);
|
||||
int res = hfgal_read_cad(ctx, cad, ARRAYLEN(cad), &num_entries, verbose);
|
||||
HFGAL_RET_IF_ERR(res);
|
||||
|
||||
// Check if facility already exists in CAD
|
||||
|
@ -764,6 +655,114 @@ static int hfgal_remove_aid_from_cad(DesfireContext_t *ctx, uint8_t *site_key,
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read credentials from a Gallagher card.
|
||||
*
|
||||
* @param aid Application ID to read. If 0, then the Card Application Directory will be queried and all entries will be read.
|
||||
* @param site_key MIFARE site key.
|
||||
* @param quiet Suppress error messages. Used when in continuous reader mode.
|
||||
*/
|
||||
static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool quiet) {
|
||||
DropField();
|
||||
clearCommandBuffer();
|
||||
|
||||
// Set up context
|
||||
DesfireContext_t dctx = {0};
|
||||
DesfireClearContext(&dctx);
|
||||
|
||||
// Get card UID (for key diversification)
|
||||
int res = DesfireGetCardUID(&dctx);
|
||||
HFGAL_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed retrieving card UID");
|
||||
|
||||
// Find AIDs to process (from CLI args or the Card Application Directory)
|
||||
uint8_t cad[36 * 3] = {0};
|
||||
uint8_t num_entries = 0;
|
||||
if (aid != 0) {
|
||||
cad_aid_uint_to_byte(aid, &cad[3]);
|
||||
num_entries = 1;
|
||||
} else {
|
||||
res = hfgal_read_cad(&dctx, cad, ARRAYLEN(cad), &num_entries, verbose);
|
||||
HFGAL_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading Card Application Directory");
|
||||
}
|
||||
|
||||
// Loop through each application in the CAD
|
||||
for (uint8_t i = 0; i < num_entries * 6; i += 6) {
|
||||
uint16_t region_code = cad[i + 0];
|
||||
uint16_t facility_code = (cad[i + 1] << 8) + cad[i + 2];
|
||||
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: %06X, region: %u, facility: %u", current_aid, region_code, facility_code);
|
||||
else
|
||||
PrintAndLogEx(INFO, "Reading AID: %06X", current_aid);
|
||||
}
|
||||
|
||||
// Read & decode credentials
|
||||
GallagherCredentials_t creds = {0};
|
||||
res = hfgal_read_creds_app(&dctx, current_aid, site_key, &creds, verbose);
|
||||
HFGAL_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading card application credentials");
|
||||
|
||||
PrintAndLogEx(SUCCESS, "GALLAGHER (AID %06X) - Region: " _GREEN_("%u") ", Facility: " _GREEN_("%u")
|
||||
", Card No.: " _GREEN_("%u") ", Issue Level: " _GREEN_("%u"), current_aid,
|
||||
creds.region_code, creds.facility_code, creds.card_number, creds.issue_level);
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdGallagherReader(const char *cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf gallagher reader",
|
||||
"Read a GALLAGHER tag",
|
||||
"hf gallagher reader --aid 2081f4 --sitekey 00112233445566778899aabbccddeeff"
|
||||
" -> act as a reader that skips reading the Card Application Directory and uses a non-default site key\n"
|
||||
"hf gallagher reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID to read (3 bytes)"),
|
||||
arg_str0("k", "sitekey", "<hex>", "Master site key to compute diversified keys (16 bytes) [default=3112B738D8862CCD34302EB299AAB456]"),
|
||||
arg_lit0(NULL, "apdu", "Show APDU requests and responses"),
|
||||
arg_lit0("v", "verbose", "Verbose mode"),
|
||||
arg_lit0("@", "continuous", "Continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||
|
||||
int aid_len = 0;
|
||||
uint8_t aid_buf[3] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, aid_buf, &aid_len);
|
||||
if (aid_len > 0 && aid_len != 3)
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "--aid must be 3 bytes");
|
||||
|
||||
reverse_aid(aid_buf); // PM3 displays AIDs backwards
|
||||
uint32_t aid = DesfireAIDByteToUint(aid_buf);
|
||||
|
||||
int site_key_len = 0;
|
||||
uint8_t site_key[16] = {0};
|
||||
memcpy(site_key, DEFAULT_SITE_KEY, ARRAYLEN(site_key));
|
||||
CLIGetHexWithReturn(ctx, 2, site_key, &site_key_len);
|
||||
if (site_key_len > 0 && site_key_len != 16)
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "--sitekey must be 16 bytes");
|
||||
|
||||
SetAPDULogging(arg_get_lit(ctx, 3));
|
||||
bool verbose = arg_get_lit(ctx, 4);
|
||||
bool continuous_mode = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!continuous_mode)
|
||||
// Read single card
|
||||
return hfgal_read_card(aid, site_key, verbose, false);
|
||||
|
||||
// Loop until <Enter> is pressed
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
while (!kbd_enter_pressed())
|
||||
hfgal_read_card(aid, site_key, verbose, !verbose);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdGallagherClone(const char *cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf gallagher clone",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue