From c8cde55a5e3c4d27cb4385c824e4ddca12e7205a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 19 Mar 2025 15:22:55 +0100 Subject: [PATCH] fix OTP simulation --- armsrc/iso14443a.c | 30 +++++++----- client/src/cmdhf14a.c | 8 ++-- client/src/cmdhficlass.c | 3 +- client/src/cmdhfmf.c | 4 +- client/src/cmdlft55xx.c | 2 +- client/src/mifare/aiddesfire.c | 88 +++++++++++++++++----------------- 6 files changed, 72 insertions(+), 63 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index bdf59f08e..250b25dce 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1726,11 +1726,21 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin } p_response = NULL; } else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7)) { // Received a WRITE + + p_response = NULL; + // cmd + block + 4 bytes data + 2 bytes crc if (CheckCrc14A(receivedCmd, len)) { uint8_t block = receivedCmd[1]; + // sanity checks + if (block > pages) { + // send NACK 0x0, invalid argument + EmSend4bit(CARD_NACK_IV); + goto jump; + } + // OTP sanity check // Quite a bad one, one should look at all individual bits and see if anyone tries be set as zero // we cheat and do fat 00000000 check instead @@ -1739,23 +1749,20 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin // OTP can't be set back to zero // send NACK 0x0 == invalid argument, EmSend4bit(CARD_NACK_IV); + goto jump; } } - if (block > pages) { - // send NACK 0x0 == invalid argument - EmSend4bit(CARD_NACK_IV); - } else { - // first blocks of emu are header - emlSetMem_xt(&receivedCmd[2], block + (MFU_DUMP_PREFIX_LENGTH / 4), 1, 4); - // send ACK - EmSend4bit(CARD_ACK); - } + // first blocks of emu are header + emlSetMem_xt(&receivedCmd[2], block + (MFU_DUMP_PREFIX_LENGTH / 4), 1, 4); + // send ACK + EmSend4bit(CARD_ACK); + } else { // send NACK 0x1 == crc/parity error EmSend4bit(CARD_NACK_PA); } - p_response = NULL; + goto jump; } else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7)) { // cmd + block + 2 bytes crc if (CheckCrc14A(receivedCmd, len)) { @@ -2002,6 +2009,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin // Count number of other messages after a halt // if (order != ORDER_WUPA && lastorder == ORDER_HALTED) { happened2++; } +jump: cmdsRecvd++; @@ -3239,7 +3247,7 @@ void ReaderIso14443a(PacketCommandNG *c) { } if ((param & ISO14A_APDU) == ISO14A_APDU) { - uint8_t res; + uint8_t res = 0; arg0 = iso14_apdu( cmd, len, diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 7bd292489..1a694bc49 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1206,9 +1206,9 @@ static int CmdExchangeAPDU(bool chainingin, const uint8_t *datain, int datainlen } } - uint16_t cmdc = 0; + uint16_t cmdc = (ISO14A_APDU | ISO14A_NO_DISCONNECT); if (chainingin) { - cmdc = ISO14A_SEND_CHAINING; + cmdc |= ISO14A_SEND_CHAINING; } // "Command APDU" length should be 5+255+1, but javacard's APDU buffer might be smaller - 133 bytes @@ -1216,9 +1216,9 @@ static int CmdExchangeAPDU(bool chainingin, const uint8_t *datain, int datainlen // here length PM3_CMD_DATA_SIZE=512 // timeout must be authomatically set by "get ATS" if (datain) { - SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_APDU | ISO14A_NO_DISCONNECT | cmdc, (datainlen & 0x1FF), 0, datain, datainlen & 0x1FF); + SendCommandMIX(CMD_HF_ISO14443A_READER, cmdc, (datainlen & 0x1FF), 0, datain, (datainlen & 0x1FF)); } else { - SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_APDU | ISO14A_NO_DISCONNECT | cmdc, 0, 0, NULL, 0); + SendCommandMIX(CMD_HF_ISO14443A_READER, cmdc, 0, 0, NULL, 0); } PacketResponseNG resp; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index aa73c7e1c..885c27c1d 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1482,7 +1482,8 @@ static void iclass_decode_credentials(uint8_t *data) { char *pbin = binstr; while (strlen(pbin) && *(++pbin) == '0'); - PrintAndLogEx(SUCCESS, "Binary... %zu - " _GREEN_("%s"), strlen(pbin), pbin); + PrintAndLogEx(SUCCESS, "Binary... " _GREEN_("%s") " ( %zu )", pbin, strlen(pbin)); + PrintAndLogEx(NORMAL, ""); decode_wiegand(top, mid, bot, 0); } diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index fb3d80218..be3eb80ec 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6279,7 +6279,8 @@ static int CmdHF14AMfMAD(const char *Cmd) { if (sector > -1) { // decode it - PrintAndLogEx(INFO, ""); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------------------- " _CYAN_("Wiegand") " ---------------------------"); PrintAndLogEx(INFO, _CYAN_("HID PACS detected")); uint8_t pacs_sector[MFBLOCK_SIZE * 3] = {0}; @@ -6302,7 +6303,6 @@ static int CmdHF14AMfMAD(const char *Cmd) { PrintAndLogEx(SUCCESS, "Binary... " _GREEN_("%s"), pbin); - PrintAndLogEx(INFO, "Wiegand decode"); decode_wiegand(top, mid, bot, 0); } } diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index c38f96bcf..f59679972 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -2303,7 +2303,7 @@ static void printT5x7KnownBlock0(uint32_t b0) { case T55X7_TEXECOM_CONFIG_BLOCK: snprintf(s + strlen(s), sizeof(s) - strlen(s), "Texecom "); break; - case T55X7_BETECH_CONFIG_BLOCK: + case T55X7_BETECH_CONFIG_BLOCK: snprintf(s + strlen(s), sizeof(s) - strlen(s), "Be-Tech "); break; default: diff --git a/client/src/mifare/aiddesfire.c b/client/src/mifare/aiddesfire.c index f1d7609f7..26bf9adf6 100644 --- a/client/src/mifare/aiddesfire.c +++ b/client/src/mifare/aiddesfire.c @@ -94,7 +94,7 @@ typedef enum { const char *nxp_cluster_to_text(uint8_t cluster) { switch (cluster) { case CL_ADMIN: - return "card administration"; + return "Card administration"; case CL_MISC1: case CL_MISC2: case CL_MISC3: @@ -102,40 +102,40 @@ const char *nxp_cluster_to_text(uint8_t cluster) { case CL_MISC5: case CL_MISC6: case CL_MISC7: - return "miscellaneous applications"; + return "Miscellaneous applications"; case CL_AIRLINES: - return "airlines"; + return "Airlines"; case CL_FERRY: - return "ferry traffic"; + return "Ferry traffic"; case CL_RAIL: - return "railway services"; + return "Railway services"; case CL_MISC: - return "miscellaneous applications"; + return "Miscellaneous applications"; case CL_TRANSPORT: - return "transport"; + return "Transport"; case CL_SECURITY: - return "security solutions"; + return "Security solutions"; case CL_CITYTRAFFIC: - return "city traffic"; + return "City traffic"; case CL_CZECH_RAIL: return "Czech Railways"; case CL_BUS: - return "bus services"; + return "Bus services"; case CL_MMT: - return "multi modal transit"; + return "Multi modal transit"; case CL_TAXI: - return "taxi"; + return "Taxi"; case CL_TOLL: - return "road toll"; + return "Road toll"; case CL_GENERIC_TRANS: - return "generic transport"; + return "Generic transport"; case CL_COMPANY_SERVICES: - return "company services"; + return "Company services"; case CL_CITYCARD: - return "city card services"; + return "City card services"; case CL_ACCESS_CONTROL_1: case CL_ACCESS_CONTROL_2: - return "access control & security"; + return "Access control & security"; case CL_VIGIK: return "VIGIK"; case CL_NED_DEFENCE: @@ -145,63 +145,63 @@ const char *nxp_cluster_to_text(uint8_t cluster) { case CL_EU: return "European Union Institutions"; case CL_SKI_TICKET: - return "ski ticketing"; + return "Ski ticketing"; case CL_SOAA: return "SOAA standard for offline access standard"; case CL_ACCESS2: - return "access control & security"; + return "Access control & security"; case CL_FOOD: - return "food"; + return "Food"; case CL_NONFOOD: - return "non-food trade"; + return "Non-food trade"; case CL_HOTEL: - return "hotel"; + return "Hotel"; case CL_LOYALTY: - return "loyalty"; + return "Loyalty"; case CL_AIRPORT: - return "airport services"; + return "Airport services"; case CL_CAR_RENTAL: - return "car rental"; + return "Car rental"; case CL_NED_GOV: return "Dutch government"; case CL_ADMIN2: - return "administration services"; + return "Administration services"; case CL_PURSE: - return "electronic purse"; + return "Electronic purse"; case CL_TV: - return "television"; + return "Television"; case CL_CRUISESHIP: - return "cruise ship"; + return "Cruise ship"; case CL_IOPTA: return "IOPTA"; case CL_METERING: - return "metering"; + return "Metering"; case CL_TELEPHONE: - return "telephone"; + return "Telephone"; case CL_HEALTH: - return "health services"; + return "Health services"; case CL_WAREHOUSE: - return "warehouse"; + return "Warehouse"; case CL_BANKING: - return "banking"; + return "Banking"; case CL_ENTERTAIN: - return "entertainment & sports"; + return "Entertainment & sports"; case CL_PARKING: - return "car parking"; + return "Car parking"; case CL_FLEET: - return "fleet management"; + return "Fleet management"; case CL_FUEL: - return "fuel, gasoline"; + return "Fuel, gasoline"; case CL_INFO: - return "info services"; + return "Info services"; case CL_PRESS: - return "press"; + return "Press"; case CL_NFC: return "NFC Forum"; case CL_COMPUTER: - return "computer"; + return "Computer"; case CL_MAIL: - return "mail"; + return "Mail"; case CL_AMISC: case CL_AMISC1: case CL_AMISC2: @@ -210,11 +210,11 @@ const char *nxp_cluster_to_text(uint8_t cluster) { case CL_AMISC5: case CL_AMISC6: case CL_AMISC7: - return "miscellaneous applications"; + return "Miscellaneous applications"; default: break; } - return "reserved"; + return "Reserved"; } static json_t *df_known_aids = NULL;