mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-24 07:05:40 -07:00
detect lrp authentication
This commit is contained in:
parent
9d072d168a
commit
d716971430
3 changed files with 50 additions and 53 deletions
|
@ -1294,7 +1294,7 @@ static int CmdHF14ADesList(const char *Cmd) {
|
|||
return CmdTraceListAlias(Cmd, "hf mfdes", "des");
|
||||
}
|
||||
|
||||
static int DesfireAuthCheck(DesfireContext_t *dctx, uint32_t appid, DesfireSecureChannel secureChannel, uint8_t *key) {
|
||||
static int DesfireAuthCheck(DesfireContext_t *dctx, DesfireISOSelectWay way, uint32_t appID, DesfireSecureChannel secureChannel, uint8_t *key) {
|
||||
DesfireSetKeyNoClear(dctx, dctx->keyNum, dctx->keyType, key);
|
||||
|
||||
int res = DesfireAuthenticate(dctx, secureChannel, false);
|
||||
|
@ -1303,7 +1303,7 @@ static int DesfireAuthCheck(DesfireContext_t *dctx, uint32_t appid, DesfireSecur
|
|||
return PM3_SUCCESS;
|
||||
} else if (res < 7) {
|
||||
DropField();
|
||||
res = DesfireSelectAIDHex(dctx, appid, false, 0);
|
||||
res = DesfireSelect(dctx, way, appID, NULL);
|
||||
if (res != PM3_SUCCESS) {
|
||||
return -10;
|
||||
}
|
||||
|
@ -1335,6 +1335,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
|
||||
arg_str0("s", "schann", "<d40/ev1/ev2/lrp>", "Secure channel: d40/ev1/ev2/lrp"),
|
||||
arg_str0(NULL, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
|
||||
arg_str0(NULL, "appisoid", "<isoid hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
|
||||
arg_str0(NULL, "dict", "<file>", "File with keys dictionary"),
|
||||
arg_lit0(NULL, "save", "save found key and parameters to defaults"),
|
||||
arg_param_end
|
||||
|
@ -1346,8 +1347,9 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
|
||||
DesfireContext_t dctx;
|
||||
int securechann = defaultSecureChannel;
|
||||
uint32_t appid = 0x000000;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL);
|
||||
uint32_t id = 0x000000;
|
||||
DesfireISOSelectWay selectway = ISW6bAID;
|
||||
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway);
|
||||
if (res) {
|
||||
CLIParserFree(ctx);
|
||||
return res;
|
||||
|
@ -1355,22 +1357,22 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
|
||||
uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0};
|
||||
int dict_filenamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(ctx, 12), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||
if (CLIParamStrToBuf(arg_get_str(ctx, 13), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
bool save = arg_get_lit(ctx, 13);
|
||||
bool save = arg_get_lit(ctx, 14);
|
||||
|
||||
SetAPDULogging(APDULogging);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// no auth and fill KDF if needs
|
||||
res = DesfireSelectAndAuthenticateEx(&dctx, securechann, appid, true, verbose);
|
||||
res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, true, verbose);
|
||||
if (res != PM3_SUCCESS) {
|
||||
DropField();
|
||||
PrintAndLogEx(FAILED, "Select AID 0x%06x " _RED_("failed") ". Result: %d", appid, res);
|
||||
PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1398,7 +1400,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
} else {
|
||||
// if fail - check auth commands
|
||||
AuthCommandsChk_t authCmdCheck = {0};
|
||||
DesfireCheckAuthCommands(appid, NULL, 0, &authCmdCheck);
|
||||
DesfireCheckAuthCommands(selectway, id, NULL, 0, &authCmdCheck);
|
||||
if (authCmdCheck.checked) {
|
||||
if (authCmdCheck.auth) {
|
||||
keytypes[T_DES] = true;
|
||||
|
@ -1416,18 +1418,19 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
keytypes[T_DES] = true;
|
||||
}
|
||||
|
||||
res = DesfireSelectAIDHex(&dctx, appid, false, 0);
|
||||
res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, true, verbose);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Desfire select " _RED_("error") ".");
|
||||
DropField();
|
||||
PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
if (appid == 0)
|
||||
if (DesfireMFSelected(selectway, id))
|
||||
PrintAndLogEx(INFO, "Check PICC key num: %d (0x%02x)", dctx.keyNum, dctx.keyNum);
|
||||
else
|
||||
PrintAndLogEx(INFO, "Check app: %06x key num: %d (0x%02x)", appid, dctx.keyNum, dctx.keyNum);
|
||||
PrintAndLogEx(INFO, "Check: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum);
|
||||
PrintAndLogEx(INFO, "keys: DES: %s 2TDEA: %s 3TDEA: %s AES: %s",
|
||||
keytypes[T_DES] ? _GREEN_("YES") : _RED_("NO"),
|
||||
keytypes[T_3DES] ? _GREEN_("YES") : _RED_("NO"),
|
||||
|
@ -1455,7 +1458,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
if (ktype == T_3K3DES)
|
||||
memcpy(&key[16], key, 8);
|
||||
|
||||
res = DesfireAuthCheck(&dctx, appid, securechann, key);
|
||||
res = DesfireAuthCheck(&dctx, selectway, id, securechann, key);
|
||||
if (res == PM3_SUCCESS) {
|
||||
found = true;
|
||||
break; // all the params already in the dctx
|
||||
|
@ -1490,7 +1493,7 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
break;
|
||||
|
||||
for (int i = 0; i < keyListLen; i++) {
|
||||
res = DesfireAuthCheck(&dctx, appid, securechann, &keyList[i * keylen]);
|
||||
res = DesfireAuthCheck(&dctx, selectway, id, securechann, &keyList[i * keylen]);
|
||||
if (res == PM3_SUCCESS) {
|
||||
found = true;
|
||||
break; // all the params already in the dctx
|
||||
|
@ -1523,10 +1526,10 @@ static int CmdHF14aDesDetect(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (found) {
|
||||
if (appid == 0)
|
||||
if (DesfireMFSelected(selectway, id))
|
||||
PrintAndLogEx(INFO, _GREEN_("Found") " key num: %d (0x%02x)", dctx.keyNum, dctx.keyNum);
|
||||
else
|
||||
PrintAndLogEx(INFO, "Found key for app: %06x key num: %d (0x%02x)", appid, dctx.keyNum, dctx.keyNum);
|
||||
PrintAndLogEx(INFO, "Found key for: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum);
|
||||
|
||||
PrintAndLogEx(INFO, "key " _GREEN_("%s") " [%d]: " _GREEN_("%s"),
|
||||
CLIGetOptionListStr(DesfireAlgoOpts, dctx.keyType),
|
||||
|
|
|
@ -1571,7 +1571,7 @@ int DesfireAuthenticate(DesfireContext_t *dctx, DesfireSecureChannel secureChann
|
|||
return 100;
|
||||
}
|
||||
|
||||
static bool DesfireCheckAuthCmd(uint32_t appAID, uint8_t keyNum, uint8_t authcmd) {
|
||||
static bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum, uint8_t authcmd, bool checklrp) {
|
||||
size_t recv_len = 0;
|
||||
uint8_t respcode = 0;
|
||||
uint8_t recv_data[256] = {0};
|
||||
|
@ -1579,44 +1579,35 @@ static bool DesfireCheckAuthCmd(uint32_t appAID, uint8_t keyNum, uint8_t authcmd
|
|||
DesfireContext_t dctx = {0};
|
||||
dctx.keyNum = keyNum;
|
||||
dctx.commMode = DCMPlain;
|
||||
dctx.cmdSet = DCCNative;
|
||||
dctx.cmdSet = (checklrp) ? DCCNativeISO : DCCNative;
|
||||
|
||||
// if cant select - return false
|
||||
int res = DesfireSelectAIDHex(&dctx, appAID, false, 0);
|
||||
int res = DesfireSelect(&dctx, way, appID, NULL);
|
||||
if (res != PM3_SUCCESS)
|
||||
return false;
|
||||
|
||||
uint8_t data[] = {keyNum, 0x00};
|
||||
res = DesfireExchangeEx(false, &dctx, authcmd, data, (authcmd == MFDES_AUTHENTICATE_EV2F) ? 2 : 1, &respcode, recv_data, &recv_len, false, 0);
|
||||
uint8_t data[] = {keyNum, (checklrp) ? 0x01 : 0x00, 0x02};
|
||||
uint8_t datalen = (authcmd == MFDES_AUTHENTICATE_EV2F) ? 2 : 1;
|
||||
if (checklrp)
|
||||
datalen = 3;
|
||||
res = DesfireExchangeEx(false, &dctx, authcmd, data, datalen, &respcode, recv_data, &recv_len, false, 0);
|
||||
DropField();
|
||||
return (res == PM3_SUCCESS && respcode == 0xaf);
|
||||
|
||||
if (checklrp)
|
||||
return (res == PM3_SUCCESS && respcode == 0xaf && recv_len == 17 && recv_data[0] == 0x01);
|
||||
else
|
||||
return (res == PM3_SUCCESS && respcode == 0xaf);
|
||||
}
|
||||
|
||||
static bool DesfireCheckISOAuthCmd(uint32_t appAID, char *dfname, uint8_t keyNum, DesfireCryptoAlgorithm keytype) {
|
||||
static bool DesfireCheckISOAuthCmd(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, DesfireCryptoAlgorithm keytype) {
|
||||
|
||||
DesfireContext_t dctx = {0};
|
||||
dctx.keyNum = keyNum;
|
||||
dctx.commMode = DCMPlain;
|
||||
dctx.cmdSet = DCCISO;
|
||||
|
||||
bool app_level = (appAID != 0x000000);
|
||||
int res = 0;
|
||||
if (dfname == NULL || strnlen(dfname, 16) == 0) {
|
||||
if (appAID == 0x000000) {
|
||||
res = DesfireISOSelect(&dctx, ISSMFDFEF, NULL, 0, NULL, NULL);
|
||||
if (res != PM3_SUCCESS)
|
||||
return false;
|
||||
} else {
|
||||
res = DesfireSelectAIDHex(&dctx, appAID, false, 0);
|
||||
if (res != PM3_SUCCESS)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
res = DesfireISOSelectDF(&dctx, dfname, NULL, NULL);
|
||||
if (res != PM3_SUCCESS)
|
||||
return false;
|
||||
app_level = true;
|
||||
}
|
||||
bool app_level = DesfireMFSelected(way, appID);
|
||||
int res = DesfireSelect(&dctx, way, appID, dfname);
|
||||
|
||||
uint8_t rndlen = DesfireGetRndLenForKey(keytype);
|
||||
|
||||
|
@ -1637,24 +1628,26 @@ static bool DesfireCheckISOAuthCmd(uint32_t appAID, char *dfname, uint8_t keyNum
|
|||
return (sw == 0x9000 || sw == 0x6982);
|
||||
}
|
||||
|
||||
void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck) {
|
||||
void DesfireCheckAuthCommands(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck) {
|
||||
memset(authCmdCheck, 0, sizeof(AuthCommandsChk_t));
|
||||
|
||||
authCmdCheck->auth = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE);
|
||||
authCmdCheck->authISO = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_ISO);
|
||||
authCmdCheck->authAES = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_AES);
|
||||
authCmdCheck->authEV2 = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_EV2F);
|
||||
authCmdCheck->authISONative = DesfireCheckISOAuthCmd(appAID, dfname, keyNum, T_DES);
|
||||
authCmdCheck->auth = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE, false);
|
||||
authCmdCheck->authISO = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_ISO, false);
|
||||
authCmdCheck->authAES = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_AES, false);
|
||||
authCmdCheck->authEV2 = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_EV2F, false);
|
||||
authCmdCheck->authISONative = DesfireCheckISOAuthCmd(way, appID, dfname, keyNum, T_DES);
|
||||
authCmdCheck->authLRP = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_EV2F, true);
|
||||
authCmdCheck->checked = true;
|
||||
}
|
||||
|
||||
void DesfireCheckAuthCommandsPrint(AuthCommandsChk_t *authCmdCheck) {
|
||||
PrintAndLogEx(NORMAL, "auth: %s auth iso: %s auth aes: %s auth ev2: %s auth iso native: %s",
|
||||
PrintAndLogEx(NORMAL, "auth: %s auth iso: %s auth aes: %s auth ev2: %s auth iso native: %s auth lrp: %s",
|
||||
authCmdCheck->auth ? _GREEN_("YES") : _RED_("NO"),
|
||||
authCmdCheck->authISO ? _GREEN_("YES") : _RED_("NO"),
|
||||
authCmdCheck->authAES ? _GREEN_("YES") : _RED_("NO"),
|
||||
authCmdCheck->authEV2 ? _GREEN_("YES") : _RED_("NO"),
|
||||
authCmdCheck->authISONative ? _GREEN_("YES") : _RED_("NO")
|
||||
authCmdCheck->authISONative ? _GREEN_("YES") : _RED_("NO"),
|
||||
authCmdCheck->authLRP ? _GREEN_("YES") : _RED_("NO")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1688,7 +1681,7 @@ int DesfireFillPICCInfo(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, bool deepm
|
|||
|
||||
// field on-off zone
|
||||
if (deepmode)
|
||||
DesfireCheckAuthCommands(0x000000, NULL, 0, &PICCInfo->authCmdCheck);
|
||||
DesfireCheckAuthCommands(ISW6bAID, 0x000000, NULL, 0, &PICCInfo->authCmdCheck);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
@ -1770,7 +1763,7 @@ int DesfireFillAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS ap
|
|||
// field on-off zone
|
||||
if (fillAppSettings && PICCInfo->appCount > 0 && deepmode) {
|
||||
for (int i = 0; i < PICCInfo->appCount; i++) {
|
||||
DesfireCheckAuthCommands(appList[i].appNum, appList[i].appDFName, 0, &appList[i].authCmdCheck);
|
||||
DesfireCheckAuthCommands(ISW6bAID, appList[i].appNum, appList[i].appDFName, 0, &appList[i].authCmdCheck);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ typedef struct {
|
|||
bool authAES;
|
||||
bool authEV2;
|
||||
bool authISONative;
|
||||
bool authLRP;
|
||||
} AuthCommandsChk_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -183,7 +184,7 @@ int DesfireSelectAndAuthenticateW(DesfireContext_t *dctx, DesfireSecureChannel s
|
|||
int DesfireSelectAndAuthenticateAppW(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, DesfireISOSelectWay way, uint32_t id, bool noauth, bool verbose);
|
||||
int DesfireSelectAndAuthenticateISO(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, bool selectfile, uint16_t isofileid, bool noauth, bool verbose);
|
||||
int DesfireAuthenticate(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, bool verbose);
|
||||
void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck);
|
||||
void DesfireCheckAuthCommands(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck);
|
||||
void DesfireCheckAuthCommandsPrint(AuthCommandsChk_t *authCmdCheck);
|
||||
|
||||
int DesfireFormatPICC(DesfireContext_t *dctx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue