mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-22 23:24:22 +08:00
Automatically choose an new valid Gallagher AID
This commit is contained in:
parent
d3da798517
commit
d7989caad0
1 changed files with 62 additions and 27 deletions
|
@ -138,6 +138,37 @@ static int selectAidAndAuthenticate(DesfireContext_t *ctx, uint32_t aid, bool ve
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the specified application exists, false otherwise.
|
||||
*/
|
||||
static bool aidExists(DesfireContext_t *ctx, uint32_t aid, bool verbose) {
|
||||
// TODO: do these both need to be set?
|
||||
DesfireSetCommMode(ctx, DCMPlain);
|
||||
DesfireSetCommandSet(ctx, DCCNativeISO);
|
||||
|
||||
int res = DesfireSelectAIDHex(ctx, aid, false, 0);
|
||||
if (res != PM3_SUCCESS && res != PM3_EAPDU_FAIL)
|
||||
HFGAL_RET_ERR(false, "Select failed with error %d, assuming AID %06X does not exist", res, aid);
|
||||
|
||||
if (verbose)
|
||||
PrintAndLogEx(INFO, "AID %06X %s", aid, res == PM3_SUCCESS ? "exists" : "does not exist");
|
||||
|
||||
return res == PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the lowest available Gallagher application ID.
|
||||
* @return 0 if no AID is available, or an AID in the range 0x2?81F4, where 0 <= ? <= 0xB.
|
||||
*/
|
||||
static uint32_t findAvailableGallagherAid(DesfireContext_t *ctx, bool verbose) {
|
||||
for (uint8_t i = 0x0; i <= 0xB; i++) {
|
||||
uint32_t aid = 0x2081F4 | (i << 16);
|
||||
if (!aidExists(ctx, aid, verbose))
|
||||
return aid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read Gallagher Card Application Directory from card.
|
||||
*
|
||||
|
@ -278,8 +309,8 @@ static int readCard(uint32_t aid, uint8_t *sitekey, bool verbose, bool quiet) {
|
|||
res = readCardApplicationCredentials(&dctx, currentAid, sitekey, &creds, verbose);
|
||||
HFGAL_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading card application credentials.");
|
||||
|
||||
PrintAndLogEx(SUCCESS, "GALLAGHER - Region: " _GREEN_("%u") ", Facility: " _GREEN_("%u") ", Card No.: " _GREEN_("%u") ", Issue Level: " _GREEN_("%u"),
|
||||
creds.region_code, creds.facility_code, creds.card_number, creds.issue_level);
|
||||
PrintAndLogEx(SUCCESS, "GALLAGHER (AID %06X) - Region: " _GREEN_("%u") ", Facility: " _GREEN_("%u") ", Card No.: " _GREEN_("%u") ", Issue Level: " _GREEN_("%u"),
|
||||
currentAid, creds.region_code, creds.facility_code, creds.card_number, creds.issue_level);
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
|
@ -326,16 +357,14 @@ static int CmdGallagherReader(const char *Cmd) {
|
|||
bool continuousMode = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!continuousMode) {
|
||||
if (!continuousMode)
|
||||
// Read single card
|
||||
return readCard(aid, sitekey, verbose, false);
|
||||
}
|
||||
|
||||
// Loop until <Enter> is pressed
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
while (!kbd_enter_pressed()) {
|
||||
while (!kbd_enter_pressed())
|
||||
readCard(aid, sitekey, verbose, !verbose);
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -524,12 +553,11 @@ static int updateGallagherCAD(DesfireContext_t *ctx, uint8_t *sitekey, uint32_t
|
|||
// Check if CAD exists
|
||||
uint8_t cad[36 * 3] = {0};
|
||||
uint8_t numEntries = 0;
|
||||
int res = selectAid(ctx, CAD_AID, verbose);
|
||||
if (res == PM3_SUCCESS) {
|
||||
if (aidExists(ctx, CAD_AID, verbose)) {
|
||||
if (verbose)
|
||||
PrintAndLogEx(INFO, "Card Application Directory exists, reading entries...");
|
||||
|
||||
res = readCardApplicationDirectory(ctx, cad, ARRAYLEN(cad), &numEntries, verbose);
|
||||
int res = readCardApplicationDirectory(ctx, cad, ARRAYLEN(cad), &numEntries, verbose);
|
||||
HFGAL_RET_IF_ERR(res);
|
||||
|
||||
// Check that there is space for the new entry
|
||||
|
@ -539,7 +567,7 @@ static int updateGallagherCAD(DesfireContext_t *ctx, uint8_t *sitekey, uint32_t
|
|||
if (verbose)
|
||||
PrintAndLogEx(INFO, "Card Application Directory does not exist, creating it now...");
|
||||
|
||||
res = createGallagherCAD(ctx, sitekey, verbose);
|
||||
int res = createGallagherCAD(ctx, sitekey, verbose);
|
||||
HFGAL_RET_IF_ERR(res);
|
||||
}
|
||||
|
||||
|
@ -559,7 +587,7 @@ static int updateGallagherCAD(DesfireContext_t *ctx, uint8_t *sitekey, uint32_t
|
|||
// Select application & authenticate
|
||||
DesfireSetKeyNoClear(ctx, 0, T_AES, sitekey);
|
||||
DesfireSetKdf(ctx, MFDES_KDF_ALGO_GALLAGHER, NULL, 0);
|
||||
res = selectAidAndAuthenticate(ctx, CAD_AID, verbose);
|
||||
int res = selectAidAndAuthenticate(ctx, CAD_AID, verbose);
|
||||
HFGAL_RET_IF_ERR(res);
|
||||
|
||||
// Create file if necessary
|
||||
|
@ -618,14 +646,14 @@ static int CmdGallagherClone(const char *Cmd) {
|
|||
arg_u64_1(NULL, "fc", "<decimal>", "Facility code. 2 bytes max"),
|
||||
arg_u64_1(NULL, "cn", "<decimal>", "Card number. 3 bytes max"),
|
||||
arg_u64_1(NULL, "il", "<decimal>", "Issue level. 4 bits max"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID to write (3 bytes) [default=2081F4]"),
|
||||
arg_str0(NULL, "aid", "<hex>", "Application ID to write (3 bytes) [default finds lowest available in range 0x2?81F4, where 0 <= ? <= 0xB]"),
|
||||
arg_str0(NULL, "sitekey", "<hex>", "Master site key to compute diversified keys (16 bytes) [default=3112B738D8862CCD34302EB299AAB456]"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
SetAPDULogging(arg_get_lit(ctx, 1));
|
||||
bool verbose = arg_get_lit(ctx, 2) || true;
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
int keyNum = arg_get_int_def(ctx, 3, 0);
|
||||
|
||||
int algo = T_DES;
|
||||
|
@ -634,13 +662,11 @@ static int CmdGallagherClone(const char *Cmd) {
|
|||
int keyLen = 0;
|
||||
uint8_t key[DESFIRE_MAX_KEY_SIZE] = {0};
|
||||
CLIGetHexWithReturn(ctx, 5, key, &keyLen);
|
||||
if (keyLen && keyLen != desfire_get_key_length(algo)) {
|
||||
if (keyLen && keyLen != desfire_get_key_length(algo))
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "%s key must have %d bytes length instead of %d", CLIGetOptionListStr(DesfireAlgoOpts, algo), desfire_get_key_length(algo), keyLen);
|
||||
}
|
||||
if (keyLen == 0) {
|
||||
if (keyLen == 0)
|
||||
// Default to a key of all zeros
|
||||
keyLen = desfire_get_key_length(algo);
|
||||
}
|
||||
|
||||
uint64_t region_code = arg_get_u64(ctx, 6); // uint16, will be validated later
|
||||
uint64_t facility_code = arg_get_u64(ctx, 7); // uint32, will be validated later
|
||||
|
@ -648,18 +674,20 @@ static int CmdGallagherClone(const char *Cmd) {
|
|||
uint64_t issue_level = arg_get_u64(ctx, 9); // uint32, will be validated later
|
||||
|
||||
int aidLen = 0;
|
||||
uint8_t aidBuf[3] = "\x20\x81\xF4";
|
||||
uint8_t aidBuf[3] = {0};
|
||||
uint32_t aid = 0;
|
||||
CLIGetHexWithReturn(ctx, 10, aidBuf, &aidLen);
|
||||
if (aidLen > 0 && aidLen != 3) {
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "--aid must be 3 bytes");
|
||||
}
|
||||
reverseAid(aidBuf); // PM3 displays AIDs backwards
|
||||
uint32_t aid = DesfireAIDByteToUint(aidBuf);
|
||||
if (aidLen > 0) {
|
||||
if (aidLen != 3)
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "--aid must be 3 bytes");
|
||||
reverseAid(aidBuf); // PM3 displays AIDs backwards
|
||||
aid = DesfireAIDByteToUint(aidBuf);
|
||||
|
||||
// Check that the AID is in the expected range
|
||||
if (memcmp(aidBuf, "\xF4\x81", 2) != 0 || aidBuf[2] < 0x20 || aidBuf[2] > 0x2B)
|
||||
// TODO: this should probably be a warning, but key diversification will throw an error later even if we don't
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "Invalid Gallagher AID %06X, expected 2?81F4, where 0 <= ? <= 0xB", aid);
|
||||
// Check that the AID is in the expected range
|
||||
if (memcmp(aidBuf, "\xF4\x81", 2) != 0 || aidBuf[2] < 0x20 || aidBuf[2] > 0x2B)
|
||||
// TODO: this should probably be a warning, but key diversification will throw an error later even if we don't
|
||||
HFGAL_RET_ERR(PM3_EINVARG, "Invalid Gallagher AID %06X, expected 2?81F4, where 0 <= ? <= 0xB", aid);
|
||||
}
|
||||
|
||||
int sitekeyLen = 0;
|
||||
uint8_t sitekey[16] = {0};
|
||||
|
@ -688,6 +716,13 @@ static int CmdGallagherClone(const char *Cmd) {
|
|||
int res = DesfireGetCardUID(&dctx);
|
||||
HFGAL_RET_IF_ERR_WITH_MSG(res, "Failed retrieving card UID");
|
||||
|
||||
// Find available Gallagher AID if the user did not specify one
|
||||
if (aidLen == 0) {
|
||||
aid = findAvailableGallagherAid(&dctx, verbose);
|
||||
if (aid == 0)
|
||||
HFGAL_RET_ERR(PM3_EFATAL, "Could not find an available AID, card is full");
|
||||
}
|
||||
|
||||
// Create application
|
||||
DesfireSetKeyNoClear(&dctx, keyNum, algo, key);
|
||||
DesfireSetKdf(&dctx, MFDES_KDF_ALGO_NONE, NULL, 0);
|
||||
|
|
Loading…
Reference in a new issue