mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-04-25 12:12:08 +00:00
Merge pull request #3217 from kormax/mfdes-getdelegateappinfo
Implement DESFire delegated app info retrieval
This commit is contained in:
@@ -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 mfdes getdelegateappinfo` command (@kormax)
|
||||
- Added `hf secc info` command to retrieve the Card Recognition Template(@antiklesys)
|
||||
- Added `hf mfdes createdelegateapp` command (@kormax)
|
||||
- Optimized `hf iclass legbrute` throughput: replaced recursive `suc()`/`output()` cipher functions with iterative loops, added 256-entry LUT for the `select()` function eliminating redundant bit arithmetic and halving key lookups per state step, switched successor state to in-place pointer update removing per-call struct copies, added `doMAC_brute()` with byte-wise LSB-first processing and direct output bit packing eliminating all bitstream struct overhead and output reversal calls per key candidate, and replaced per-iteration 64-bit modulo progress check with a countdown counter (@antiklesys)
|
||||
|
||||
@@ -3852,6 +3852,101 @@ static int CmdHF14ADesCreateDelegateApp(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF14ADesGetDelegateAppInfo(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes getdelegateappinfo",
|
||||
"Get delegated application information for DAM slot (GetDelegatedInfo / 0x69).",
|
||||
"By default authentication is performed with PICC key number 0x00.\n"
|
||||
"Use --keyno to pick another key number, or --no-auth to skip authentication.\n"
|
||||
"hf mfdes getdelegateappinfo --damslot 0001 --algo 2TDEA --key 00000000000000000000000000000000\n"
|
||||
"hf mfdes getdelegateappinfo --damslot 0001 --no-auth");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("a", "apdu", "Show APDU requests and responses"),
|
||||
arg_lit0("v", "verbose", "Verbose output"),
|
||||
arg_int0("n", "keyno", "<dec>", "Key number (default: 0 / PICC key)"),
|
||||
arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
|
||||
arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
|
||||
arg_str0(NULL, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
|
||||
arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
|
||||
arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
|
||||
arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
|
||||
arg_str0(NULL, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
|
||||
arg_str0(NULL, "damslot", "<hex>", "DAM slot number (2 hex bytes, little endian on card)"),
|
||||
arg_lit0(NULL, "no-auth", "Execute without authentication"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
bool verbose = arg_get_lit(ctx, 2);
|
||||
bool noauth = arg_get_lit(ctx, 12);
|
||||
|
||||
int keynum = arg_get_int_def(ctx, 3, 0x00);
|
||||
if (keynum < 0 || keynum > 0xFF) {
|
||||
CLIParserFree(ctx);
|
||||
PrintAndLogEx(ERR, "Key number must be in range 0..255");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
DesfireContext_t dctx = {0};
|
||||
int securechann = defaultSecureChannel;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 0, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
dctx.keyNum = keynum & 0xFF;
|
||||
|
||||
uint32_t damslot = 0x0000;
|
||||
bool damslotpresent = false;
|
||||
if (CLIGetUint32Hex(ctx, 11, 0x0000, &damslot, &damslotpresent, 2, "DAM slot number must have 2 bytes length")) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!damslotpresent) {
|
||||
PrintAndLogEx(ERR, "DAM slot number is mandatory");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
res = DesfireSelectAndAuthenticateEx(&dctx, securechann, 0x000000, noauth, verbose);
|
||||
if (res != PM3_SUCCESS) {
|
||||
DropField();
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t resp[16] = {0};
|
||||
size_t resplen = 0;
|
||||
res = DesfireGetDelegatedInfo(&dctx, damslot & 0xffff, resp, &resplen);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Desfire GetDelegatedInfo command " _RED_("error") ". Result: %d", res);
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
PrintAndLogEx(SUCCESS, "received data[%zu]: %s", resplen, sprint_hex(resp, resplen));
|
||||
|
||||
uint16_t quota = MemLeToUint2byte(&resp[1]);
|
||||
uint16_t freeblocks = MemLeToUint2byte(&resp[3]);
|
||||
uint32_t delegatedaid = MemLeToUint3byte(&resp[5]);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "DAM slot 0x%04x", damslot & 0xffff);
|
||||
PrintAndLogEx(SUCCESS, "DAM slot ver 0x%02x", resp[0]);
|
||||
PrintAndLogEx(SUCCESS, "Quota limit 0x%04x (%u blocks)", quota, (unsigned int)quota);
|
||||
PrintAndLogEx(SUCCESS, "Free blocks 0x%04x (%u blocks)", freeblocks, (unsigned int)freeblocks);
|
||||
PrintAndLogEx(SUCCESS, "Delegated AID 0x%06x", delegatedaid);
|
||||
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF14ADesDeleteApp(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfdes deleteapp",
|
||||
@@ -6962,6 +7057,7 @@ static command_t CommandTable[] = {
|
||||
{"bruteaid", CmdHF14ADesBruteApps, IfPm3Iso14443a, "Recover AIDs by bruteforce"},
|
||||
{"createapp", CmdHF14ADesCreateApp, IfPm3Iso14443a, "Create Application"},
|
||||
{"createdelegateapp", CmdHF14ADesCreateDelegateApp, IfPm3Iso14443a, "Create Delegated Application"},
|
||||
{"getdelegateappinfo", CmdHF14ADesGetDelegateAppInfo, IfPm3Iso14443a, "Get Delegated Application info by DAM slot"},
|
||||
{"deleteapp", CmdHF14ADesDeleteApp, IfPm3Iso14443a, "Delete Application"},
|
||||
{"selectapp", CmdHF14ADesSelectApp, IfPm3Iso14443a, "Select Application ID"},
|
||||
{"selectisofid", CmdHF14ADesSelectISOFID, IfPm3Iso14443a, "Select file by ISO ID"},
|
||||
|
||||
@@ -2249,6 +2249,12 @@ int DesfireCreateDelegatedApplication(DesfireContext_t *dctx, uint8_t *appdata,
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int DesfireGetDelegatedInfo(DesfireContext_t *dctx, uint16_t damslot, uint8_t *resp, size_t *resplen) {
|
||||
uint8_t data[2] = {0};
|
||||
Uint2byteToMemLe(data, damslot);
|
||||
return DesfireCommand(dctx, MFDES_GET_DELEGATE_INFO, data, sizeof(data), resp, resplen, 8);
|
||||
}
|
||||
|
||||
int DesfireDeleteApplication(DesfireContext_t *dctx, uint32_t aid) {
|
||||
uint8_t data[3] = {0};
|
||||
DesfireAIDUintToByte(aid, data);
|
||||
|
||||
@@ -210,6 +210,7 @@ void DesfirePrintAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS
|
||||
|
||||
int DesfireCreateApplication(DesfireContext_t *dctx, uint8_t *appdata, size_t appdatalen);
|
||||
int DesfireCreateDelegatedApplication(DesfireContext_t *dctx, uint8_t *appdata, size_t appdatalen, uint8_t *contdata, size_t contdatalen);
|
||||
int DesfireGetDelegatedInfo(DesfireContext_t *dctx, uint16_t damslot, uint8_t *resp, size_t *resplen);
|
||||
int DesfireDeleteApplication(DesfireContext_t *dctx, uint32_t aid);
|
||||
|
||||
int DesfireGetKeyVersion(DesfireContext_t *dctx, uint8_t *data, size_t len, uint8_t *resp, size_t *resplen);
|
||||
|
||||
@@ -68,6 +68,7 @@ static const AllowedChannelModes_t AllowedChannelModes[] = {
|
||||
{MFDES_GET_DF_NAMES, DACd40, DCCNative, DCMMACed},
|
||||
{MFDES_GET_KEY_SETTINGS, DACd40, DCCNative, DCMMACed},
|
||||
{MFDES_GET_KEY_VERSION, DACd40, DCCNative, DCMMACed},
|
||||
{MFDES_GET_DELEGATE_INFO, DACd40, DCCNative, DCMMACed},
|
||||
{MFDES_GET_FREE_MEMORY, DACd40, DCCNative, DCMMACed},
|
||||
{MFDES_CREATE_STD_DATA_FILE, DACd40, DCCNative, DCMMACed},
|
||||
{MFDES_CREATE_BACKUP_DATA_FILE, DACd40, DCCNative, DCMMACed},
|
||||
@@ -107,6 +108,7 @@ static const AllowedChannelModes_t AllowedChannelModes[] = {
|
||||
{MFDES_SELECT_APPLICATION, DACEV1, DCCNative, DCMPlain},
|
||||
|
||||
{MFDES_GET_KEY_VERSION, DACEV1, DCCNative, DCMMACed},
|
||||
{MFDES_GET_DELEGATE_INFO, DACEV1, DCCNative, DCMMACed},
|
||||
{MFDES_GET_FREE_MEMORY, DACEV1, DCCNative, DCMMACed},
|
||||
{MFDES_CREATE_APPLICATION, DACEV1, DCCNative, DCMMACed},
|
||||
{MFDES_CREATE_DELEGATE_APP, DACEV1, DCCNative, DCMMACed},
|
||||
@@ -188,6 +190,7 @@ static const AllowedChannelModes_t AllowedChannelModes[] = {
|
||||
static const CmdHeaderLengths_t CmdHeaderLengths[] = {
|
||||
{MFDES_CREATE_APPLICATION, CMD_HEADER_LEN_ALL},
|
||||
{MFDES_CREATE_DELEGATE_APP, CMD_HEADER_LEN_ALL},
|
||||
{MFDES_GET_DELEGATE_INFO, 2},
|
||||
{MFDES_DELETE_APPLICATION, CMD_HEADER_LEN_ALL},
|
||||
{MFDES_CHANGE_KEY, 1},
|
||||
{MFDES_CHANGE_KEY_EV2, 2},
|
||||
|
||||
@@ -496,6 +496,7 @@ const static vocabulary_t vocabulary[] = {
|
||||
{ 0, "hf mfdes bruteaid" },
|
||||
{ 0, "hf mfdes createapp" },
|
||||
{ 0, "hf mfdes createdelegateapp" },
|
||||
{ 0, "hf mfdes getdelegateappinfo" },
|
||||
{ 0, "hf mfdes deleteapp" },
|
||||
{ 0, "hf mfdes selectapp" },
|
||||
{ 0, "hf mfdes selectisofid" },
|
||||
|
||||
Reference in New Issue
Block a user