diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f5eacc363..416bf91e4 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -46,6 +46,7 @@ #include "util.h" #include "ticks.h" #include "commonutil.h" +#include "crc16.h" #ifdef WITH_LCD #include "LCD.h" @@ -1630,13 +1631,44 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_SMART_UPLOAD: { // upload file from client + struct p { + uint32_t idx; + uint32_t bytes_in_packet; + uint16_t crc; + uint8_t data[400]; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; uint8_t *mem = BigBuf_get_addr(); - memcpy(mem + packet->oldarg[0], packet->data.asBytes, PM3_CMD_DATA_SIZE); - reply_mix(CMD_ACK, 1, 0, 0, 0, 0); + memcpy(mem + payload->idx, payload->data, payload->bytes_in_packet); + + uint8_t a = 0, b = 0; + compute_crc(CRC_14443_A, mem + payload->idx, payload->bytes_in_packet, &a, &b); + int res = PM3_SUCCESS; + if (payload->crc != (a << 8 | b)) { + DbpString("CRC Failed"); + res = PM3_ESOFT; + } + reply_ng(CMD_SMART_UPLOAD, res, NULL, 0); break; } case CMD_SMART_UPGRADE: { - SmartCardUpgrade(packet->oldarg[0]); + struct p { + uint16_t fw_size; + uint16_t crc; + } PACKED; + struct p *payload = (struct p *)packet->data.asBytes; + + uint8_t *fwdata = BigBuf_get_addr(); + uint8_t a = 0, b = 0; + compute_crc(CRC_14443_A, fwdata, payload->fw_size, &a, &b); + + if (payload->crc != (a << 8 | b)) { + Dbprintf("CRC Failed, 0x[%04x] != 0x[%02x%02x]", payload->crc, a, b); + reply_ng(CMD_SMART_UPGRADE, PM3_ESOFT, NULL, 0); + } else { + SmartCardUpgrade(payload->fw_size); + } + fwdata = NULL; break; } #endif diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 92737214a..085f9e633 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -219,7 +219,7 @@ static bool I2C_WaitForSim(void) { // 8051 speaks with smart card. // 1000*50*3.07 = 153.5ms // 1byte transfer == 1ms with max frame being 256bytes - if (!WaitSCL_H_delay(20 * 1000 * 50)) + if (!WaitSCL_H_delay(10 * 1000 * 50)) return false; return true; @@ -807,7 +807,7 @@ void SmartCardUpgrade(uint64_t arg0) { } // writing takes time. - WaitMS(100); + WaitMS(50); // read res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); @@ -827,7 +827,8 @@ void SmartCardUpgrade(uint64_t arg0) { length -= size; pos += size; } - reply_mix(CMD_ACK, isOK, pos, 0, 0, 0); + + reply_ng(CMD_SMART_UPGRADE, (isOK) ? PM3_SUCCESS : PM3_ESOFT, NULL, 0); LED_C_OFF(); BigBuf_free(); } diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 906a483e7..405bad8db 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -8,12 +8,10 @@ // Proxmark3 RDV40 Smartcard module commands //----------------------------------------------------------------------------- #include "cmdsmartcard.h" - #include #include - -#include "cmdparser.h" // command_t -#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN #include "protocols.h" #include "cmdtrace.h" #include "proxmark3.h" @@ -23,6 +21,7 @@ #include "emv/dump.h" #include "ui.h" #include "fileutils.h" +#include "crc16.h" // crc static int CmdHelp(const char *Cmd); @@ -626,45 +625,72 @@ static int CmdSmartUpgrade(const char *Cmd) { PrintAndLogEx(SUCCESS, "Sim module firmware uploading to PM3"); + PacketResponseNG resp; + //Send to device uint32_t index = 0; uint32_t bytes_sent = 0; uint32_t bytes_remaining = firmware_size; - // fast push mode - conn.block_after_ACK = true; - while (bytes_remaining > 0) { - uint32_t bytes_in_packet = MIN(PM3_CMD_DATA_SIZE, bytes_remaining); - if (bytes_in_packet == bytes_remaining) { - // Disable fast mode on last packet - conn.block_after_ACK = false; - } + + struct { + uint32_t idx; + uint32_t bytes_in_packet; + uint16_t crc; + uint8_t data[400]; + } PACKED upload; + + uint32_t bytes_in_packet = MIN(sizeof(upload.data), bytes_remaining); + + upload.idx = index + bytes_sent; + upload.bytes_in_packet = bytes_in_packet; + memcpy(upload.data, firmware + bytes_sent, bytes_in_packet); + + uint8_t a = 0, b = 0; + compute_crc(CRC_14443_A, upload.data, bytes_in_packet, &a, &b); + upload.crc = (a << 8 | b); + clearCommandBuffer(); - SendCommandOLD(CMD_SMART_UPLOAD, index + bytes_sent, bytes_in_packet, 0, firmware + bytes_sent, bytes_in_packet); - if (!WaitForResponseTimeout(CMD_ACK, NULL, 2000)) { + SendCommandNG(CMD_SMART_UPLOAD, (uint8_t *)&upload, sizeof(upload)); + if (!WaitForResponseTimeout(CMD_SMART_UPLOAD, &resp, 2000)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); free(firmware); return PM3_ETIMEOUT; } - + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "uploading to device failed"); + free(firmware); + return resp.status; + } bytes_remaining -= bytes_in_packet; bytes_sent += bytes_in_packet; PrintAndLogEx(INPLACE, "%d bytes sent", bytes_sent); } - free(firmware); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "Sim module firmware updating, don\'t turn off your PM3!"); - // trigger the firmware upgrade + // trigger the firmware upgrade clearCommandBuffer(); - SendCommandMIX(CMD_SMART_UPGRADE, firmware_size, 0, 0, NULL, 0); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { + struct { + uint16_t fw_size; + uint16_t crc; + } PACKED payload; + payload.fw_size = firmware_size; + + uint8_t a = 0, b = 0; + compute_crc(CRC_14443_A, firmware, firmware_size, &a, &b); + payload.crc = (a << 8 | b); + + free(firmware); + SendCommandNG(CMD_SMART_UPGRADE, (uint8_t *)&payload, sizeof(payload)); + if (!WaitForResponseTimeout(CMD_SMART_UPGRADE, &resp, 2500)) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } - if ((resp.oldarg[0] & 0xFF)) { + + if ((resp.status == PM3_SUCCESS)) { PrintAndLogEx(SUCCESS, "Sim module firmware upgrade " _GREEN_("successful")); PrintAndLogEx(HINT, "run " _YELLOW_("`hw status`") " to validate the fw version "); } else { @@ -814,7 +840,6 @@ static int CmdSmartSetClock(const char *Cmd) { struct { uint32_t new_clk; } PACKED payload; - payload.new_clk = new_clk; clearCommandBuffer();