diff --git a/armsrc/Standalone/hf_aveful.c b/armsrc/Standalone/hf_aveful.c index 51d998736..695ea9254 100644 --- a/armsrc/Standalone/hf_aveful.c +++ b/armsrc/Standalone/hf_aveful.c @@ -246,7 +246,7 @@ void RunMod(void) { FLAG_SET_UID_IN_DATA(flags, 7); Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state."); - SimulateIso14443aTag(7, flags, card.uid, 0, NULL, 0, false, false); + SimulateIso14443aTag(7, flags, card.uid, 0); // Go back to search state if user presses pm3-button state = STATE_SEARCH; diff --git a/armsrc/Standalone/hf_craftbyte.c b/armsrc/Standalone/hf_craftbyte.c index 736e89aca..d12c5c5dd 100644 --- a/armsrc/Standalone/hf_craftbyte.c +++ b/armsrc/Standalone/hf_craftbyte.c @@ -89,22 +89,22 @@ void RunMod(void) { Dbprintf("Starting simulation, press " _GREEN_("pm3 button") " to stop and go back to search state."); if (card.sak == 0x08 && card.atqa[0] == 0x04 && card.atqa[1] == 0) { DbpString("Mifare Classic 1k"); - SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false); + SimulateIso14443aTag(1, flags, card.uid, 0); } else if (card.sak == 0x08 && card.atqa[0] == 0x44 && card.atqa[1] == 0) { DbpString("Mifare Classic 4k "); - SimulateIso14443aTag(8, flags, card.uid, 0, NULL, 0, false, false); + SimulateIso14443aTag(8, flags, card.uid, 0); } else if (card.sak == 0x00 && card.atqa[0] == 0x44 && card.atqa[1] == 0) { DbpString("Mifare Ultralight"); - SimulateIso14443aTag(2, flags, card.uid, 0, NULL, 0, false, false); + SimulateIso14443aTag(2, flags, card.uid, 0); } else if (card.sak == 0x20 && card.atqa[0] == 0x04 && card.atqa[1] == 0x03) { DbpString("Mifare DESFire"); - SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false); + SimulateIso14443aTag(3, flags, card.uid, 0); } else if (card.sak == 0x20 && card.atqa[0] == 0x44 && card.atqa[1] == 0x03) { DbpString("Mifare DESFire Ev1/Plus/JCOP"); - SimulateIso14443aTag(3, flags, card.uid, 0, NULL, 0, false, false); + SimulateIso14443aTag(3, flags, card.uid, 0); } else { Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation"); - SimulateIso14443aTag(1, flags, card.uid, 0, NULL, 0, false, false); + SimulateIso14443aTag(1, flags, card.uid, 0); } // Go back to search state if user presses pm3-button diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index 83ad1999a..079ae7c3b 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -253,25 +253,25 @@ void RunMod(void) { if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0) { DbpString("Mifare Classic 1k"); - SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false); + SimulateIso14443aTag(1, flags, data, 0); } else if (uids[selected].sak == 0x18 && uids[selected].atqa[0] == 0x02 && uids[selected].atqa[1] == 0) { DbpString("Mifare Classic 4k (4b uid)"); - SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false); + SimulateIso14443aTag(8, flags, data, 0); } else if (uids[selected].sak == 0x08 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) { DbpString("Mifare Classic 4k (7b uid)"); - SimulateIso14443aTag(8, flags, data, 0, NULL, 0, false, false); + SimulateIso14443aTag(8, flags, data, 0); } else if (uids[selected].sak == 0x00 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0) { DbpString("Mifare Ultralight"); - SimulateIso14443aTag(2, flags, data, 0, NULL, 0, false, false); + SimulateIso14443aTag(2, flags, data, 0); } else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x04 && uids[selected].atqa[1] == 0x03) { DbpString("Mifare DESFire"); - SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false); + SimulateIso14443aTag(3, flags, data, 0); } else if (uids[selected].sak == 0x20 && uids[selected].atqa[0] == 0x44 && uids[selected].atqa[1] == 0x03) { DbpString("Mifare DESFire Ev1/Plus/JCOP"); - SimulateIso14443aTag(3, flags, data, 0, NULL, 0, false, false); + SimulateIso14443aTag(3, flags, data, 0); } else { Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation"); - SimulateIso14443aTag(1, flags, data, 0, NULL, 0, false, false); + SimulateIso14443aTag(1, flags, data, 0); } } else if (button_pressed == BUTTON_SINGLE_CLICK) { diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 88ce070a8..a2ad9b86b 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1779,13 +1779,17 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t uid[10]; uint8_t exitAfter; uint8_t rats[20]; - bool ulauth_z1; - bool ulauth_z2; + uint8_t ulauth_1a1_len; + uint8_t ulauth_1a2_len; + uint8_t ulauth_1a1[16]; + uint8_t ulauth_1a2[16]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - SimulateIso14443aTag(payload->tagtype, payload->flags, payload->uid, + SimulateIso14443aTagEx(payload->tagtype, payload->flags, payload->uid, payload->exitAfter, payload->rats, sizeof(payload->rats), - payload->ulauth_z1, payload->ulauth_z2); // ## Simulate iso14443a tag - pass tag type & UID + payload->ulauth_1a1, payload->ulauth_1a1_len, + payload->ulauth_1a2, payload->ulauth_1a2_len + ); // ## Simulate iso14443a tag - pass tag type & UID break; } case CMD_HF_ISO14443A_SIM_AID: { diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index e7ce4b7d9..7b486152f 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1621,9 +1621,14 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, // response to send, and send it. // 'hf 14a sim' //----------------------------------------------------------------------------- -void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads, - uint8_t *ats, size_t ats_len, bool ulauth_z1, bool ulauth_z2) { +void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads) { + SimulateIso14443aTagEx(tagType, flags, useruid, exitAfterNReads, NULL, 0, NULL, 0, NULL, 0); +} +void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads, + uint8_t *ats, size_t ats_len, + uint8_t *ulauth_1a1, uint8_t ulauth_1a1_len, + uint8_t *ulauth_1a2, uint8_t ulauth_1a2_len) { #define ATTACK_KEY_COUNT 16 #define ULC_TAG_NONCE "\x01\x02\x03\x04\x05\x06\x07\x08" @@ -2065,8 +2070,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin // our very random TAG NONCE memcpy(dynamic_response_info.response + 1, ULC_TAG_NONCE, 8); - if (ulauth_z1) { - memset(dynamic_response_info.response + 1, 0, 8); + if (ulauth_1a1_len == 8 && ulauth_1a1 != NULL) { + memcpy(dynamic_response_info.response + 1, ulauth_1a1, ulauth_1a1_len); } else { // encrypt TAG NONCE tdes_nxp_send(dynamic_response_info.response + 1, dynamic_response_info.response + 1, 8, ulc_key, ulc_iv, 2); @@ -2104,9 +2109,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin // OK response dynamic_response_info.response[0] = 0x00; - if (ulauth_z2) { - // try empty auth but with correct CRC and 0x00 command - memset(dynamic_response_info.response + 1, 0, 8); + if (ulauth_1a2_len == 8 && ulauth_1a2 != NULL) { + memcpy(dynamic_response_info.response + 1, ulauth_1a2, ulauth_1a2_len); } else { // rol RndA rol(rnd_ab, 8); @@ -2139,8 +2143,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin memcpy(dynamic_response_info.response + 1, ULC_TAG_NONCE, 8); memcpy(dynamic_response_info.response + 9, ULC_TAG_NONCE, 8); - if (ulauth_z1) { - memset(dynamic_response_info.response + 1, 0, 16); + if (ulauth_1a1_len == 16 && ulauth_1a1 != NULL) { + memcpy(dynamic_response_info.response + 1, ulauth_1a1, ulauth_1a1_len); } else { // encrypt TAG NONCE aes128_nxp_send(dynamic_response_info.response + 1, dynamic_response_info.response + 1, 16, ulc_key, ulc_iv); @@ -2180,9 +2184,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uin // OK response dynamic_response_info.response[0] = 0x00; - if (ulauth_z2) { - // try empty auth but with correct CRC and 0x00 command - memset(dynamic_response_info.response + 1, 0, 16); + if (ulauth_1a2_len == 16 && ulauth_1a2 != NULL) { + memcpy(dynamic_response_info.response + 1, ulauth_1a2, ulauth_1a2_len); } else { // rol RndA rol(rnd_ab, 16); diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 279441910..c9efbf118 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -142,8 +142,12 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time); RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time); void RAMFUNC SniffIso14443a(uint8_t param); -void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads, - uint8_t *ats, size_t ats_len, bool ulauth_z1, bool ulauth_z2); +void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads); + +void SimulateIso14443aTagEx(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads, + uint8_t *ats, size_t ats_len, + uint8_t *ulauth_1a1, uint8_t ulauth_1a1_len, + uint8_t *ulauth_1a2, uint8_t ulauth_1a2_len); void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid, uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len, diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 3d0351c67..6fc8b0344 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -921,8 +921,8 @@ int CmdHF14ASim(const char *Cmd) { arg_lit0("x", NULL, "Performs the 'reader attack', nr/ar attack against a reader"), arg_lit0(NULL, "sk", "Fill simulator keys from found keys"), arg_lit0("v", "verbose", "verbose output"), - arg_lit0(NULL, "z1", "ULC/ULAES Auth - all zero handshake part 1"), - arg_lit0(NULL, "z2", "ULC/ULAES Auth - all zero handshake part 2"), + arg_str0(NULL, "1a1", "", "<8|16> hex bytes ULC/ULAES Auth reply step1: ek(RndB)"), + arg_str0(NULL, "1a2", "", "<8|16> hex bytes ULC/ULAES Auth reply step2: ek(RndA')"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -956,11 +956,53 @@ int CmdHF14ASim(const char *Cmd) { bool setEmulatorMem = arg_get_lit(ctx, 5); bool verbose = arg_get_lit(ctx, 6); - bool ulauth_z1 = arg_get_lit(ctx, 7); - bool ulauth_z2 = arg_get_lit(ctx, 8); - + int ulauth_1a1_len = 0; + int ulauth_1a2_len = 0; + uint8_t ulauth_1a1[16] = {0}; + uint8_t ulauth_1a2[16] = {0}; + CLIGetHexWithReturn(ctx, 7, ulauth_1a1, &ulauth_1a1_len); + CLIGetHexWithReturn(ctx, 8, ulauth_1a2, &ulauth_1a2_len); CLIParserFree(ctx); + if (ulauth_1a1_len > 0) { + switch (tagtype) { + case 13: // ULC + if (ulauth_1a1_len != 8) { + PrintAndLogEx(ERR, "ULC --1a1 length must be 8 bytes"); + return PM3_EINVARG; + } + break; + case 14: // ULAES + if (ulauth_1a1_len != 16) { + PrintAndLogEx(ERR, "ULAES --1a1 length must be 16 bytes"); + return PM3_EINVARG; + } + break; + default: + PrintAndLogEx(ERR, "--1a1 option is only valid for tag types 13 (ULC) and 14 (ULAES)"); + return PM3_EINVARG; + } + } + if (ulauth_1a2_len > 0) { + switch (tagtype) { + case 13: // ULC + if (ulauth_1a2_len != 8) { + PrintAndLogEx(ERR, "ULC --1a2 length must be 8 bytes"); + return PM3_EINVARG; + } + break; + case 14: // ULAES + if (ulauth_1a2_len != 16) { + PrintAndLogEx(ERR, "ULAES --1a2 length must be 16 bytes"); + return PM3_EINVARG; + } + break; + default: + PrintAndLogEx(ERR, "--1a2 option is only valid for tag types 13 (ULC) and 14 (ULAES)"); + return PM3_EINVARG; + } + } + if (tagtype > 14) { PrintAndLogEx(ERR, "Undefined tag %d", tagtype); return PM3_EINVARG; @@ -976,16 +1018,20 @@ int CmdHF14ASim(const char *Cmd) { uint8_t uid[10]; uint8_t exitAfter; uint8_t rats[20]; - bool ulauth_z1; - bool ulauth_z2; + uint8_t ulauth_1a1_len; + uint8_t ulauth_1a2_len; + uint8_t ulauth_1a1[16]; + uint8_t ulauth_1a2[16]; } PACKED payload; payload.tagtype = tagtype; payload.flags = flags; payload.exitAfter = exitAfterNReads; - payload.ulauth_z1 = ulauth_z1; - payload.ulauth_z2 = ulauth_z2; + payload.ulauth_1a1_len = ulauth_1a1_len; + payload.ulauth_1a2_len = ulauth_1a2_len; memcpy(payload.uid, uid, uid_len); + memcpy(payload.ulauth_1a1, ulauth_1a1, ulauth_1a1_len); + memcpy(payload.ulauth_1a2, ulauth_1a2, ulauth_1a2_len); clearCommandBuffer(); SendCommandNG(CMD_HF_ISO14443A_SIMULATE, (uint8_t *)&payload, sizeof(payload)); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 92c798298..f3af17d6a 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -4125,8 +4125,8 @@ static int CmdHF14AMfUSim(const char *Cmd) { arg_str0("u", "uid", "", "<4|7|10> hex bytes UID"), arg_int0("n", "num", "", "Exit simulation after blocks. 0 = infinite"), arg_lit0("v", "verbose", "Verbose output"), - arg_lit0(NULL, "z1", "ULC/ULAES Auth - all zero handshake part 1"), - arg_lit0(NULL, "z2", "ULC/ULAES Auth - all zero handshake part 2"), + arg_str0(NULL, "1a1", "", "<8|16> hex bytes ULC/ULAES Auth reply step1: ek(RndB)"), + arg_str0(NULL, "1a2", "", "<8|16> hex bytes ULC/ULAES Auth reply step2: ek(RndA')"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false);