Merge pull request #1460 from merlokk/desf_lrp

Desfire lrp select/authentication
This commit is contained in:
Oleg Moiseenko 2021-08-19 13:17:35 +03:00 committed by GitHub
commit 89b53f3e6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 456 additions and 166 deletions

View file

@ -776,41 +776,10 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
*dataoutlen = 0;
if (activateField) {
PacketResponseNG resp;
responseNum = 0;
// Anticollision + SELECT card
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout.");
return 1;
}
// check result
if (resp.oldarg[0] == 0) {
if (!silentMode) PrintAndLogEx(ERR, "No card in field.");
return 1;
}
if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) {
if (!silentMode) PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]);
return 1;
}
if (resp.oldarg[0] == 2) { // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
// get ATS
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, sizeof(rats));
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout.");
return 1;
}
if (resp.oldarg[0] == 0) { // ats_len
if (!silentMode) PrintAndLogEx(ERR, "Can't get ATS.");
return 1;
}
}
// select with no disconnect and set g_frame_len
int selres = SelectCard14443A_4(false, !silentMode, NULL);
if (selres != PM3_SUCCESS)
return selres;
}
if (leaveSignalON)

View file

@ -385,9 +385,11 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct
uint8_t kdfid, uint8_t kdfiid,
uint8_t cmodeid, uint8_t ccsetid, uint8_t schannid,
uint8_t appid,
uint8_t appisoid,
int *securechannel,
DesfireCommunicationMode defcommmode,
uint32_t *aid) {
uint32_t *id,
DesfireISOSelectWay *selectway) {
uint8_t keynum = defaultKeyNum;
int algores = defaultAlgoId;
@ -457,10 +459,25 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct
return PM3_ESOFT;
}
if (appid && aid) {
*aid = 0x000000;
if (CLIGetUint32Hex(ctx, appid, 0x000000, aid, NULL, 3, "AID must have 3 bytes length"))
if (appid && id) {
*id = 0x000000;
if (CLIGetUint32Hex(ctx, appid, 0x000000, id, NULL, 3, "AID must have 3 bytes length"))
return PM3_EINVARG;
if (selectway)
*selectway = ISW6bAID;
}
if (appisoid && id) {
uint32_t xisoid = 0x0000;
bool isoidpresent = false;
if (CLIGetUint32Hex(ctx, appisoid, 0x0000, &xisoid, &isoidpresent, 2, "Application ISO ID (for EF) must have 2 bytes length"))
return PM3_EINVARG;
if (isoidpresent) {
*id = xisoid & 0xffff;
if (selectway)
*selectway = ISWIsoID;
}
}
DesfireSetKey(dctx, keynum, algores, key);
@ -488,14 +505,14 @@ static int CmdHF14ADesDefault(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 1, 2, 3, 4, 5, 6, 7, 8, 0, &securechann, DCMNone, NULL);
int res = CmdDesGetSessionParameters(ctx, &dctx, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, &securechann, DCMNone, NULL, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -546,12 +563,14 @@ static int CmdHF14ADesInfo(const char *Cmd) {
mfdes_info_res_t info;
int res = mfdes_get_info(&info);
if (res != PM3_SUCCESS) {
DropField();
return res;
}
nxp_cardtype_t cardtype = getCardType(info.versionHW[3], info.versionHW[4]);
if (cardtype == PLUS_EV1) {
PrintAndLogEx(INFO, "Card seems to be MIFARE Plus EV1. Try " _YELLOW_("`hf mfp info`"));
DropField();
return PM3_SUCCESS;
}
@ -605,17 +624,11 @@ static int CmdHF14ADesInfo(const char *Cmd) {
DesfireContext dctx = {0};
dctx.commMode = DCMPlain;
dctx.cmdSet = DCCNative;
res = DesfireSelectAIDHex(&dctx, 0x000000, false, 0);
if (res != PM3_SUCCESS)
res = DesfireAnticollision(false);
if (res != PM3_SUCCESS) {
DropField();
return res;
PICCInfoS PICCInfo = {0};
uint8_t aidbuf[250] = {0};
size_t aidbuflen = 0;
res = DesfireGetAIDList(&dctx, aidbuf, &aidbuflen);
if (res == PM3_SUCCESS) {
PICCInfo.appCount = aidbuflen / 3;
}
if (cardtype == DESFIRE_EV2 ||
@ -639,6 +652,15 @@ static int CmdHF14ADesInfo(const char *Cmd) {
}
}
PICCInfoS PICCInfo = {0};
uint8_t aidbuf[250] = {0};
size_t aidbuflen = 0;
res = DesfireGetAIDList(&dctx, aidbuf, &aidbuflen);
if (res == PM3_SUCCESS) {
PICCInfo.appCount = aidbuflen / 3;
}
if (aidbuflen > 2) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "--- " _CYAN_("AID list"));
@ -1311,7 +1333,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "dict", "<file>", "File with keys dictionary"),
arg_lit0(NULL, "save", "save found key and parameters to defaults"),
@ -1325,7 +1347,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -1567,7 +1589,7 @@ static int CmdHF14aDesMAD(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of issuer info file, (non-standard feature!) (3 hex bytes, big endian)"),
arg_lit0(NULL, "auth", "Authenticate to get info from GetApplicationIDs command (non-standard feature!)"),
arg_param_end
@ -1581,7 +1603,7 @@ static int CmdHF14aDesMAD(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMPlain, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -1696,7 +1718,8 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
"hf mfdes selectapp --mf -> select master file (PICC level)\n"
"hf mfdes selectapp --dfname aid123456 -> select application aid123456 by DF name\n"
"hf mfdes selectapp --isoid 1111 -> select application 1111 by ISO ID\n"
"hf mfdes selectapp --isoid 1111 --fileisoid 2222 -> select application 1111 file 2222 by ISO ID");
"hf mfdes selectapp --isoid 1111 --fileisoid 2222 -> select application 1111 file 2222 by ISO ID\n"
"hf mfdes selectapp --isoid 01df --fileisoid 00ef -> select file 00 on the Desfire Light");
void *argtable[] = {
arg_param_begin,
@ -1709,7 +1732,7 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of application for some parameters (3 hex bytes, big endian)"),
arg_str0(NULL, "dfname", "<df name str>", "Application DF Name (string, max 16 chars). Selects application via ISO SELECT command"),
arg_lit0(NULL, "mf", "Select MF (master file) via ISO channel"),
@ -1725,7 +1748,7 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMPlain, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -1847,7 +1870,7 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 0, 0, 0, 0, 0, 0, 0, 0, 0, &securechann, DCMNone, NULL);
int res = CmdDesGetSessionParameters(ctx, &dctx, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &securechann, DCMNone, NULL, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -1935,8 +1958,9 @@ static int CmdHF14ADesAuth(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of application for some parameters (3 hex bytes, big endian)"),
arg_str0(NULL, "appisoid", "<isoid hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian). Works only for ISO read commands."),
arg_lit0(NULL, "save", "saves channels parameters to defaults if authentication succeeds"),
arg_param_end
};
@ -1947,29 +1971,30 @@ static int CmdHF14ADesAuth(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid);
uint32_t id = 0x000000;
DesfireISOSelectWay selectway = ISW6bAID;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMPlain, &id, &selectway);
if (res) {
CLIParserFree(ctx);
return res;
}
bool save = arg_get_lit(ctx, 12);
bool save = arg_get_lit(ctx, 13);
SetAPDULogging(APDULogging);
CLIParserFree(ctx);
res = DesfireSelectAndAuthenticateEx(&dctx, securechann, appid, false, verbose);
res = DesfireSelectAndAuthenticateW(&dctx, securechann, selectway, id, false, 0, false, verbose);
if (res != PM3_SUCCESS) {
DropField();
PrintAndLogEx(FAILED, "Select or authentication 0x%06x " _RED_("failed") ". Result [%d] %s", appid, res, DesfireAuthErrorToStr(res));
PrintAndLogEx(FAILED, "Select or authentication %s 0x%06x " _RED_("failed") ". Result [%d] %s", DesfireSelectWayToStr(selectway), id, res, DesfireAuthErrorToStr(res));
return res;
}
if (appid == 0x000000)
if (DesfireMFSelected(selectway, id))
PrintAndLogEx(SUCCESS, "PICC selected and authenticated " _GREEN_("succesfully"));
else
PrintAndLogEx(SUCCESS, "Application " _CYAN_("%06x") " selected and authenticated " _GREEN_("succesfully"), appid);
PrintAndLogEx(SUCCESS, "Application %s " _CYAN_("%0*x") " selected and authenticated " _GREEN_("succesfully"), DesfireSelectWayToStr(selectway), selectway == ISW6bAID ? 6 : 4, id);
PrintAndLogEx(SUCCESS, _CYAN_("Context: "));
DesfirePrintContext(&dctx);
@ -2001,15 +2026,17 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
"02h ATS update.\n"
"03h SAK update\n"
"04h Secure Messaging Configuration.\n"
"05h Capability data. (here change for LRP in the Desfire Light)\n"
"06h DF Name renaming\n"
"08h File renaming\n"
"09h Value file configuration\n"
"0Ah Failed authentication counter setting\n"
"05h Capability data. (here change for LRP in the Desfire Light [enable 00000000010000000000])\n"
"06h DF Name renaming (one-time)\n"
"08h File renaming (one-time)\n"
"09h Value file configuration (one-time)\n"
"0Ah Failed authentication counter setting [disable 00ffffffff]\n"
"0Bh HW configuration\n"
"\n"
"hf mfdes setconfig --param 03 --data 0428 -> set SAK\n"
"hf mfdes setconfig --param 02 --data 0875778102637264 -> set ATS (first byte - length)");
"hf mfdes setconfig --param 02 --data 0875778102637264 -> set ATS (first byte - length)\n"
"hf mfdes setconfig --appisoid 01df -t aes -s ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light\n"
"hf mfdes setconfig --appisoid 01df -t aes -s ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light");
void *argtable[] = {
arg_param_begin,
@ -2022,8 +2049,9 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of application for some parameters (3 hex bytes, big endian)"),
arg_str0(NULL, "appisoid", "<isoid hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian). Works only for ISO read commands."),
arg_str0("p", "param", "<HEX 1 byte>", "Parameter id (HEX 1 byte)"),
arg_str0("d", "data", "<data HEX>", "Data for parameter (HEX 1..30 bytes)"),
arg_param_end
@ -2035,22 +2063,23 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMEncrypted, &appid);
uint32_t id = 0x000000;
DesfireISOSelectWay selectway = ISW6bAID;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
if (res) {
CLIParserFree(ctx);
return res;
}
uint32_t paramid = 0;
if (CLIGetUint32Hex(ctx, 12, 0, &paramid, NULL, 1, "Parameter ID must have 1 bytes length")) {
if (CLIGetUint32Hex(ctx, 13, 0, &paramid, NULL, 1, "Parameter ID must have 1 bytes length")) {
CLIParserFree(ctx);
return PM3_EINVARG;
}
uint8_t param[250] = {0};
int paramlen = sizeof(param);
CLIGetHexWithReturn(ctx, 13, param, &paramlen);
CLIGetHexWithReturn(ctx, 14, param, &paramlen);
if (paramlen == 0) {
PrintAndLogEx(ERR, "Parameter must have a data.");
CLIParserFree(ctx);
@ -2066,13 +2095,13 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
CLIParserFree(ctx);
if (verbose) {
if (appid == 0x000000)
if (DesfireMFSelected(selectway, id))
PrintAndLogEx(INFO, _CYAN_("PICC") " param ID: 0x%02x param[%d]: %s", paramid, paramlen, sprint_hex(param, paramlen));
else
PrintAndLogEx(INFO, _CYAN_("Application %06x") " param ID: 0x%02x param[%d]: %s", appid, paramid, paramlen, sprint_hex(param, paramlen));
PrintAndLogEx(INFO, _CYAN_("%s %06x") " param ID: 0x%02x param[%d]: %s", DesfireSelectWayToStr(selectway), id, paramid, paramlen, sprint_hex(param, paramlen));
}
res = DesfireSelectAndAuthenticate(&dctx, securechann, appid, verbose);
res = DesfireSelectAndAuthenticateW(&dctx, securechann, selectway, id, false, 0, false, verbose);
if (res != PM3_SUCCESS) {
DropField();
return res;
@ -2112,7 +2141,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of application (3 hex bytes, big endian)"),
arg_str0(NULL, "oldalgo", "<DES/2TDEA/3TDEA/AES>", "Old key crypto algorithm: DES, 2TDEA, 3TDEA, AES"),
arg_str0(NULL, "oldkey", "<old key>", "Old key (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
@ -2130,7 +2159,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMEncrypted, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMEncrypted, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2271,7 +2300,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "rawdata", "<rawdata hex>", "Rawdata that sends to command"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID for create. Mandatory. (3 hex bytes, big endian)"),
arg_str0(NULL, "fid", "<file id hex>", "ISO file ID. Forbidden values: 0000 3F00, 3FFF, FFFF. (2 hex bytes, big endian). If specified - enable iso file id over all the files in the app."),
@ -2290,7 +2319,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2435,7 +2464,7 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of delegated application (3 hex bytes, big endian)"),
arg_param_end
};
@ -2447,7 +2476,7 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2497,7 +2526,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -2507,7 +2536,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, DCMEncrypted, NULL);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, DCMEncrypted, NULL, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2572,7 +2601,7 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID of delegated application (3 hex bytes, big endian)"),
arg_param_end
};
@ -2584,7 +2613,7 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2629,7 +2658,7 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end
};
@ -2642,7 +2671,7 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2690,7 +2719,7 @@ static int CmdHF14ADesChKeySettings(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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("d", "data", "<key settings HEX>", "Key settings (HEX 1 byte)"),
arg_param_end
@ -2703,7 +2732,7 @@ static int CmdHF14ADesChKeySettings(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMEncrypted, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMEncrypted, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2762,7 +2791,7 @@ static int CmdHF14ADesGetKeyVersions(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "keynum", "<key number HEX>", "Key number/count (HEX 1 byte). Default 0x00."),
arg_str0(NULL, "keyset", "<keyset num HEX>", "Keyset number (HEX 1 byte)"),
@ -2776,7 +2805,7 @@ static int CmdHF14ADesGetKeyVersions(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2859,7 +2888,7 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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_param_end
};
@ -2871,7 +2900,7 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -2937,7 +2966,7 @@ static int CmdHF14ADesGetAIDs(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end
};
@ -2949,7 +2978,7 @@ static int CmdHF14ADesGetAIDs(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, DCMMACed, NULL);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, DCMMACed, NULL, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3003,7 +3032,7 @@ static int CmdHF14ADesGetAppNames(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end
};
@ -3015,7 +3044,7 @@ static int CmdHF14ADesGetAppNames(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, DCMMACed, NULL);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, DCMMACed, NULL, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3075,7 +3104,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end
@ -3089,7 +3118,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3144,7 +3173,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end
@ -3158,7 +3187,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3213,7 +3242,7 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte). default: 1"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -3228,7 +3257,7 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3383,7 +3412,7 @@ static int CmdHF14ADesChFileSettings(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "rawdata", "<file settings HEX>", "File settings (HEX > 5 bytes). Have priority over the other settings."),
@ -3405,7 +3434,7 @@ static int CmdHF14ADesChFileSettings(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMEncrypted, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMEncrypted, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3523,7 +3552,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "isofid", "<iso file id hex>", "ISO File ID (2 hex bytes)"),
@ -3551,7 +3580,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3661,7 +3690,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "amode", "<plain/mac/encrypt>", "File access mode: plain/mac/encrypt"),
@ -3688,7 +3717,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3787,7 +3816,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "isofid", "<iso file id hex>", "ISO File ID (2 hex bytes)"),
@ -3815,7 +3844,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -3904,7 +3933,7 @@ static int CmdHF14ADesCreateTrMACFile(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "amode", "<plain/mac/encrypt>", "File access mode: plain/mac/encrypt"),
@ -3929,7 +3958,7 @@ static int CmdHF14ADesCreateTrMACFile(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMEncrypted, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMEncrypted, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -4017,7 +4046,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -4032,7 +4061,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -4090,7 +4119,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0("o", "op", "<get/credit/limcredit/debit/clear>", "Operation: get(default)/credit/limcredit(limited credit)/debit/clear. Operation clear: get-getopt-debit to min value"),
@ -4107,7 +4136,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -4248,7 +4277,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID for clearing (1 hex byte)"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -4263,7 +4292,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -4582,7 +4611,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -4602,7 +4631,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -4661,7 +4690,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
return res;
}
} else {
res = DesfireSelectAndAuthenticateISO(&dctx, securechann, (appid != 0), appid, appisoid, fileisoid, noauth, verbose);
res = DesfireSelectAndAuthenticateISO(&dctx, securechann, (appid != 0), appid, appisoid, true, fileisoid, noauth, verbose);
if (res != PM3_SUCCESS) {
DropField();
return res;
@ -4758,7 +4787,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -4783,7 +4812,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMPlain, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -4872,7 +4901,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
return res;
}
} else {
res = DesfireSelectAndAuthenticateISO(&dctx, securechann, (appid != 0), appid, appisoid, fileisoid, noauth, verbose);
res = DesfireSelectAndAuthenticateISO(&dctx, securechann, (appid != 0), appid, appisoid, true, fileisoid, noauth, verbose);
if (res != PM3_SUCCESS) {
DropField();
return res;
@ -5094,7 +5123,7 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end
@ -5108,7 +5137,7 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -5164,7 +5193,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_lit0(NULL, "no-deep", "not to check authentication commands that avail for any application"),
arg_lit0(NULL, "files", "scan files and print file settings for each application"),
@ -5180,7 +5209,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL, NULL);
if (res) {
CLIParserFree(ctx);
return res;
@ -5229,7 +5258,7 @@ static int CmdHF14ADesDump(const char *Cmd) {
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
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_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end
@ -5243,7 +5272,7 @@ static int CmdHF14ADesDump(const char *Cmd) {
DesfireContext dctx;
int securechann = defaultSecureChannel;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, (noauth) ? DCMPlain : DCMMACed, &appid);
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, &appid, NULL);
if (res) {
CLIParserFree(ctx);
return res;

View file

@ -72,6 +72,7 @@ const CLIParserOption DesfireSecureChannelOpts[] = {
{DACd40, "d40"},
{DACEV1, "ev1"},
{DACEV2, "ev2"},
{DACLRP, "lrp"},
{0, NULL},
};
const size_t DesfireSecureChannelOptsLen = ARRAY_LENGTH(DesfireSecureChannelOpts);
@ -257,6 +258,12 @@ const char *DesfireAuthErrorToStr(int error) {
return "mbedtls_aes_setkey_dec failed";
case 11:
return "Authentication failed. Cannot verify Session Key.";
case 12:
return "Authentication failed. Cannot verify CMAC.";
case 50:
return "PICC returned not an AES answer";
case 51:
return "PICC returned not an LRP answer";
case 100:
return "Can't find auth method for provided channel parameters.";
case 200:
@ -289,6 +296,38 @@ const char *DesfireAuthErrorToStr(int error) {
return "";
}
const char *DesfireSelectWayToStr(DesfireISOSelectWay way) {
switch (way) {
case ISW6bAID:
return "AID";
case ISWMF:
return "MF";
case ISWIsoID:
return "ISO ID";
case ISWDFName:
return "DF Name";
default:
break;
}
return "";
}
bool DesfireMFSelected(DesfireISOSelectWay way, uint32_t id) {
switch (way) {
case ISW6bAID:
return (id == 0x000000);
case ISWMF:
return true;
case ISWIsoID:
return (id == 0x3f00);
case ISWDFName:
return false;
default:
break;
}
return false;
}
uint32_t DesfireAIDByteToUint(uint8_t *data) {
return data[0] + (data[1] << 8) + (data[2] << 16);
}
@ -887,14 +926,25 @@ int DesfireSelectAndAuthenticateEx(DesfireContext *dctx, DesfireSecureChannel se
if (verbose)
PrintAndLogEx(INFO, "Switch to " _CYAN_("native") " for select");
}
int res = DesfireSelectAIDHex(dctx, aid, false, 0);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire select " _RED_("error") ".");
return 200;
int res;
if (aid == 0x000000) {
res = DesfireAnticollision(verbose);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire anticollision " _RED_("error") ".");
return 200;
}
if (verbose)
PrintAndLogEx(INFO, "Anticollision " _GREEN_("ok"));
} else {
res = DesfireSelectAIDHex(dctx, aid, false, 0);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire select " _RED_("error") ".");
return 200;
}
if (verbose)
PrintAndLogEx(INFO, "App %06x " _GREEN_("selected"), aid);
}
if (verbose)
PrintAndLogEx(INFO, "App %06x " _GREEN_("selected"), aid);
if (isosw)
dctx->cmdSet = DCCISO;
@ -921,34 +971,36 @@ int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secu
return DesfireSelectAndAuthenticateEx(dctx, secureChannel, aid, false, verbose);
}
int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, uint16_t isofileid, bool noauth, bool verbose) {
int DesfireSelectAndAuthenticateW(DesfireContext *dctx, DesfireSecureChannel secureChannel, DesfireISOSelectWay way, uint32_t id, bool selectfile, uint16_t isofileid, bool noauth, bool verbose) {
if (verbose)
DesfirePrintContext(dctx);
int res = 0;
if (useaid) {
if (way == ISW6bAID && dctx->cmdSet == DCCISO) {
dctx->cmdSet = DCCNativeISO;
if (verbose)
PrintAndLogEx(INFO, "Select via " _CYAN_("native iso wrapping") " interface");
res = DesfireSelectAIDHex(dctx, aid, false, 0);
res = DesfireSelectAIDHex(dctx, id, false, 0);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire select " _RED_("error") ".");
return 200;
}
if (verbose)
PrintAndLogEx(INFO, "App %06x via native iso channel is " _GREEN_("selected"), aid);
PrintAndLogEx(INFO, "App %06x via native iso channel is " _GREEN_("selected"), id);
dctx->cmdSet = DCCISO;
} else {
res = DesfireSelectEx(dctx, true, ISWIsoID, isoappid, NULL);
res = DesfireSelectEx(dctx, true, way, id, NULL);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire iso application select " _RED_("error") ".");
PrintAndLogEx(ERR, "Desfire %s select " _RED_("error") ".", DesfireSelectWayToStr(way));
return 202;
}
if (verbose)
PrintAndLogEx(INFO, "Application iso id %04x is " _GREEN_("selected"), isoappid);
PrintAndLogEx(INFO, "%s %0*x is " _GREEN_("selected"), DesfireSelectWayToStr(way), way == ISW6bAID ? 6 : 4, id);
}
if (selectfile) {
res = DesfireSelectEx(dctx, false, ISWIsoID, isofileid, NULL);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire iso file select " _RED_("error") ".");
@ -956,7 +1008,7 @@ int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel s
}
if (verbose)
PrintAndLogEx(INFO, "Application iso id %04x file iso id %04x is " _GREEN_("selected"), isoappid, isofileid);
PrintAndLogEx(INFO, "Application %s %04x file iso id %04x is " _GREEN_("selected"), DesfireSelectWayToStr(way), id, isofileid);
}
if (!noauth) {
@ -977,6 +1029,10 @@ int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel s
return PM3_SUCCESS;
}
int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, bool selectfile, uint16_t isofileid, bool noauth, bool verbose) {
return DesfireSelectAndAuthenticateW(dctx, secureChannel, useaid ? ISW6bAID : ISWIsoID, useaid ? aid : isoappid, selectfile, isofileid, noauth, verbose);
}
static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) {
// 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
// 4 different crypto arg1 DES, 3DES, 3K3DES, AES
@ -1160,7 +1216,7 @@ static int DesfireAuthenticateEV2(DesfireContext *dctx, DesfireSecureChannel sec
PrintAndLogEx(INFO, _CYAN_("Auth %s:") " cmd: 0x%02x keynum: 0x%02x key: %s", (firstauth) ? "first" : "non-first", subcommand, dctx->keyNum, sprint_hex(key, 16));
// Let's send our auth command
uint8_t cdata[2] = {dctx->keyNum, 0x00};
uint8_t cdata[] = {dctx->keyNum, 0x00};
int res = DesfireExchangeEx(false, dctx, subcommand, cdata, (firstauth) ? sizeof(cdata) : 1, &respcode, recv_data, &recv_len, false, 0);
if (res != PM3_SUCCESS) {
return 1;
@ -1174,12 +1230,19 @@ static int DesfireAuthenticateEV2(DesfireContext *dctx, DesfireSecureChannel sec
return 3;
}
size_t rdataindx = 0;
if (recv_len != CRYPTO_AES_BLOCK_SIZE) {
return 4;
if (recv_len == CRYPTO_AES_BLOCK_SIZE + 1) {
if (recv_data[0] != 0x00)
return 50;
rdataindx = 1;
} else {
return 4;
}
}
// Part 2
memcpy(encRndB, recv_data, 16);
memcpy(encRndB, &recv_data[rdataindx], 16);
// Part 3
if (aes_decode(IV, key, encRndB, RndB, CRYPTO_AES_BLOCK_SIZE))
@ -1323,6 +1386,138 @@ static int DesfireAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel sec
return PM3_SUCCESS;
}
static int DesfireAuthenticateLRP(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool firstauth, bool verbose) {
// Crypt constants
uint8_t RndA[CRYPTO_AES_BLOCK_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
uint8_t RndB[CRYPTO_AES_BLOCK_SIZE] = {0};
uint8_t both[CRYPTO_AES_BLOCK_SIZE * 2 + 1] = {0}; // ek/dk_keyNo(RndA+RndB')
uint8_t subcommand = firstauth ? MFDES_AUTHENTICATE_EV2F : MFDES_AUTHENTICATE_EV2NF;
uint8_t *key = dctx->key;
size_t recv_len = 0;
uint8_t respcode = 0;
uint8_t recv_data[256] = {0};
if (verbose)
PrintAndLogEx(INFO, _CYAN_("Auth %s:") " cmd: 0x%02x keynum: 0x%02x key: %s", (firstauth) ? "first" : "non-first", subcommand, dctx->keyNum, sprint_hex(key, 16));
// Let's send our auth command
uint8_t cdata[] = {dctx->keyNum, 0x01, 0x02};
int res = DesfireExchangeEx(false, dctx, subcommand, cdata, (firstauth) ? sizeof(cdata) : 1, &respcode, recv_data, &recv_len, false, 0);
if (res != PM3_SUCCESS) {
return 1;
}
if (!recv_len) {
return 2;
}
if (respcode != MFDES_ADDITIONAL_FRAME) {
return 3;
}
if (recv_len != CRYPTO_AES_BLOCK_SIZE + 1) {
return 4;
}
if (recv_data[0] != 0x01)
return 51;
// PICC return RndB in plain
memcpy(RndB, &recv_data[1], 16);
if (g_debugMode > 1) {
PrintAndLogEx(DEBUG, "RndB: %s", sprint_hex(RndB, CRYPTO_AES_BLOCK_SIZE));
}
// cmac(sessionkey, rnda+rndb)
uint8_t sessionkey[32] = {0};
DesfireGenSessionKeyLRP(key, RndA, RndB, false, sessionkey);
uint8_t tmp[CRYPTO_AES_BLOCK_SIZE * 4] = {0};
memcpy(tmp, RndA, CRYPTO_AES_BLOCK_SIZE);
memcpy(tmp + CRYPTO_AES_BLOCK_SIZE, RndB, CRYPTO_AES_BLOCK_SIZE);
uint8_t cmac[CRYPTO_AES_BLOCK_SIZE] = {0};
LRPContext ctx = {0};
LRPSetKey(&ctx, sessionkey, 0, true);
LRPCMAC(&ctx, tmp, 32, cmac);
// response = rnda + cmac(sessionkey, rnda+rndb)
memcpy(both, RndA, CRYPTO_AES_BLOCK_SIZE);
memcpy(both + CRYPTO_AES_BLOCK_SIZE, cmac, CRYPTO_AES_BLOCK_SIZE);
if (g_debugMode > 1) {
PrintAndLogEx(DEBUG, "Both: %s", sprint_hex(tmp, CRYPTO_AES_BLOCK_SIZE * 2));
}
res = DesfireExchangeEx(false, dctx, MFDES_ADDITIONAL_FRAME, both, CRYPTO_AES_BLOCK_SIZE * 2, &respcode, recv_data, &recv_len, false, 0);
if (res != PM3_SUCCESS) {
return 7;
}
if (!recv_len) {
return 8;
}
if (respcode != MFDES_S_OPERATION_OK) {
return 9;
}
// Part 4
uint8_t data[64] = {0};
// clear IV here
DesfireClearIV(dctx);
// check mac
memcpy(tmp, RndB, CRYPTO_AES_BLOCK_SIZE);
memcpy(tmp + CRYPTO_AES_BLOCK_SIZE, RndA, CRYPTO_AES_BLOCK_SIZE);
if (firstauth)
memcpy(tmp + CRYPTO_AES_BLOCK_SIZE * 2, recv_data, CRYPTO_AES_BLOCK_SIZE);
LRPSetKey(&ctx, sessionkey, 0, true);
LRPCMAC(&ctx, tmp, (firstauth) ? CRYPTO_AES_BLOCK_SIZE * 3 : CRYPTO_AES_BLOCK_SIZE * 2, cmac);
uint8_t *recCMAC = &recv_data[(firstauth) ? CRYPTO_AES_BLOCK_SIZE : 0];
if (memcmp(recCMAC, cmac, CRYPTO_AES_BLOCK_SIZE) != 0) {
if (g_debugMode > 1) {
PrintAndLogEx(DEBUG, "Expected cmac : %s", sprint_hex(recCMAC, CRYPTO_AES_BLOCK_SIZE));
PrintAndLogEx(DEBUG, "Generated cmac : %s", sprint_hex(cmac, CRYPTO_AES_BLOCK_SIZE));
}
return 12;
}
// decode data
if (firstauth) {
LRPSetKeyEx(&ctx, sessionkey, dctx->IV, 4 * 2, 1, false);
size_t declen = 0;
LRPDecode(&ctx, recv_data, 16, data, &declen);
memcpy(dctx->IV, ctx.counter, 4);
dctx->cmdCntr = 0;
memcpy(dctx->TI, data, 4);
}
memcpy(dctx->sessionKeyEnc, sessionkey, CRYPTO_AES_BLOCK_SIZE);
memcpy(dctx->sessionKeyMAC, sessionkey, CRYPTO_AES_BLOCK_SIZE);
dctx->secureChannel = secureChannel;
if (verbose) {
if (firstauth) {
PrintAndLogEx(INFO, "TI : %s", sprint_hex(data, 4));
PrintAndLogEx(INFO, "pic : %s", sprint_hex(&data[4], 6));
PrintAndLogEx(INFO, "pcd : %s", sprint_hex(&data[10], 6));
} else {
PrintAndLogEx(INFO, "TI : %s", sprint_hex(dctx->TI, 4));
}
PrintAndLogEx(INFO, "session key ENC: %s", sprint_hex(dctx->sessionKeyEnc, 16));
PrintAndLogEx(INFO, "session key MAC: %s", sprint_hex(dctx->sessionKeyMAC, 16));
}
return PM3_SUCCESS;
}
int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) {
if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) {
MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen);
@ -1349,6 +1544,9 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel
if (secureChannel == DACEV2)
return DesfireAuthenticateEV2(dctx, secureChannel, (DesfireIsAuthenticated(dctx) == false), verbose); // non first auth if there is a working secure channel
if (secureChannel == DACLRP)
return DesfireAuthenticateLRP(dctx, secureChannel, (DesfireIsAuthenticated(dctx) == false), verbose);
return 100;
}
@ -2219,8 +2417,8 @@ void DesfirePrintFileSettingsOneLine(FileSettingsS *fsettings) {
void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail, uint16_t isoid, FileSettingsS *fsettings) {
if (printheader) {
PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings ");
PrintAndLogEx(SUCCESS, "----------------------------------------------------------------------------------------------------------");
PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings ");
PrintAndLogEx(SUCCESS, "------------------------------------------------------------------------------------------------------------");
}
PrintAndLogEx(SUCCESS, " " _GREEN_("%02x") " |" NOLF, id);
if (isoidavail) {
@ -2232,7 +2430,7 @@ void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail
PrintAndLogEx(NORMAL, " |" NOLF);
}
PrintAndLogEx(NORMAL, "0x%02x " _CYAN_("%-13s") " |" NOLF, fsettings->fileType, GetDesfireFileType(fsettings->fileType));
PrintAndLogEx(NORMAL, "0x%02x " _CYAN_("%-15s") " |" NOLF, fsettings->fileType, GetDesfireFileType(fsettings->fileType));
PrintAndLogEx(NORMAL, " %-5s |" NOLF, GetDesfireCommunicationMode(fsettings->fileCommMode));
PrintAndLogEx(NORMAL, "%04x, %-4s %-4s %-4s %-4s |" NOLF,
@ -2728,6 +2926,10 @@ int DesfireGetCardUID(DesfireContext *ctx) {
return PM3_SUCCESS;
}
int DesfireAnticollision(bool verbose) {
return SelectCard14443A_4(false, verbose, NULL);
}
int DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname) {
uint8_t resp[250] = {0};
size_t resplen = 0;

View file

@ -161,6 +161,7 @@ int DesfireExchangeEx(bool activate_field, DesfireContext *ctx, uint8_t cmd, uin
int DesfireReadSignature(DesfireContext *dctx, uint8_t sid, uint8_t *resp, size_t *resplen);
int DesfireAnticollision(bool verbose);
int DesfireSelectAID(DesfireContext *ctx, uint8_t *aid1, uint8_t *aid2);
int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uint32_t aid2);
int DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid);
@ -169,13 +170,16 @@ void DesfirePrintMADAID(uint32_t appid, bool verbose);
int DesfireGetCardUID(DesfireContext *ctx);
const char *DesfireSelectWayToStr(DesfireISOSelectWay way);
bool DesfireMFSelected(DesfireISOSelectWay way, uint32_t id);
int DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname);
int DesfireSelect(DesfireContext *ctx, DesfireISOSelectWay way, uint32_t id, char *dfname);
const char *DesfireAuthErrorToStr(int error);
int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool verbose);
int DesfireSelectAndAuthenticateEx(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool noauth, bool verbose);
int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, uint16_t isofileid, bool noauth, bool verbose);
int DesfireSelectAndAuthenticateW(DesfireContext *dctx, DesfireSecureChannel secureChannel, DesfireISOSelectWay way, uint32_t id, bool selectfile, uint16_t isofileid, bool noauth, bool verbose);
int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, bool selectfile, uint16_t isofileid, bool noauth, bool verbose);
int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose);
void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk *authCmdCheck);
void DesfireCheckAuthCommandsPrint(AuthCommandsChk *authCmdCheck);

View file

@ -31,12 +31,13 @@
#include "crc16.h" // crc16 ccitt
#include "crc32.h"
#include "commonutil.h"
#include "crypto/libpcrypto.h"
void DesfireClearContext(DesfireContext *ctx) {
ctx->keyNum = 0;
ctx->keyType = T_DES;
memset(ctx->key, 0, sizeof(ctx->key));
LRPClearContext(&ctx->lrpCtx);
ctx->secureChannel = DACNone;
ctx->cmdSet = DCCNative;
@ -118,6 +119,9 @@ size_t DesfireGetMACLength(DesfireContext *ctx) {
case DACEV2:
mac_length = 8;
break;
case DACLRP:
mac_length = 8;
break;
}
return mac_length;
}
@ -257,11 +261,16 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type,
if (key == NULL)
return;
size_t offset = 0;
while (offset < srcdatalen) {
DesfireCryptoEncDecSingleBlock(key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
if (ctx->secureChannel == DACLRP) {
size_t dstlen = 0;
LRPEncDec(key, iv, encode, srcdata, srcdatalen, data, &dstlen);
} else {
size_t offset = 0;
while (offset < srcdatalen) {
DesfireCryptoEncDecSingleBlock(key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
offset += block_size;
offset += block_size;
}
}
if (iv == NULL)
@ -582,6 +591,26 @@ void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool en
memcpy(sessionkey, cmac, CRYPTO_AES_BLOCK_SIZE);
}
// https://www.nxp.com/docs/en/data-sheet/MF2DLHX0.pdf
// page 35
void DesfireGenSessionKeyLRP(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey) {
uint8_t data[64] = {0};
memset(sessionkey, 0, CRYPTO_AES_BLOCK_SIZE);
data[1] = 0x01;
data[3] = 0x80;
memcpy(data + 4, rndA, 8);
bin_xor(data + 6, rndB, 6); // xor rndb 6b
memcpy(data + 12, rndB + 6, 10);
memcpy(data + 22, rndA + 8, 8);
data[30] = 0x96;
data[31] = 0x69;
LRPContext ctx = {0};
LRPSetKey(&ctx, key, 0, true);
LRPCMAC(&ctx, data, 32, sessionkey);
}
void DesfireEV2FillIV(DesfireContext *ctx, bool ivforcommand, uint8_t *iv) {
uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0};

View file

@ -23,6 +23,7 @@
#include "common.h"
#include "crypto/libpcrypto.h"
#include "mifare/lrpcrypto.h"
#define MAX_CRYPTO_BLOCK_SIZE 16
#define DESFIRE_MAX_CRYPTO_BLOCK_SIZE 16
@ -36,7 +37,7 @@ enum DESFIRE_CRYPTOALGO {
T_DES = 0x00,
T_3DES = 0x01, //aka 2K3DES
T_3K3DES = 0x02,
T_AES = 0x03
T_AES = 0x03,
};
typedef enum DESFIRE_CRYPTOALGO DesfireCryptoAlgorythm;
@ -45,7 +46,8 @@ typedef enum {
DACNone,
DACd40,
DACEV1,
DACEV2
DACEV2,
DACLRP,
} DesfireSecureChannel;
typedef enum {
@ -75,6 +77,8 @@ typedef struct DesfireContextS {
DesfireCryptoAlgorythm keyType; // des/2tdea/3tdea/aes
uint8_t key[DESFIRE_MAX_KEY_SIZE];
uint8_t masterKey[DESFIRE_MAX_KEY_SIZE]; // source for kdf
LRPContext lrpCtx;
// KDF finction
uint8_t kdfAlgo;
@ -122,6 +126,8 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen,
void DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac);
void MifareKdfAn10922(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, const uint8_t *data, size_t len);
void DesfireGenSessionKeyLRP(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey);
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);
uint8_t DesfireDESKeyGetVersion(uint8_t *key);

View file

@ -137,6 +137,10 @@ static const AllowedChannelModesS AllowedChannelModes[] = {
{ISO7816_READ_BINARY, DACEV1, DCCISO, DCMMACed},
{ISO7816_READ_RECORDS, DACEV1, DCCISO, DCMMACed},
// LRP channel separately
{MFDES_AUTHENTICATE_EV2F, DACLRP, DCCNative, DCMPlain},
{MFDES_AUTHENTICATE_EV2NF, DACLRP, DCCNative, DCMPlain},
};
#define CMD_HEADER_LEN_ALL 0xffff
@ -387,6 +391,7 @@ void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcda
case DACEV2:
DesfireSecureChannelEncodeEV2(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen);
break;
case DACLRP:
case DACNone:
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;
@ -603,6 +608,7 @@ void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t sr
case DACEV2:
DesfireSecureChannelDecodeEV2(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen);
break;
case DACLRP:
case DACNone:
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;

View file

@ -857,6 +857,28 @@ static bool TestLRPCMAC(void) {
return res;
}
// https://www.nxp.com/docs/en/application-note/AN12343.pdf
// page 49
static bool TestLRPSessionKeys(void) {
bool res = true;
uint8_t key[16] = {0};
uint8_t rnda[] = {0x74, 0xD7, 0xDF, 0x6A, 0x2C, 0xEC, 0x0B, 0x72, 0xB4, 0x12, 0xDE, 0x0D, 0x2B, 0x11, 0x17, 0xE6};
uint8_t rndb[] = {0x56, 0x10, 0x9A, 0x31, 0x97, 0x7C, 0x85, 0x53, 0x19, 0xCD, 0x46, 0x18, 0xC9, 0xD2, 0xAE, 0xD2};
uint8_t sessionkeyres[] = {0x13, 0x2D, 0x7E, 0x6F, 0x35, 0xBA, 0x86, 0x1F, 0x39, 0xB3, 0x72, 0x21, 0x21, 0x4E, 0x25, 0xA5};
uint8_t sessionkey[16] = {0};
DesfireGenSessionKeyLRP(key, rnda, rndb, true, sessionkey);
res = res && (memcmp(sessionkey, sessionkeyres, sizeof(sessionkeyres)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP session keys.. " _GREEN_("passed"));
else
PrintAndLogEx(ERR, "LRP session keys.. " _RED_("fail"));
return res;
}
bool DesfireTest(bool verbose) {
bool res = true;
@ -883,6 +905,7 @@ bool DesfireTest(bool verbose) {
res = res && TestLRPDecode();
res = res && TestLRPSubkeys();
res = res && TestLRPCMAC();
res = res && TestLRPSessionKeys();
PrintAndLogEx(INFO, "---------------------------");
if (res)

View file

@ -192,6 +192,16 @@ void LRPDecode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, si
}
}
void LRPEncDec(uint8_t *key, uint8_t *iv, bool encode, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen) {
LRPContext ctx = {0};
LRPSetKeyEx(&ctx, key, iv, 4 * 2, 0, true);
if (encode)
LRPEncode(&ctx, data, datalen, resp, resplen);
else
LRPDecode(&ctx, data, datalen, resp, resplen);
}
static bool shiftLeftBe(uint8_t *data, size_t length) {
if (length == 0)
return false;
@ -265,3 +275,13 @@ void LRPCMAC(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *cmac) {
LRPEvalLRP(ctx, y, CRYPTO_AES128_KEY_SIZE * 2, true, cmac);
}
void LRPCMAC8(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *cmac) {
uint8_t cmac_tmp[16] = {0};
memset(cmac, 0x00, 8);
LRPCMAC(ctx, data, datalen, cmac_tmp);
for (int i = 0; i < 8; i++)
cmac[i] = cmac_tmp[i * 2 + 1];
}

View file

@ -54,7 +54,9 @@ void LRPEvalLRP(LRPContext *ctx, uint8_t *iv, size_t ivlen, bool final, uint8_t
void LRPIncCounter(uint8_t *ctr, size_t ctrlen);
void LRPEncode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen);
void LRPDecode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen);
void LRPEncDec(uint8_t *key, uint8_t *iv, bool encode, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen);
void LRPGenSubkeys(uint8_t *key, uint8_t *sk1, uint8_t *sk2);
void LRPCMAC(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *cmac);
void LRPCMAC8(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *cmac);
#endif // __LRPCRYPTO_H