diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index befa56c6c..0f48038b1 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -381,19 +381,45 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext *ctx, uint8 uint32_t i = 1; uint8_t rcode = 0xff; - uint8_t cdata[255] = {0}; + uint8_t cdata[1024] = {0}; uint32_t cdatalen = 0; cdata[0] = cmd; memcpy(&cdata[1], data, datalen); cdatalen = datalen + 1; - int res = DESFIRESendRaw(activate_field, cdata, cdatalen, 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; + int res = 0; + size_t len = 0; + // tx chaining + size_t sentdatalen = 0; + 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 (splitbysize) { resp[0] = buflen; diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 004a452f9..8933e7e10 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -19,6 +19,8 @@ #include "mifare/desfire_crypto.h" #include "mifare/mifare4.h" +#define DESFIRE_TX_FRAME_MAX_LEN 54 + typedef struct { const uint8_t id; const char *text;