diff --git a/client/comms.c b/client/comms.c index 5aa704728..6fd41ecad 100644 --- a/client/comms.c +++ b/client/comms.c @@ -136,7 +136,7 @@ static void SendCommandNG_internal(uint16_t cmd, uint8_t *data, size_t len, bool txBufferNG.pre.ng = ng; txBufferNG.pre.length = len; txBufferNG.pre.cmd = cmd; - if ( len > 0 && data ) + if (len > 0 && data) memcpy(&txBufferNG.data, data, len); if ((conn.send_via_fpc_usart && conn.send_with_crc_on_fpc) || ((!conn.send_via_fpc_usart) && conn.send_with_crc_on_usb)) { diff --git a/client/emv/apduinfo.c b/client/emv/apduinfo.c index 79b502816..3b3664e4b 100644 --- a/client/emv/apduinfo.c +++ b/client/emv/apduinfo.c @@ -319,39 +319,39 @@ const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2) { int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { ExtAPDUHeader *hapdu = (ExtAPDUHeader *)data; - + apdu->cla = hapdu->cla; apdu->ins = hapdu->ins; apdu->p1 = hapdu->p1; apdu->p2 = hapdu->p2; - + apdu->lc = 0; apdu->data = NULL; apdu->le = 0; apdu->extended_apdu = false; apdu->case_type = 0x00; - + uint8_t b0 = hapdu->lc[0]; - + // case 1 if (len == 4) { apdu->case_type = 0x01; } - - // case 2S (Le) + + // case 2S (Le) if (len == 5) { apdu->case_type = 0x02; apdu->le = b0; if (!apdu->le) apdu->le = 0x100; } - + // case 3S (Lc + data) if (len == 5U + b0 && b0 != 0) { apdu->case_type = 0x03; apdu->lc = b0; } - + // case 4S (Lc + data + Le) if (len == 5U + b0 + 1U && b0 != 0) { apdu->case_type = 0x04; @@ -360,12 +360,12 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { if (!apdu->le) apdu->le = 0x100; } - + // extended length apdu if (len >= 7 && b0 == 0) { uint16_t extlen = (hapdu->lc[1] << 8) + hapdu->lc[2]; - - // case 2E (Le) - extended + + // case 2E (Le) - extended if (len == 7) { apdu->case_type = 0x12; apdu->extended_apdu = true; @@ -373,59 +373,65 @@ int APDUDecode(uint8_t *data, size_t len, APDUStruct *apdu) { if (!apdu->le) apdu->le = 0x10000; } - - // case 3E (Lc + data) - extended - if (len == 7U + extlen) { + + // case 3E (Lc + data) - extended + if (len == 7U + extlen) { apdu->case_type = 0x13; apdu->extended_apdu = true; apdu->lc = extlen; } - // case 4E (Lc + data + Le) - extended 2-byte Le - if (len == 7U + extlen + 2U) { + // case 4E (Lc + data + Le) - extended 2-byte Le + if (len == 7U + extlen + 2U) { apdu->case_type = 0x14; apdu->extended_apdu = true; apdu->lc = extlen; apdu->le = (data[len - 2] << 8) + data[len - 1]; - if (!apdu->le) - apdu->le = 0x10000; + if (!apdu->le) + apdu->le = 0x10000; } - // case 4E (Lc + data + Le) - extended 3-byte Le - if (len == 7U + extlen + 3U && data[len - 3] == 0) { + // case 4E (Lc + data + Le) - extended 3-byte Le + if (len == 7U + extlen + 3U && data[len - 3] == 0) { apdu->case_type = 0x24; apdu->extended_apdu = true; apdu->lc = extlen; apdu->le = (data[len - 2] << 8) + data[len - 1]; - if (!apdu->le) - apdu->le = 0x10000; + if (!apdu->le) + apdu->le = 0x10000; } } - + if (!apdu->case_type) return 1; - + if (apdu->lc) { if (apdu->extended_apdu) { apdu->data = data + 7; } else { apdu->data = data + 5; } - - } - + + } + return 0; } int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len) { + if (len) + *len = 0; + + if (apdu->le > 0x10000 || apdu->lc != 0xffff) + return 1; + size_t dptr = 0; data[dptr++] = apdu->cla; data[dptr++] = apdu->ins; data[dptr++] = apdu->p1; data[dptr++] = apdu->p2; - + if (apdu->lc) { - if (apdu->extended_apdu || apdu->lc > 0xff || apdu->le > 0xff) { + if (apdu->extended_apdu || apdu->lc > 0xff || apdu->le > 0x100) { data[dptr++] = 0x00; data[dptr++] = (apdu->lc >> 8) & 0xff; data[dptr++] = (apdu->lc) & 0xff; @@ -436,24 +442,34 @@ int APDUEncode(APDUStruct *apdu, uint8_t *data, size_t *len) { data[dptr++] = apdu->lc; memmove(&data[dptr], apdu->data, apdu->lc); dptr += apdu->lc; - } - } - + } + } + if (apdu->le) { if (apdu->extended_apdu) { - data[dptr++] = 0x00; - data[dptr++] = (apdu->le >> 8) & 0xff; - data[dptr++] = (apdu->le) & 0xff; + if (apdu->le != 0x10000) { + data[dptr++] = 0x00; + data[dptr++] = (apdu->le >> 8) & 0xff; + data[dptr++] = (apdu->le) & 0xff; + } else { + data[dptr++] = 0x00; + data[dptr++] = 0x00; + data[dptr++] = 0x00; + } } else { - data[dptr++] = apdu->le; - } + if (apdu->le != 0x100) + data[dptr++] = apdu->le; + else + data[dptr++] = 0x00; + } } - - *len = dptr; + + if (len) + *len = dptr; return 0; } void APDUPrint(APDUStruct apdu) { - PrintAndLogEx(INFO, "apdu: %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%d le=%d\n", - apdu.extended_apdu ? "[e]":"", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le); + PrintAndLogEx(INFO, "apdu: %scase=%02x cla=%02x ins=%02x p1=%02x p2=%02x Lc=%d Le=%d\n", + apdu.extended_apdu ? "[e]" : "", apdu.case_type, apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.lc, apdu.le); } diff --git a/client/emv/apduinfo.h b/client/emv/apduinfo.h index e510492cf..7f1e8fd72 100644 --- a/client/emv/apduinfo.h +++ b/client/emv/apduinfo.h @@ -32,8 +32,7 @@ typedef struct { const APDUCode *GetAPDUCode(uint8_t sw1, uint8_t sw2); const char *GetAPDUCodeDescription(uint8_t sw1, uint8_t sw2); -typedef struct -{ +typedef struct { uint8_t cla; uint8_t ins; uint8_t p1; @@ -41,8 +40,7 @@ typedef struct uint8_t lc[3]; } __attribute__((packed)) ExtAPDUHeader; -typedef struct -{ +typedef struct { uint8_t cla; uint8_t ins; uint8_t p1; diff --git a/client/util.c b/client/util.c index 568a022f1..8121a7ed3 100644 --- a/client/util.c +++ b/client/util.c @@ -170,8 +170,8 @@ bool CheckStringIsHEXValue(const char *value) { void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, const size_t hex_max_len, const size_t min_str_len, const size_t spaces_between, bool uppercase) { - if (buf == NULL ) return; - + if (buf == NULL) return; + char *tmp = (char *)buf; size_t i; memset(tmp, 0x00, hex_max_len); @@ -197,16 +197,16 @@ void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex // printing and converting functions void print_hex(const uint8_t *data, const size_t len) { - if (data == NULL || len == 0 ) return; - + if (data == NULL || len == 0) return; + for (size_t i = 0; i < len; i++) printf("%02x ", data[i]); printf("\n"); } void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { - if (data == NULL || len == 0 ) return; - + if (data == NULL || len == 0) return; + int rownum = 0; printf("[%02d] | ", rownum); for (size_t i = 0; i < len; ++i) {