mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
Merge pull request #1396 from merlokk/desf_tx_chaining
Desfire tx chaining
This commit is contained in:
commit
417acff358
3 changed files with 62 additions and 12 deletions
|
@ -6394,7 +6394,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resplen > 0) {
|
if (resplen > 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Read %u bytes from file 0x%02x offset %u", resplen, fnum, offset);
|
PrintAndLogEx(SUCCESS, "Read %zu bytes from file 0x%02x offset %u", resplen, fnum, offset);
|
||||||
print_buffer_with_offset(resp, resplen, offset, true);
|
print_buffer_with_offset(resp, resplen, offset, true);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "Read operation returned no data from file %d", fnum);
|
PrintAndLogEx(SUCCESS, "Read operation returned no data from file %d", fnum);
|
||||||
|
@ -6444,7 +6444,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
|
||||||
PrintAndLogEx(SUCCESS, "Lastest record at the bottom.");
|
PrintAndLogEx(SUCCESS, "Lastest record at the bottom.");
|
||||||
for (int i = 0; i < reccount; i++) {
|
for (int i = 0; i < reccount; i++) {
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
PrintAndLogEx(SUCCESS, "Record %d", reccount - (i + offset + 1));
|
PrintAndLogEx(SUCCESS, "Record %zu", reccount - (i + offset + 1));
|
||||||
print_buffer_with_offset(&resp[i * reclen], reclen, offset, (i == 0));
|
print_buffer_with_offset(&resp[i * reclen], reclen, offset, (i == 0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -381,19 +381,46 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext *ctx, uint8
|
||||||
uint32_t i = 1;
|
uint32_t i = 1;
|
||||||
|
|
||||||
uint8_t rcode = 0xff;
|
uint8_t rcode = 0xff;
|
||||||
uint8_t cdata[255] = {0};
|
uint8_t cdata[1024] = {0};
|
||||||
uint32_t cdatalen = 0;
|
uint32_t cdatalen = 0;
|
||||||
cdata[0] = cmd;
|
cdata[0] = cmd;
|
||||||
memcpy(&cdata[1], data, datalen);
|
memcpy(&cdata[1], data, datalen);
|
||||||
cdatalen = datalen + 1;
|
cdatalen = datalen + 1;
|
||||||
|
|
||||||
int res = DESFIRESendRaw(activate_field, cdata, cdatalen, buf, sizeof(buf), &buflen, &rcode);
|
int res = 0;
|
||||||
if (res != PM3_SUCCESS) {
|
size_t len = 0;
|
||||||
uint16_t ssw = DESFIRE_GET_ISO_STATUS(rcode);
|
// tx chaining
|
||||||
PrintAndLogEx(DEBUG, "error DESFIRESendRaw %s", DesfireGetErrorString(res, &ssw));
|
size_t sentdatalen = 0;
|
||||||
return res;
|
while(cdatalen >= sentdatalen) {
|
||||||
|
if (cdatalen - sentdatalen > DESFIRE_TX_FRAME_MAX_LEN)
|
||||||
|
len = DESFIRE_TX_FRAME_MAX_LEN;
|
||||||
|
else
|
||||||
|
len = cdatalen - sentdatalen;
|
||||||
|
|
||||||
|
size_t sendindx = sentdatalen;
|
||||||
|
size_t sendlen = len;
|
||||||
|
if (sentdatalen > 0) {
|
||||||
|
sendindx--;
|
||||||
|
sendlen++;
|
||||||
|
cdata[sendindx] = MFDES_ADDITIONAL_FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = DESFIRESendRaw(activate_field, &cdata[sendindx], sendlen, buf, sizeof(buf), &buflen, &rcode);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
uint16_t ssw = DESFIRE_GET_ISO_STATUS(rcode);
|
||||||
|
PrintAndLogEx(DEBUG, "error DESFIRESendRaw %s", DesfireGetErrorString(res, &ssw));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
sentdatalen += len;
|
||||||
|
if (rcode != MFDES_ADDITIONAL_FRAME || buflen > 0) {
|
||||||
|
if (sentdatalen != cdatalen)
|
||||||
|
PrintAndLogEx(WARNING, "Tx chaining error. Needs to send: %d but sent: %d", cdatalen, sentdatalen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rx
|
||||||
if (resp) {
|
if (resp) {
|
||||||
if (splitbysize) {
|
if (splitbysize) {
|
||||||
resp[0] = buflen;
|
resp[0] = buflen;
|
||||||
|
@ -468,10 +495,31 @@ static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, uint8_t
|
||||||
apdu.P2 = 0;
|
apdu.P2 = 0;
|
||||||
apdu.data = data;
|
apdu.data = data;
|
||||||
|
|
||||||
int res = DESFIRESendApdu(activate_field, apdu, buf, sizeof(buf), &buflen, &sw);
|
int res = 0;
|
||||||
if (res != PM3_SUCCESS) {
|
// tx chaining
|
||||||
PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw));
|
size_t sentdatalen = 0;
|
||||||
return res;
|
while(datalen >= sentdatalen) {
|
||||||
|
if (datalen - sentdatalen > DESFIRE_TX_FRAME_MAX_LEN)
|
||||||
|
apdu.Lc = DESFIRE_TX_FRAME_MAX_LEN;
|
||||||
|
else
|
||||||
|
apdu.Lc = datalen - sentdatalen;
|
||||||
|
apdu.data = &data[sentdatalen];
|
||||||
|
|
||||||
|
if (sentdatalen > 0)
|
||||||
|
apdu.INS = MFDES_ADDITIONAL_FRAME;
|
||||||
|
|
||||||
|
res = DESFIRESendApdu(activate_field, apdu, buf, sizeof(buf), &buflen, &sw);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
sentdatalen += apdu.Lc;
|
||||||
|
if (sw != DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME) || buflen > 0) {
|
||||||
|
if (sentdatalen != datalen)
|
||||||
|
PrintAndLogEx(WARNING, "Tx chaining error. Needs to send: %d but sent: %d", datalen, sentdatalen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100))
|
if (respcode != NULL && ((sw & 0xff00) == 0x9100))
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "mifare/desfire_crypto.h"
|
#include "mifare/desfire_crypto.h"
|
||||||
#include "mifare/mifare4.h"
|
#include "mifare/mifare4.h"
|
||||||
|
|
||||||
|
#define DESFIRE_TX_FRAME_MAX_LEN 54
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const uint8_t id;
|
const uint8_t id;
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue