fix OTP simulation

This commit is contained in:
iceman1001 2025-03-19 15:22:55 +01:00
commit c8cde55a5e
6 changed files with 72 additions and 63 deletions

View file

@ -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);
}
} 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,

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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;