mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
clear record file works, lrp transaction check code
This commit is contained in:
parent
09b4c3eed1
commit
db2c8776c0
4 changed files with 67 additions and 14 deletions
|
@ -4314,7 +4314,8 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf mfdes clearrecfile",
|
CLIParserInit(&ctx, "hf mfdes clearrecfile",
|
||||||
"Clear record file. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
"Clear record file. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
|
||||||
"hf mfdes clearrecfile --aid 123456 --fid 01 -> clear record file for: app=123456, file=01 with defaults from `default` command");
|
"hf mfdes clearrecfile --aid 123456 --fid 01 -> clear record file for: app=123456, file=01 with defaults from `default` command\n"
|
||||||
|
"hf mfdes clearrecfile --appisoid df01 --fid 01 -s lrp -t aes -n 3 -> clear record file for lrp channel with key number 3");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
|
@ -4329,6 +4330,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
|
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
|
||||||
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
|
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
|
||||||
arg_str0(NULL, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
|
arg_str0(NULL, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
|
||||||
|
arg_str0(NULL, "appisoid", "<isoid hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
|
||||||
arg_str0(NULL, "fid", "<file id hex>", "File ID for clearing (1 hex byte)"),
|
arg_str0(NULL, "fid", "<file id hex>", "File ID for clearing (1 hex byte)"),
|
||||||
arg_lit0(NULL, "no-auth", "execute without authentication"),
|
arg_lit0(NULL, "no-auth", "execute without authentication"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -4337,19 +4339,20 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
|
|
||||||
bool APDULogging = arg_get_lit(ctx, 1);
|
bool APDULogging = arg_get_lit(ctx, 1);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
bool noauth = arg_get_lit(ctx, 13);
|
bool noauth = arg_get_lit(ctx, 14);
|
||||||
|
|
||||||
DesfireContext dctx;
|
DesfireContext dctx;
|
||||||
int securechann = defaultSecureChannel;
|
int securechann = defaultSecureChannel;
|
||||||
uint32_t appid = 0x000000;
|
uint32_t id = 0x000000;
|
||||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
DesfireISOSelectWay selectway = ISW6bAID;
|
||||||
|
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||||
if (res) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t fnum = 1;
|
uint32_t fnum = 1;
|
||||||
if (CLIGetUint32Hex(ctx, 12, 1, &fnum, NULL, 1, "File ID must have 1 byte length")) {
|
if (CLIGetUint32Hex(ctx, 13, 1, &fnum, NULL, 1, "File ID must have 1 byte length")) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
@ -4362,9 +4365,10 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = DesfireSelectAndAuthenticateEx(&dctx, securechann, appid, noauth, verbose);
|
res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, noauth, verbose);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
DropField();
|
DropField();
|
||||||
|
PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4374,8 +4378,22 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
PrintAndLogEx(INFO, "File cleared");
|
||||||
|
|
||||||
|
DesfireSetCommMode(&dctx, DCMMACed);
|
||||||
|
res = DesfireCommitTransaction(&dctx, false, 0);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(ERR, "Desfire CommitTransaction command " _RED_("error") ". Result: %d", res);
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "File %02x in the app %06x cleared " _GREEN_("successfully"), fnum, appid);
|
if (verbose)
|
||||||
|
PrintAndLogEx(INFO, "Transaction commited");
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, "File %02x in the %s cleared " _GREEN_("successfully"), fnum, DesfireWayIDStr(selectway, id));
|
||||||
|
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -5040,13 +5058,9 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "Prev reader id encoded [%zu]: %s", resplen, sprint_hex(resp, resplen));
|
PrintAndLogEx(INFO, "Prev reader id encoded [%zu]: %s", resplen, sprint_hex(resp, resplen));
|
||||||
|
|
||||||
if (trkeylen > 0) {
|
if (trkeylen > 0) {
|
||||||
uint8_t sessionkey[16] = {0};
|
uint8_t prevReaderID[CRYPTO_AES_BLOCK_SIZE] = {0};
|
||||||
uint8_t uid[7] = {0};
|
DesfireDecodePrevReaderID(&dctx, trkey, transactionCounter, resp, prevReaderID);
|
||||||
memcpy(uid, dctx.uid, MAX(dctx.uidlen, 7));
|
PrintAndLogEx(INFO, "Prev reader id: %s", resplen, sprint_hex(prevReaderID, CRYPTO_AES_BLOCK_SIZE));
|
||||||
DesfireGenTransSessionKeyEV2(trkey, transactionCounter, uid, false, sessionkey);
|
|
||||||
|
|
||||||
aes_decode(NULL, sessionkey, resp, resp, CRYPTO_AES_BLOCK_SIZE);
|
|
||||||
PrintAndLogEx(INFO, "Prev reader id [%zu]: %s", resplen, sprint_hex(resp, resplen));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readeridpushed = true;
|
readeridpushed = true;
|
||||||
|
|
|
@ -667,6 +667,41 @@ void DesfireGenTransSessionKeyEV2(uint8_t *key, uint32_t trCntr, uint8_t *uid, b
|
||||||
DesfireCryptoCMACEx(&ctx, DCOMainKey, xiv, 16, 0, sessionkey);
|
DesfireCryptoCMACEx(&ctx, DCOMainKey, xiv, 16, 0, sessionkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://www.nxp.com/docs/en/data-sheet/MF2DLHX0.pdf
|
||||||
|
// page 43
|
||||||
|
void DesfireGenTransSessionKeyLRP(uint8_t *key, uint32_t trCntr, uint8_t *uid, bool forMAC, uint8_t *sessionkey) {
|
||||||
|
uint8_t data[CRYPTO_AES_BLOCK_SIZE] = {0};
|
||||||
|
|
||||||
|
data[1] = 0x01;
|
||||||
|
data[3] = 0x80;
|
||||||
|
Uint4byteToMemLe(&data[4], trCntr + 0x00010001);
|
||||||
|
memcpy(&data[8], uid, 7);
|
||||||
|
if (forMAC) {
|
||||||
|
data[15] = 0x5a;
|
||||||
|
} else {
|
||||||
|
data[15] = 0xa5;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRPContext lctx = {0};
|
||||||
|
LRPSetKey(&lctx, key, 0, true);
|
||||||
|
LRPCMAC(&lctx, data, sizeof(data), sessionkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesfireDecodePrevReaderID(DesfireContext *ctx, uint8_t *key, uint32_t trCntr, uint8_t *encPrevReaderID, uint8_t *prevReaderID) {
|
||||||
|
uint8_t sessionkey[16] = {0};
|
||||||
|
uint8_t uid[7] = {0};
|
||||||
|
memcpy(uid, ctx->uid, MAX(ctx->uidlen, 7));
|
||||||
|
|
||||||
|
if (ctx->secureChannel == DACEV2) {
|
||||||
|
DesfireGenTransSessionKeyEV2(key, trCntr, uid, false, sessionkey);
|
||||||
|
|
||||||
|
aes_decode(NULL, sessionkey, encPrevReaderID, prevReaderID, CRYPTO_AES_BLOCK_SIZE);
|
||||||
|
} else if (ctx->secureChannel == DACLRP) {
|
||||||
|
DesfireGenTransSessionKeyLRP(key, trCntr, uid, false, sessionkey);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int DesfireLRPCalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac) {
|
int DesfireLRPCalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac) {
|
||||||
uint8_t mdata[1050] = {0};
|
uint8_t mdata[1050] = {0};
|
||||||
size_t mdatalen = 0;
|
size_t mdatalen = 0;
|
||||||
|
|
|
@ -141,7 +141,10 @@ void DesfireGenSessionKeyEV1(const uint8_t rnda[], const uint8_t rndb[], Desfire
|
||||||
void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey);
|
void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey);
|
||||||
void DesfireEV2FillIV(DesfireContext *ctx, bool ivforcommand, uint8_t *iv);
|
void DesfireEV2FillIV(DesfireContext *ctx, bool ivforcommand, uint8_t *iv);
|
||||||
int DesfireEV2CalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac);
|
int DesfireEV2CalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac);
|
||||||
|
|
||||||
void DesfireGenTransSessionKeyEV2(uint8_t *key, uint32_t trCntr, uint8_t *uid, bool forMAC, uint8_t *sessionkey);
|
void DesfireGenTransSessionKeyEV2(uint8_t *key, uint32_t trCntr, uint8_t *uid, bool forMAC, uint8_t *sessionkey);
|
||||||
|
void DesfireGenTransSessionKeyLRP(uint8_t *key, uint32_t trCntr, uint8_t *uid, bool forMAC, uint8_t *sessionkey);
|
||||||
|
void DesfireDecodePrevReaderID(DesfireContext *ctx, uint8_t *key, uint32_t trCntr, uint8_t *encPrevReaderID, uint8_t *prevReaderID);
|
||||||
|
|
||||||
int DesfireLRPCalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac);
|
int DesfireLRPCalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac);
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,7 @@ static const AllowedChannelModesS AllowedChannelModes[] = {
|
||||||
{MFDES_GET_ISOFILE_IDS, DACLRP, DCCNative, DCMMACed},
|
{MFDES_GET_ISOFILE_IDS, DACLRP, DCCNative, DCMMACed},
|
||||||
{MFDES_GET_FILE_SETTINGS, DACLRP, DCCNative, DCMMACed},
|
{MFDES_GET_FILE_SETTINGS, DACLRP, DCCNative, DCMMACed},
|
||||||
{MFDES_GET_KEY_VERSION, DACLRP, DCCNative, DCMMACed},
|
{MFDES_GET_KEY_VERSION, DACLRP, DCCNative, DCMMACed},
|
||||||
|
{MFDES_CLEAR_RECORD_FILE, DACLRP, DCCNative, DCMMACed},
|
||||||
|
|
||||||
{MFDES_GET_UID, DACLRP, DCCNative, DCMEncrypted},
|
{MFDES_GET_UID, DACLRP, DCCNative, DCMEncrypted},
|
||||||
{MFDES_CHANGE_FILE_SETTINGS, DACLRP, DCCNative, DCMEncrypted},
|
{MFDES_CHANGE_FILE_SETTINGS, DACLRP, DCCNative, DCMEncrypted},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue