mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
fix return codes
This commit is contained in:
parent
30b217be65
commit
33380ad240
5 changed files with 231 additions and 111 deletions
|
@ -923,12 +923,14 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
|||
// select with no disconnect and set gs_frame_len
|
||||
int selres = SelectCard14443A_4(false, !silentMode, NULL);
|
||||
gs_frames_num = 0;
|
||||
if (selres != PM3_SUCCESS)
|
||||
if (selres != PM3_SUCCESS) {
|
||||
return selres;
|
||||
}
|
||||
}
|
||||
|
||||
if (leaveSignalON)
|
||||
if (leaveSignalON) {
|
||||
cmdc |= ISO14A_NO_DISCONNECT;
|
||||
}
|
||||
|
||||
uint8_t data[PM3_CMD_DATA_SIZE] = { 0x0a | gs_frames_num, 0x00 };
|
||||
gs_frames_num ^= 1;
|
||||
|
@ -939,44 +941,54 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
|||
|
||||
uint8_t *recv;
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
recv = resp.data.asBytes;
|
||||
int iLen = resp.oldarg[0];
|
||||
|
||||
if (!iLen) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "No card response.");
|
||||
return 1;
|
||||
if (iLen == 0) {
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "No card response");
|
||||
}
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
*dataoutlen = iLen - 2;
|
||||
if (*dataoutlen < 0)
|
||||
if (*dataoutlen < 0) {
|
||||
*dataoutlen = 0;
|
||||
}
|
||||
|
||||
if (maxdataoutlen && *dataoutlen > maxdataoutlen) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen);
|
||||
return 2;
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen);
|
||||
}
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
|
||||
if (recv[0] != data[0]) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", recv[0], data[0]);
|
||||
return 2;
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", recv[0], data[0]);
|
||||
}
|
||||
return PM3_ELENGTH;
|
||||
}
|
||||
|
||||
memcpy(dataout, &recv[2], *dataoutlen);
|
||||
|
||||
// CRC Check
|
||||
if (iLen == -1) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "ISO 14443A CRC error.");
|
||||
return 3;
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "ISO 14443A CRC error.");
|
||||
}
|
||||
return PM3_ECRC;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Reply timeout.");
|
||||
return 4;
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Reply timeout.");
|
||||
}
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int SelectCard14443A_4_WithParameters(bool disconnect, bool verbose, iso14a_card_select_t *card, iso14a_polling_parameters_t *polling_parameters) {
|
||||
|
|
|
@ -382,6 +382,12 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
|||
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
|
||||
int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false);
|
||||
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(INFO, "identification failed");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
// DESFire answers 0x1C or 67 00
|
||||
// Plus answers 0x0B, 0x09, 0x06
|
||||
// 6D00 is "INS code not supported" in APDU
|
||||
|
@ -413,12 +419,14 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, " result.... " _GREEN_("MIFARE Plus SL0/SL3"));
|
||||
}
|
||||
|
||||
if (!res && datalen > 1 && data[0] == 0x09) {
|
||||
if ((datalen > 1) &&
|
||||
(data[0] == 0x09)) {
|
||||
SLmode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isPlus) {
|
||||
// How do we detect SL0 / SL1 / SL2 / SL3 modes?!?
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Security Level (SL)"));
|
||||
|
@ -446,7 +454,7 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(INFO, "\tMifare Plus info not available.");
|
||||
PrintAndLogEx(INFO, " Mifare Plus info not available");
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
DropField();
|
||||
|
@ -1730,7 +1738,6 @@ static int CmdHFMFPDump(const char *Cmd) {
|
|||
*/
|
||||
}
|
||||
|
||||
|
||||
static int CmdHFMFPMAD(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
|
|
|
@ -495,53 +495,68 @@ static int DESFIRESendApdu(bool activate_field, sAPDU_t apdu, uint8_t *result, u
|
|||
|
||||
static int DESFIRESendRaw(bool activate_field, uint8_t *data, size_t datalen, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint8_t *respcode) {
|
||||
*result_len = 0;
|
||||
if (respcode) *respcode = 0xff;
|
||||
if (respcode) {
|
||||
*respcode = 0xff;
|
||||
}
|
||||
|
||||
if (activate_field) {
|
||||
DropField();
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
if (GetAPDULogging())
|
||||
if (GetAPDULogging()) {
|
||||
PrintAndLogEx(SUCCESS, "raw>> %s", sprint_hex(data, datalen));
|
||||
}
|
||||
|
||||
int res = ExchangeRAW14a(data, datalen, activate_field, true, result, max_result_len, (int *)result_len, true);
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (GetAPDULogging())
|
||||
if (GetAPDULogging()) {
|
||||
PrintAndLogEx(SUCCESS, "raw<< %s", sprint_hex(result, *result_len));
|
||||
}
|
||||
|
||||
if (*result_len < 1) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
*result_len -= 1 + 2;
|
||||
*result_len -= (1 + 2);
|
||||
|
||||
uint8_t rcode = result[0];
|
||||
if (respcode) *respcode = rcode;
|
||||
if (respcode) {
|
||||
*respcode = rcode;
|
||||
}
|
||||
|
||||
memmove(&result[0], &result[1], *result_len);
|
||||
|
||||
if (rcode != MFDES_S_OPERATION_OK &&
|
||||
rcode != MFDES_S_SIGNATURE &&
|
||||
rcode != MFDES_S_ADDITIONAL_FRAME &&
|
||||
rcode != MFDES_S_NO_CHANGES) {
|
||||
if (GetAPDULogging())
|
||||
|
||||
if (GetAPDULogging()) {
|
||||
PrintAndLogEx(ERR, "Command (%02x) ERROR: 0x%02x", data[0], rcode);
|
||||
}
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *respcode, uint8_t *resp, size_t *resplen, bool enable_chaining, size_t splitbysize) {
|
||||
if (resplen)
|
||||
if (resplen) {
|
||||
*resplen = 0;
|
||||
if (respcode)
|
||||
}
|
||||
|
||||
if (respcode) {
|
||||
*respcode = 0xff;
|
||||
}
|
||||
|
||||
uint8_t *buf = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
if (buf == NULL)
|
||||
if (buf == NULL) {
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
uint32_t buflen = 0;
|
||||
uint32_t pos = 0;
|
||||
uint32_t i = 1;
|
||||
|
@ -558,7 +573,8 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin
|
|||
// tx chaining
|
||||
size_t sentdatalen = 0;
|
||||
while (cdatalen >= sentdatalen) {
|
||||
if (cdatalen - sentdatalen > DESFIRE_TX_FRAME_MAX_LEN)
|
||||
|
||||
if ((cdatalen - sentdatalen) > DESFIRE_TX_FRAME_MAX_LEN)
|
||||
len = DESFIRE_TX_FRAME_MAX_LEN;
|
||||
else
|
||||
len = cdatalen - sentdatalen;
|
||||
|
@ -580,9 +596,10 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin
|
|||
}
|
||||
|
||||
sentdatalen += len;
|
||||
if (rcode != MFDES_ADDITIONAL_FRAME || buflen > 0) {
|
||||
if (sentdatalen != cdatalen)
|
||||
if ((rcode != MFDES_ADDITIONAL_FRAME) || (buflen > 0)) {
|
||||
if (sentdatalen != cdatalen) {
|
||||
PrintAndLogEx(WARNING, "Tx chaining error. Needs to send: %d but sent: %zu", cdatalen, sentdatalen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -596,16 +613,20 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin
|
|||
memcpy(resp, buf, buflen);
|
||||
}
|
||||
}
|
||||
if (respcode != NULL)
|
||||
if (respcode != NULL) {
|
||||
*respcode = rcode;
|
||||
}
|
||||
|
||||
pos += buflen;
|
||||
if (!enable_chaining) {
|
||||
|
||||
if (enable_chaining == false) {
|
||||
if (rcode == MFDES_S_OPERATION_OK ||
|
||||
rcode == MFDES_ADDITIONAL_FRAME) {
|
||||
if (resplen)
|
||||
|
||||
if (resplen) {
|
||||
*resplen = pos;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
@ -620,8 +641,9 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin
|
|||
return res;
|
||||
}
|
||||
|
||||
if (respcode != NULL)
|
||||
if (respcode != NULL) {
|
||||
*respcode = rcode;
|
||||
}
|
||||
|
||||
if (resp != NULL) {
|
||||
if (splitbysize) {
|
||||
|
@ -634,22 +656,26 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin
|
|||
}
|
||||
pos += buflen;
|
||||
|
||||
if (rcode != MFDES_ADDITIONAL_FRAME) break;
|
||||
if (rcode != MFDES_ADDITIONAL_FRAME)
|
||||
break;
|
||||
}
|
||||
|
||||
if (resplen)
|
||||
if (resplen) {
|
||||
*resplen = (splitbysize) ? i : pos;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *respcode, uint8_t *resp, size_t *resplen, bool enable_chaining, size_t splitbysize) {
|
||||
if (resplen)
|
||||
if (resplen) {
|
||||
*resplen = 0;
|
||||
}
|
||||
|
||||
if (respcode)
|
||||
if (respcode) {
|
||||
*respcode = 0xff;
|
||||
}
|
||||
|
||||
uint16_t sw = 0;
|
||||
uint8_t *buf = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
|
@ -679,8 +705,9 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
|
||||
apdu.data = &data[sentdatalen];
|
||||
|
||||
if (sentdatalen > 0)
|
||||
if (sentdatalen > 0) {
|
||||
apdu.INS = MFDES_ADDITIONAL_FRAME;
|
||||
}
|
||||
|
||||
res = DESFIRESendApdu(activate_field, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw);
|
||||
if (res != PM3_SUCCESS) {
|
||||
|
@ -691,14 +718,16 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
|
||||
sentdatalen += apdu.Lc;
|
||||
if (sw != DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME) || buflen > 0) {
|
||||
if (sentdatalen != datalen)
|
||||
if (sentdatalen != datalen) {
|
||||
PrintAndLogEx(WARNING, "Tx chaining error. Needs to send: %zu but sent: %zu", datalen, sentdatalen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100))
|
||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100)) {
|
||||
*respcode = sw & 0xff;
|
||||
}
|
||||
|
||||
if (resp) {
|
||||
if (splitbysize) {
|
||||
|
@ -710,12 +739,14 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
}
|
||||
|
||||
pos += buflen;
|
||||
if (!enable_chaining) {
|
||||
if (enable_chaining == false) {
|
||||
if (sw == DESFIRE_GET_ISO_STATUS(MFDES_S_OPERATION_OK) ||
|
||||
sw == DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) {
|
||||
if (resplen)
|
||||
|
||||
if (resplen) {
|
||||
*resplen = pos;
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
@ -735,8 +766,9 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
return res;
|
||||
}
|
||||
|
||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100))
|
||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100)) {
|
||||
*respcode = sw & 0xff;
|
||||
}
|
||||
|
||||
if (resp != NULL) {
|
||||
if (splitbysize) {
|
||||
|
@ -749,11 +781,14 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
}
|
||||
pos += buflen;
|
||||
|
||||
if (sw != DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) break;
|
||||
if (sw != DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (resplen)
|
||||
if (resplen) {
|
||||
*resplen = (splitbysize) ? i : pos;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return PM3_SUCCESS;
|
||||
|
@ -761,13 +796,16 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
|
||||
static int DesfireExchangeISO(bool activate_field, DesfireContext_t *ctx, sAPDU_t apdu, uint16_t le, uint8_t *resp, size_t *resplen, uint16_t *sw) {
|
||||
uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
if (data == NULL)
|
||||
if (data == NULL) {
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
uint32_t datalen = 0;
|
||||
int res = DESFIRESendApduEx(activate_field, apdu, le, data, DESFIRE_BUFFER_SIZE, &datalen, sw);
|
||||
|
||||
if (res == PM3_SUCCESS)
|
||||
if (res == PM3_SUCCESS) {
|
||||
DesfireSecureChannelDecode(ctx, data, datalen, 0, resp, resplen);
|
||||
}
|
||||
|
||||
free(data);
|
||||
return res;
|
||||
|
@ -791,15 +829,18 @@ static void DesfireSplitBytesToBlock(uint8_t *blockdata, size_t *blockdatacount,
|
|||
size_t tlen = len + blockdata[i * blockdatasize];
|
||||
if (tlen > dstdatalen) {
|
||||
tlen = dstdatalen;
|
||||
|
||||
if (tlen >= len)
|
||||
blockdata[i * blockdatasize] = tlen - len;
|
||||
else
|
||||
blockdata[i * blockdatasize] = 0;
|
||||
}
|
||||
|
||||
if (len == tlen) {
|
||||
*blockdatacount = i;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(&blockdata[i * blockdatasize + 1], &dstdata[len], tlen - len);
|
||||
len = tlen;
|
||||
}
|
||||
|
@ -809,12 +850,15 @@ int DesfireExchangeEx(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, u
|
|||
uint8_t *resp, size_t *resplen, bool enable_chaining, size_t splitbysize) {
|
||||
int res = PM3_SUCCESS;
|
||||
|
||||
if (!PrintChannelModeWarning(cmd, ctx->secureChannel, ctx->cmdSet, ctx->commMode))
|
||||
if (PrintChannelModeWarning(cmd, ctx->secureChannel, ctx->cmdSet, ctx->commMode) == false) {
|
||||
DesfirePrintContext(ctx);
|
||||
}
|
||||
|
||||
uint8_t *databuf = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
if (databuf == NULL)
|
||||
if (databuf == NULL) {
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
size_t databuflen = 0;
|
||||
|
||||
switch (ctx->cmdSet) {
|
||||
|
@ -857,13 +901,16 @@ int DesfireExchange(DesfireContext_t *ctx, uint8_t cmd, uint8_t *data, size_t da
|
|||
}
|
||||
|
||||
int DesfireSelectAID(DesfireContext_t *ctx, uint8_t *aid1, uint8_t *aid2) {
|
||||
if (aid1 == NULL)
|
||||
if (aid1 == NULL) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t data[6] = {0};
|
||||
memcpy(data, aid1, 3);
|
||||
if (aid2 != NULL)
|
||||
if (aid2 != NULL) {
|
||||
memcpy(&data[3], aid2, 3);
|
||||
}
|
||||
|
||||
uint8_t resp[257] = {0};
|
||||
size_t resplen = 0;
|
||||
uint8_t respcode = 0;
|
||||
|
@ -871,12 +918,14 @@ int DesfireSelectAID(DesfireContext_t *ctx, uint8_t *aid1, uint8_t *aid2) {
|
|||
ctx->secureChannel = DACNone;
|
||||
int res = DesfireExchangeEx(true, ctx, MFDES_SELECT_APPLICATION, data, (aid2 == NULL) ? 3 : 6, &respcode, resp, &resplen, true, 0);
|
||||
if (res == PM3_SUCCESS) {
|
||||
if (resplen != 0)
|
||||
if (resplen != 0) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// select operation fail
|
||||
if (respcode != MFDES_S_OPERATION_OK)
|
||||
if (respcode != MFDES_S_OPERATION_OK) {
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
DesfireClearSession(ctx);
|
||||
ctx->appSelected = (aid1[0] != 0x00 || aid1[1] != 0x00 || aid1[2] != 0x00);
|
||||
|
@ -1933,8 +1982,9 @@ int DesfireGetFreeMem(DesfireContext_t *dctx, uint32_t *freemem) {
|
|||
uint8_t resp[257] = {0};
|
||||
size_t resplen = 0;
|
||||
int res = DesfireCommandRxData(dctx, MFDES_GET_FREE_MEMORY, resp, &resplen, 3);
|
||||
if (res == PM3_SUCCESS)
|
||||
if (res == PM3_SUCCESS) {
|
||||
*freemem = DesfireAIDByteToUint(resp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2148,8 +2198,9 @@ int DesfireValueFileOperations(DesfireContext_t *dctx, uint8_t fid, uint8_t oper
|
|||
|
||||
int res = DesfireCommand(dctx, operation, data, datalen, resp, &resplen, -1);
|
||||
|
||||
if (resplen == 4 && value)
|
||||
if (resplen == 4 && value) {
|
||||
*value = MemLeToUint4byte(resp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -218,14 +218,20 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti
|
|||
|
||||
uint8_t cmd1[] = {0x70, keyn[1], keyn[0], 0x00};
|
||||
int res = ExchangeRAW14a(cmd1, sizeof(cmd1), activateField, true, data, sizeof(data), &datalen, silentMode);
|
||||
if (res) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Exchange raw error: %d", res);
|
||||
if (dropFieldIfError) DropField();
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Exchange raw error: %d", res);
|
||||
}
|
||||
|
||||
if (dropFieldIfError) {
|
||||
DropField();
|
||||
}
|
||||
return PM3_ERFTRANS;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "< phase1: %s", sprint_hex(data, datalen));
|
||||
}
|
||||
|
||||
if (datalen < 1) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Card response wrong length: %d", datalen);
|
||||
|
@ -247,8 +253,9 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti
|
|||
|
||||
aes_decode(NULL, key, &data[1], RndB, 16);
|
||||
RndB[16] = RndB[0];
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "RndB: %s", sprint_hex(RndB, 16));
|
||||
}
|
||||
|
||||
uint8_t cmd2[33] = {0};
|
||||
cmd2[0] = 0x72;
|
||||
|
@ -262,14 +269,19 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti
|
|||
PrintAndLogEx(INFO, ">phase2: %s", sprint_hex(cmd2, 33));
|
||||
}
|
||||
res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, true, data, sizeof(data), &datalen, silentMode);
|
||||
if (res) {
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Exchange raw error: %d", res);
|
||||
if (dropFieldIfError) DropField();
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (silentMode == false) {
|
||||
PrintAndLogEx(ERR, "Exchange raw error: %d", res);
|
||||
}
|
||||
if (dropFieldIfError) {
|
||||
DropField();
|
||||
}
|
||||
return PM3_ERFTRANS;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "< phase2: %s", sprint_hex(data, datalen));
|
||||
}
|
||||
|
||||
aes_decode(NULL, key, &data[1], raw, 32);
|
||||
|
||||
|
@ -320,11 +332,13 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti
|
|||
PrintAndLogEx(INFO, "kmac: %s", sprint_hex(kmac, 16));
|
||||
}
|
||||
|
||||
if (!leaveSignalON)
|
||||
if (leaveSignalON == false) {
|
||||
DropField();
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
if (mf4session) {
|
||||
mf4session->Authenticated = true;
|
||||
|
@ -341,21 +355,23 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti
|
|||
memmove(mf4session->Kmac, kmac, 16);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "Authentication OK");
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
|
||||
if (g_verbose_mode)
|
||||
if (g_verbose_mode) {
|
||||
PrintAndLogEx(INFO, ">>> %s", sprint_hex(datain, datainlen));
|
||||
}
|
||||
|
||||
int res = ExchangeRAW14a(datain, datainlen, activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen, false);
|
||||
|
||||
if (g_verbose_mode)
|
||||
if (g_verbose_mode) {
|
||||
PrintAndLogEx(INFO, "<<< %s", sprint_hex(dataout, *dataoutlen));
|
||||
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -373,48 +389,79 @@ int MFPCommitPerso(bool activateField, bool leaveSignalON, uint8_t *dataout, int
|
|||
}
|
||||
|
||||
int MFPReadBlock(mf4Session_t *mf4session, bool plain, bool nomaccmd, bool nomacres, uint8_t blockNum, uint8_t blockCount, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) {
|
||||
|
||||
int cmdb = 0x31;
|
||||
if (nomacres) {cmdb = cmdb ^ 0x01;} // If we do not want MAC in reply, remove 0x01
|
||||
if (plain) {cmdb = cmdb ^ 0x02;} // If we do not need an encrypted transmission, add 0x02
|
||||
if (nomaccmd) {cmdb = cmdb ^ 0x04;} // If we do not want to send a MAC, remove 0x04
|
||||
if (nomacres) {
|
||||
cmdb = cmdb ^ 0x01; // If we do not want MAC in reply, remove 0x01
|
||||
}
|
||||
|
||||
if (plain) {
|
||||
cmdb = cmdb ^ 0x02; // If we do not need an encrypted transmission, add 0x02
|
||||
}
|
||||
|
||||
if (nomaccmd) {
|
||||
cmdb = cmdb ^ 0x04; // If we do not want to send a MAC, remove 0x04
|
||||
}
|
||||
|
||||
uint8_t rcmd1[4] = {cmdb, blockNum, 0x00, blockCount};
|
||||
uint8_t maccmddat[8] = {0};
|
||||
uint8_t rcmd[nomaccmd ? 4 : 12];
|
||||
if (!nomaccmd && mf4session)
|
||||
CalculateMAC(mf4session, mtypReadCmd, blockNum, blockCount, rcmd1, 4, &maccmddat[0], g_verbose_mode);
|
||||
memmove(rcmd, rcmd1, 4);
|
||||
if (!nomaccmd) {memmove(&rcmd[4], maccmddat, 8);}
|
||||
int res = intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen);
|
||||
if (res)
|
||||
return res;
|
||||
if (mf4session)
|
||||
mf4session->R_Ctr++;
|
||||
if (mf4session && !nomacres && *dataoutlen > 11)
|
||||
CalculateMAC(mf4session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, g_verbose_mode);
|
||||
|
||||
return 0;
|
||||
if (nomaccmd == false && mf4session) {
|
||||
CalculateMAC(mf4session, mtypReadCmd, blockNum, blockCount, rcmd1, 4, &maccmddat[0], g_verbose_mode);
|
||||
}
|
||||
|
||||
memmove(rcmd, rcmd1, 4);
|
||||
if (nomaccmd == false) {
|
||||
memmove(&rcmd[4], maccmddat, 8);
|
||||
}
|
||||
|
||||
int res = intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen);
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (mf4session) {
|
||||
mf4session->R_Ctr++;
|
||||
}
|
||||
|
||||
if (mf4session && !nomacres && *dataoutlen > 11) {
|
||||
CalculateMAC(mf4session, mtypReadResp, blockNum, blockCount, dataout, *dataoutlen - 8 - 2, mac, g_verbose_mode);
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int MFPWriteBlock(mf4Session_t *mf4session, bool plain, bool nomacres, uint8_t blockNum, uint8_t blockHdr, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac) {
|
||||
int cmdb = 0xA1;
|
||||
if (nomacres) {cmdb = cmdb ^ 0x01;} // If we do not want MAC in reply, remove 0x01
|
||||
if (plain) {cmdb = cmdb ^ 0x02;} // If we do not need an encrypted transmission, add 0x02
|
||||
if (nomacres) {
|
||||
cmdb = cmdb ^ 0x01; // If we do not want MAC in reply, remove 0x01
|
||||
}
|
||||
|
||||
if (plain) {
|
||||
cmdb = cmdb ^ 0x02; // If we do not need an encrypted transmission, add 0x02
|
||||
}
|
||||
|
||||
uint8_t rcmd[1 + 2 + 16 + 8] = {cmdb, blockNum, blockHdr};
|
||||
memmove(&rcmd[3], data, 16);
|
||||
if (mf4session)
|
||||
if (mf4session) {
|
||||
CalculateMAC(mf4session, mtypWriteCmd, blockNum, 1, rcmd, 19, &rcmd[19], g_verbose_mode);
|
||||
}
|
||||
|
||||
int res = intExchangeRAW14aPlus(rcmd, sizeof(rcmd), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen);
|
||||
if (res)
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (mf4session)
|
||||
if (mf4session) {
|
||||
mf4session->W_Ctr++;
|
||||
}
|
||||
|
||||
if (mf4session && mac && *dataoutlen > 3 && !nomacres)
|
||||
if (mf4session && mac && *dataoutlen > 3 && !nomacres) {
|
||||
CalculateMAC(mf4session, mtypWriteResp, blockNum, 1, dataout, *dataoutlen, mac, g_verbose_mode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose) {
|
||||
|
@ -424,8 +471,9 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data
|
|||
uint16_t uKeyNum = 0x4000 + sectorNo * 2 + (keyType ? 1 : 0);
|
||||
keyn[0] = uKeyNum >> 8;
|
||||
keyn[1] = uKeyNum & 0xff;
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "--sector[%u]:%02x key:%04x", mfNumBlocksPerSector(sectorNo), sectorNo, uKeyNum);
|
||||
}
|
||||
|
||||
mf4Session_t _session;
|
||||
int res = MifareAuth4(&_session, keyn, key, true, true, true, verbose, false);
|
||||
|
@ -467,16 +515,18 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data
|
|||
PrintAndLogEx(WARNING, "MAC card: %s", sprint_hex(&data[1 + 16], 8));
|
||||
PrintAndLogEx(WARNING, "MAC reader: %s", sprint_hex(mac, 8));
|
||||
|
||||
if (!verbose)
|
||||
if (verbose == false) {
|
||||
return 7;
|
||||
}
|
||||
} else {
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "MAC: %s", sprint_hex(&data[1 + 16], 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
DropField();
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
|
||||
|
@ -501,13 +551,13 @@ int MFPGetVersion(bool activateField, bool leaveSignalON, uint8_t *dataout, int
|
|||
if (tmp[0] == 0xAF) {
|
||||
c[0] = 0xAF;
|
||||
res = intExchangeRAW14aPlus(c, sizeof(c), false, true, tmp, maxdataoutlen, dataoutlen);
|
||||
if (res == 0) {
|
||||
if (res == PM3_SUCCESS) {
|
||||
|
||||
memcpy(dataout + 7, tmp + 1, (*dataoutlen - 3));
|
||||
|
||||
// MFDES_ADDITIONAL_FRAME
|
||||
res = intExchangeRAW14aPlus(c, sizeof(c), false, false, tmp, maxdataoutlen, dataoutlen);
|
||||
if (res == 0) {
|
||||
if (res == PM3_SUCCESS) {
|
||||
if (tmp[0] == 0x90) {
|
||||
memcpy(dataout + 7 + 7, tmp + 1, (*dataoutlen - 3));
|
||||
*dataoutlen = 28;
|
||||
|
|
|
@ -232,9 +232,9 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
|
|||
PacketResponseNG resp;
|
||||
|
||||
uint32_t timeout = 0;
|
||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
||||
|
||||
PrintAndLogEx((timeout == 0) ? INFO : NORMAL, "." NOLF);
|
||||
PrintAndLogEx((timeout) ? NORMAL : INFO, "." NOLF);
|
||||
fflush(stdout);
|
||||
|
||||
timeout++;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue