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; *dataoutlen = 0;
if (activateField) { if (activateField) {
PacketResponseNG resp; // select with no disconnect and set g_frame_len
responseNum = 0; int selres = SelectCard14443A_4(false, !silentMode, NULL);
if (selres != PM3_SUCCESS)
// Anticollision + SELECT card return selres;
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;
}
}
} }
if (leaveSignalON) if (leaveSignalON)

View file

@ -385,9 +385,11 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct
uint8_t kdfid, uint8_t kdfiid, uint8_t kdfid, uint8_t kdfiid,
uint8_t cmodeid, uint8_t ccsetid, uint8_t schannid, uint8_t cmodeid, uint8_t ccsetid, uint8_t schannid,
uint8_t appid, uint8_t appid,
uint8_t appisoid,
int *securechannel, int *securechannel,
DesfireCommunicationMode defcommmode, DesfireCommunicationMode defcommmode,
uint32_t *aid) { uint32_t *id,
DesfireISOSelectWay *selectway) {
uint8_t keynum = defaultKeyNum; uint8_t keynum = defaultKeyNum;
int algores = defaultAlgoId; int algores = defaultAlgoId;
@ -457,10 +459,25 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct
return PM3_ESOFT; return PM3_ESOFT;
} }
if (appid && aid) { if (appid && id) {
*aid = 0x000000; *id = 0x000000;
if (CLIGetUint32Hex(ctx, appid, 0x000000, aid, NULL, 3, "AID must have 3 bytes length")) if (CLIGetUint32Hex(ctx, appid, 0x000000, id, NULL, 3, "AID must have 3 bytes length"))
return PM3_EINVARG; 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); 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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 arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;
@ -546,12 +563,14 @@ static int CmdHF14ADesInfo(const char *Cmd) {
mfdes_info_res_t info; mfdes_info_res_t info;
int res = mfdes_get_info(&info); int res = mfdes_get_info(&info);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
DropField();
return res; return res;
} }
nxp_cardtype_t cardtype = getCardType(info.versionHW[3], info.versionHW[4]); nxp_cardtype_t cardtype = getCardType(info.versionHW[3], info.versionHW[4]);
if (cardtype == PLUS_EV1) { if (cardtype == PLUS_EV1) {
PrintAndLogEx(INFO, "Card seems to be MIFARE Plus EV1. Try " _YELLOW_("`hf mfp info`")); PrintAndLogEx(INFO, "Card seems to be MIFARE Plus EV1. Try " _YELLOW_("`hf mfp info`"));
DropField();
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -605,17 +624,11 @@ static int CmdHF14ADesInfo(const char *Cmd) {
DesfireContext dctx = {0}; DesfireContext dctx = {0};
dctx.commMode = DCMPlain; dctx.commMode = DCMPlain;
dctx.cmdSet = DCCNative; dctx.cmdSet = DCCNative;
res = DesfireSelectAIDHex(&dctx, 0x000000, false, 0);
if (res != PM3_SUCCESS) res = DesfireAnticollision(false);
if (res != PM3_SUCCESS) {
DropField();
return res; 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 || 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) { if (aidbuflen > 2) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "--- " _CYAN_("AID list")); 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_str0(NULL, "dict", "<file>", "File with keys dictionary"), arg_str0(NULL, "dict", "<file>", "File with keys dictionary"),
arg_lit0(NULL, "save", "save found key and parameters to defaults"), arg_lit0(NULL, "save", "save found key and parameters to defaults"),
@ -1325,7 +1347,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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_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_lit0(NULL, "auth", "Authenticate to get info from GetApplicationIDs command (non-standard feature!)"),
arg_param_end arg_param_end
@ -1581,7 +1603,7 @@ static int CmdHF14aDesMAD(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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 --mf -> select master file (PICC level)\n"
"hf mfdes selectapp --dfname aid123456 -> select application aid123456 by DF name\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 -> 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[] = { void *argtable[] = {
arg_param_begin, 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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_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"), arg_lit0(NULL, "mf", "Select MF (master file) via ISO channel"),
@ -1725,7 +1748,7 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;
@ -1847,7 +1870,7 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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_lit0(NULL, "save", "saves channels parameters to defaults if authentication succeeds"),
arg_param_end arg_param_end
}; };
@ -1947,29 +1971,30 @@ static int CmdHF14ADesAuth(const char *Cmd) {
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, &securechann, DCMPlain, &appid); DesfireISOSelectWay selectway = ISW6bAID;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMPlain, &id, &selectway);
if (res) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;
} }
bool save = arg_get_lit(ctx, 12); bool save = arg_get_lit(ctx, 13);
SetAPDULogging(APDULogging); SetAPDULogging(APDULogging);
CLIParserFree(ctx); CLIParserFree(ctx);
res = DesfireSelectAndAuthenticateEx(&dctx, securechann, appid, false, verbose); res = DesfireSelectAndAuthenticateW(&dctx, securechann, selectway, id, false, 0, false, verbose);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
DropField(); 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; return res;
} }
if (appid == 0x000000) if (DesfireMFSelected(selectway, id))
PrintAndLogEx(SUCCESS, "PICC selected and authenticated " _GREEN_("succesfully")); PrintAndLogEx(SUCCESS, "PICC selected and authenticated " _GREEN_("succesfully"));
else 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: ")); PrintAndLogEx(SUCCESS, _CYAN_("Context: "));
DesfirePrintContext(&dctx); DesfirePrintContext(&dctx);
@ -2001,15 +2026,17 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
"02h ATS update.\n" "02h ATS update.\n"
"03h SAK update\n" "03h SAK update\n"
"04h Secure Messaging Configuration.\n" "04h Secure Messaging Configuration.\n"
"05h Capability data. (here change for LRP in the Desfire Light)\n" "05h Capability data. (here change for LRP in the Desfire Light [enable 00000000010000000000])\n"
"06h DF Name renaming\n" "06h DF Name renaming (one-time)\n"
"08h File renaming\n" "08h File renaming (one-time)\n"
"09h Value file configuration\n" "09h Value file configuration (one-time)\n"
"0Ah Failed authentication counter setting\n" "0Ah Failed authentication counter setting [disable 00ffffffff]\n"
"0Bh HW configuration\n" "0Bh HW configuration\n"
"\n" "\n"
"hf mfdes setconfig --param 03 --data 0428 -> set SAK\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[] = { void *argtable[] = {
arg_param_begin, 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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("p", "param", "<HEX 1 byte>", "Parameter id (HEX 1 byte)"),
arg_str0("d", "data", "<data HEX>", "Data for parameter (HEX 1..30 bytes)"), arg_str0("d", "data", "<data HEX>", "Data for parameter (HEX 1..30 bytes)"),
arg_param_end arg_param_end
@ -2035,22 +2063,23 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
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, &securechann, DCMEncrypted, &appid); DesfireISOSelectWay selectway = ISW6bAID;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMEncrypted, &id, &selectway);
if (res) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;
} }
uint32_t paramid = 0; 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); CLIParserFree(ctx);
return PM3_EINVARG; return PM3_EINVARG;
} }
uint8_t param[250] = {0}; uint8_t param[250] = {0};
int paramlen = sizeof(param); int paramlen = sizeof(param);
CLIGetHexWithReturn(ctx, 13, param, &paramlen); CLIGetHexWithReturn(ctx, 14, param, &paramlen);
if (paramlen == 0) { if (paramlen == 0) {
PrintAndLogEx(ERR, "Parameter must have a data."); PrintAndLogEx(ERR, "Parameter must have a data.");
CLIParserFree(ctx); CLIParserFree(ctx);
@ -2066,13 +2095,13 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) {
CLIParserFree(ctx); CLIParserFree(ctx);
if (verbose) { 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)); PrintAndLogEx(INFO, _CYAN_("PICC") " param ID: 0x%02x param[%d]: %s", paramid, paramlen, sprint_hex(param, paramlen));
else 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) { if (res != PM3_SUCCESS) {
DropField(); DropField();
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "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)"), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "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."), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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_str0(NULL, "aid", "<app id hex>", "Application ID of delegated application (3 hex bytes, big endian)"),
arg_param_end arg_param_end
}; };
@ -2447,7 +2476,7 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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 arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -2507,7 +2536,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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_str0(NULL, "aid", "<app id hex>", "Application ID of delegated application (3 hex bytes, big endian)"),
arg_param_end arg_param_end
}; };
@ -2584,7 +2613,7 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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-auth", "execute without authentication"),
arg_param_end arg_param_end
}; };
@ -2642,7 +2671,7 @@ static int CmdHF14ADesGetFreeMem(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_str0("d", "data", "<key settings HEX>", "Key settings (HEX 1 byte)"), arg_str0("d", "data", "<key settings HEX>", "Key settings (HEX 1 byte)"),
arg_param_end arg_param_end
@ -2703,7 +2732,7 @@ static int CmdHF14ADesChKeySettings(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "keynum", "<key number HEX>", "Key number/count (HEX 1 byte). Default 0x00."),
arg_str0(NULL, "keyset", "<keyset num HEX>", "Keyset number (HEX 1 byte)"), arg_str0(NULL, "keyset", "<keyset num HEX>", "Keyset number (HEX 1 byte)"),
@ -2776,7 +2805,7 @@ static int CmdHF14ADesGetKeyVersions(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_param_end arg_param_end
}; };
@ -2871,7 +2900,7 @@ static int CmdHF14ADesGetKeySettings(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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-auth", "execute without authentication"),
arg_param_end arg_param_end
}; };
@ -2949,7 +2978,7 @@ static int CmdHF14ADesGetAIDs(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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-auth", "execute without authentication"),
arg_param_end arg_param_end
}; };
@ -3015,7 +3044,7 @@ static int CmdHF14ADesGetAppNames(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end arg_param_end
@ -3089,7 +3118,7 @@ static int CmdHF14ADesGetFileIDs(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end arg_param_end
@ -3158,7 +3187,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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_str0(NULL, "fid", "<file id hex>", "File ID (1 hex byte). default: 1"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -3228,7 +3257,7 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "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."), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "isofid", "<iso file id hex>", "ISO File ID (2 hex bytes)"), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "amode", "<plain/mac/encrypt>", "File access mode: plain/mac/encrypt"), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "isofid", "<iso file id hex>", "ISO File ID (2 hex bytes)"), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "amode", "<plain/mac/encrypt>", "File access mode: plain/mac/encrypt"), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -4032,7 +4061,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "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"), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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_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"),
@ -4263,7 +4292,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -4602,7 +4631,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;
@ -4661,7 +4690,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
return res; return res;
} }
} else { } 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) { if (res != PM3_SUCCESS) {
DropField(); DropField();
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "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, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
@ -4783,7 +4812,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;
@ -4872,7 +4901,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
return res; return res;
} }
} else { } 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) { if (res != PM3_SUCCESS) {
DropField(); DropField();
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end arg_param_end
@ -5108,7 +5137,7 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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-auth", "execute without authentication"),
arg_lit0(NULL, "no-deep", "not to check authentication commands that avail for any application"), 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"), 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; DesfireContext dctx;
int securechann = defaultSecureChannel; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; 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("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"), 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("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, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_lit0(NULL, "no-auth", "execute without authentication"), arg_lit0(NULL, "no-auth", "execute without authentication"),
arg_param_end arg_param_end
@ -5243,7 +5272,7 @@ static int CmdHF14ADesDump(const char *Cmd) {
DesfireContext dctx; DesfireContext dctx;
int securechann = defaultSecureChannel; int securechann = defaultSecureChannel;
uint32_t appid = 0x000000; 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) { if (res) {
CLIParserFree(ctx); CLIParserFree(ctx);
return res; return res;

View file

@ -72,6 +72,7 @@ const CLIParserOption DesfireSecureChannelOpts[] = {
{DACd40, "d40"}, {DACd40, "d40"},
{DACEV1, "ev1"}, {DACEV1, "ev1"},
{DACEV2, "ev2"}, {DACEV2, "ev2"},
{DACLRP, "lrp"},
{0, NULL}, {0, NULL},
}; };
const size_t DesfireSecureChannelOptsLen = ARRAY_LENGTH(DesfireSecureChannelOpts); const size_t DesfireSecureChannelOptsLen = ARRAY_LENGTH(DesfireSecureChannelOpts);
@ -257,6 +258,12 @@ const char *DesfireAuthErrorToStr(int error) {
return "mbedtls_aes_setkey_dec failed"; return "mbedtls_aes_setkey_dec failed";
case 11: case 11:
return "Authentication failed. Cannot verify Session Key."; 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: case 100:
return "Can't find auth method for provided channel parameters."; return "Can't find auth method for provided channel parameters.";
case 200: case 200:
@ -289,6 +296,38 @@ const char *DesfireAuthErrorToStr(int error) {
return ""; 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) { uint32_t DesfireAIDByteToUint(uint8_t *data) {
return data[0] + (data[1] << 8) + (data[2] << 16); return data[0] + (data[1] << 8) + (data[2] << 16);
} }
@ -887,14 +926,25 @@ int DesfireSelectAndAuthenticateEx(DesfireContext *dctx, DesfireSecureChannel se
if (verbose) if (verbose)
PrintAndLogEx(INFO, "Switch to " _CYAN_("native") " for select"); PrintAndLogEx(INFO, "Switch to " _CYAN_("native") " for select");
} }
int res = DesfireSelectAIDHex(dctx, aid, false, 0); int res;
if (res != PM3_SUCCESS) { if (aid == 0x000000) {
PrintAndLogEx(ERR, "Desfire select " _RED_("error") "."); res = DesfireAnticollision(verbose);
return 200; 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) if (isosw)
dctx->cmdSet = DCCISO; dctx->cmdSet = DCCISO;
@ -921,34 +971,36 @@ int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secu
return DesfireSelectAndAuthenticateEx(dctx, secureChannel, aid, false, verbose); 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) if (verbose)
DesfirePrintContext(dctx); DesfirePrintContext(dctx);
int res = 0; int res = 0;
if (useaid) { if (way == ISW6bAID && dctx->cmdSet == DCCISO) {
dctx->cmdSet = DCCNativeISO; dctx->cmdSet = DCCNativeISO;
if (verbose) if (verbose)
PrintAndLogEx(INFO, "Select via " _CYAN_("native iso wrapping") " interface"); 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) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire select " _RED_("error") "."); PrintAndLogEx(ERR, "Desfire select " _RED_("error") ".");
return 200; return 200;
} }
if (verbose) 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; dctx->cmdSet = DCCISO;
} else { } else {
res = DesfireSelectEx(dctx, true, ISWIsoID, isoappid, NULL); res = DesfireSelectEx(dctx, true, way, id, NULL);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire iso application select " _RED_("error") "."); PrintAndLogEx(ERR, "Desfire %s select " _RED_("error") ".", DesfireSelectWayToStr(way));
return 202; return 202;
} }
if (verbose) 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); res = DesfireSelectEx(dctx, false, ISWIsoID, isofileid, NULL);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire iso file select " _RED_("error") "."); PrintAndLogEx(ERR, "Desfire iso file select " _RED_("error") ".");
@ -956,7 +1008,7 @@ int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel s
} }
if (verbose) 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) { if (!noauth) {
@ -977,6 +1029,10 @@ int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel s
return PM3_SUCCESS; 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) { static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) {
// 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) // 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
// 4 different crypto arg1 DES, 3DES, 3K3DES, AES // 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)); 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 // 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); int res = DesfireExchangeEx(false, dctx, subcommand, cdata, (firstauth) ? sizeof(cdata) : 1, &respcode, recv_data, &recv_len, false, 0);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
return 1; return 1;
@ -1174,12 +1230,19 @@ static int DesfireAuthenticateEV2(DesfireContext *dctx, DesfireSecureChannel sec
return 3; return 3;
} }
size_t rdataindx = 0;
if (recv_len != CRYPTO_AES_BLOCK_SIZE) { 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 // Part 2
memcpy(encRndB, recv_data, 16); memcpy(encRndB, &recv_data[rdataindx], 16);
// Part 3 // Part 3
if (aes_decode(IV, key, encRndB, RndB, CRYPTO_AES_BLOCK_SIZE)) 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; 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) { int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) {
if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) { if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) {
MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen);
@ -1349,6 +1544,9 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel
if (secureChannel == DACEV2) if (secureChannel == DACEV2)
return DesfireAuthenticateEV2(dctx, secureChannel, (DesfireIsAuthenticated(dctx) == false), verbose); // non first auth if there is a working secure channel 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; return 100;
} }
@ -2219,8 +2417,8 @@ void DesfirePrintFileSettingsOneLine(FileSettingsS *fsettings) {
void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail, uint16_t isoid, FileSettingsS *fsettings) { void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail, uint16_t isoid, FileSettingsS *fsettings) {
if (printheader) { if (printheader) {
PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings "); PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings ");
PrintAndLogEx(SUCCESS, "----------------------------------------------------------------------------------------------------------"); PrintAndLogEx(SUCCESS, "------------------------------------------------------------------------------------------------------------");
} }
PrintAndLogEx(SUCCESS, " " _GREEN_("%02x") " |" NOLF, id); PrintAndLogEx(SUCCESS, " " _GREEN_("%02x") " |" NOLF, id);
if (isoidavail) { if (isoidavail) {
@ -2232,7 +2430,7 @@ void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail
PrintAndLogEx(NORMAL, " |" NOLF); 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, " %-5s |" NOLF, GetDesfireCommunicationMode(fsettings->fileCommMode));
PrintAndLogEx(NORMAL, "%04x, %-4s %-4s %-4s %-4s |" NOLF, PrintAndLogEx(NORMAL, "%04x, %-4s %-4s %-4s %-4s |" NOLF,
@ -2728,6 +2926,10 @@ int DesfireGetCardUID(DesfireContext *ctx) {
return PM3_SUCCESS; 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) { int DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname) {
uint8_t resp[250] = {0}; uint8_t resp[250] = {0};
size_t resplen = 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 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 DesfireSelectAID(DesfireContext *ctx, uint8_t *aid1, uint8_t *aid2);
int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uint32_t aid2); int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uint32_t aid2);
int DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid); int DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid);
@ -169,13 +170,16 @@ void DesfirePrintMADAID(uint32_t appid, bool verbose);
int DesfireGetCardUID(DesfireContext *ctx); 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 DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname);
int DesfireSelect(DesfireContext *ctx, DesfireISOSelectWay way, uint32_t id, char *dfname); int DesfireSelect(DesfireContext *ctx, DesfireISOSelectWay way, uint32_t id, char *dfname);
const char *DesfireAuthErrorToStr(int error); const char *DesfireAuthErrorToStr(int error);
int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool verbose); 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 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); int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose);
void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk *authCmdCheck); void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk *authCmdCheck);
void DesfireCheckAuthCommandsPrint(AuthCommandsChk *authCmdCheck); void DesfireCheckAuthCommandsPrint(AuthCommandsChk *authCmdCheck);

View file

@ -31,12 +31,13 @@
#include "crc16.h" // crc16 ccitt #include "crc16.h" // crc16 ccitt
#include "crc32.h" #include "crc32.h"
#include "commonutil.h" #include "commonutil.h"
#include "crypto/libpcrypto.h"
void DesfireClearContext(DesfireContext *ctx) { void DesfireClearContext(DesfireContext *ctx) {
ctx->keyNum = 0; ctx->keyNum = 0;
ctx->keyType = T_DES; ctx->keyType = T_DES;
memset(ctx->key, 0, sizeof(ctx->key)); memset(ctx->key, 0, sizeof(ctx->key));
LRPClearContext(&ctx->lrpCtx);
ctx->secureChannel = DACNone; ctx->secureChannel = DACNone;
ctx->cmdSet = DCCNative; ctx->cmdSet = DCCNative;
@ -118,6 +119,9 @@ size_t DesfireGetMACLength(DesfireContext *ctx) {
case DACEV2: case DACEV2:
mac_length = 8; mac_length = 8;
break; break;
case DACLRP:
mac_length = 8;
break;
} }
return mac_length; return mac_length;
} }
@ -257,11 +261,16 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type,
if (key == NULL) if (key == NULL)
return; return;
size_t offset = 0; if (ctx->secureChannel == DACLRP) {
while (offset < srcdatalen) { size_t dstlen = 0;
DesfireCryptoEncDecSingleBlock(key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); 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) 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); 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) { void DesfireEV2FillIV(DesfireContext *ctx, bool ivforcommand, uint8_t *iv) {
uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0}; uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0};

View file

@ -23,6 +23,7 @@
#include "common.h" #include "common.h"
#include "crypto/libpcrypto.h" #include "crypto/libpcrypto.h"
#include "mifare/lrpcrypto.h"
#define MAX_CRYPTO_BLOCK_SIZE 16 #define MAX_CRYPTO_BLOCK_SIZE 16
#define DESFIRE_MAX_CRYPTO_BLOCK_SIZE 16 #define DESFIRE_MAX_CRYPTO_BLOCK_SIZE 16
@ -36,7 +37,7 @@ enum DESFIRE_CRYPTOALGO {
T_DES = 0x00, T_DES = 0x00,
T_3DES = 0x01, //aka 2K3DES T_3DES = 0x01, //aka 2K3DES
T_3K3DES = 0x02, T_3K3DES = 0x02,
T_AES = 0x03 T_AES = 0x03,
}; };
typedef enum DESFIRE_CRYPTOALGO DesfireCryptoAlgorythm; typedef enum DESFIRE_CRYPTOALGO DesfireCryptoAlgorythm;
@ -45,7 +46,8 @@ typedef enum {
DACNone, DACNone,
DACd40, DACd40,
DACEV1, DACEV1,
DACEV2 DACEV2,
DACLRP,
} DesfireSecureChannel; } DesfireSecureChannel;
typedef enum { typedef enum {
@ -75,6 +77,8 @@ typedef struct DesfireContextS {
DesfireCryptoAlgorythm keyType; // des/2tdea/3tdea/aes DesfireCryptoAlgorythm keyType; // des/2tdea/3tdea/aes
uint8_t key[DESFIRE_MAX_KEY_SIZE]; uint8_t key[DESFIRE_MAX_KEY_SIZE];
uint8_t masterKey[DESFIRE_MAX_KEY_SIZE]; // source for kdf uint8_t masterKey[DESFIRE_MAX_KEY_SIZE]; // source for kdf
LRPContext lrpCtx;
// KDF finction // KDF finction
uint8_t kdfAlgo; 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 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 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); void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);
uint8_t DesfireDESKeyGetVersion(uint8_t *key); uint8_t DesfireDESKeyGetVersion(uint8_t *key);

View file

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

View file

@ -857,6 +857,28 @@ static bool TestLRPCMAC(void) {
return res; 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 DesfireTest(bool verbose) {
bool res = true; bool res = true;
@ -883,6 +905,7 @@ bool DesfireTest(bool verbose) {
res = res && TestLRPDecode(); res = res && TestLRPDecode();
res = res && TestLRPSubkeys(); res = res && TestLRPSubkeys();
res = res && TestLRPCMAC(); res = res && TestLRPCMAC();
res = res && TestLRPSessionKeys();
PrintAndLogEx(INFO, "---------------------------"); PrintAndLogEx(INFO, "---------------------------");
if (res) 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) { static bool shiftLeftBe(uint8_t *data, size_t length) {
if (length == 0) if (length == 0)
return false; 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); 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 LRPIncCounter(uint8_t *ctr, size_t ctrlen);
void LRPEncode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen); 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 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 LRPGenSubkeys(uint8_t *key, uint8_t *sk1, uint8_t *sk2);
void LRPCMAC(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *cmac); 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 #endif // __LRPCRYPTO_H