diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 0f48038b1..d97dbe16a 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -411,6 +411,7 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext *ctx, uint8 PrintAndLogEx(DEBUG, "error DESFIRESendRaw %s", DesfireGetErrorString(res, &ssw)); return res; } + sentdatalen += len; if (rcode != MFDES_ADDITIONAL_FRAME || buflen > 0) { if (sentdatalen != cdatalen) @@ -494,10 +495,31 @@ static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, uint8_t apdu.P2 = 0; apdu.data = data; - int res = DESFIRESendApdu(activate_field, apdu, buf, sizeof(buf), &buflen, &sw); - if (res != PM3_SUCCESS) { - PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw)); - return res; + int res = 0; + // tx chaining + size_t sentdatalen = 0; + 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))