diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 95b42982a..cc1d299f3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1023,7 +1023,10 @@ static void PacketReceived(PacketCommandNG *packet) { em4x50_read((em4x50_data_t *)packet->data.asBytes); break; } - + case CMD_LF_EM4X50_WIPE: { + em4x50_wipe((em4x50_data_t *)packet->data.asBytes); + break; + } #endif #ifdef WITH_ISO15693 diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index ddc297591..8344f7542 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -1028,3 +1028,61 @@ void em4x50_write_password(em4x50_data_t *etd) { lf_finalize(); reply_ng(CMD_ACK, bsuccess, 0, 0); } + +void em4x50_wipe(em4x50_data_t *etd) { + + // set all data of EM4x50 tag to 0x0 including password + + bool bsuccess = false; + uint8_t zero[4] = {0, 0, 0, 0}; + uint8_t addresses[4] = {0, 0, EM4X50_NO_WORDS - 3, 1}; + + init_tag(); + em4x50_setup_read(); + + // set gHigh and gLow + if (get_signalproperties() && find_em4x50_tag()) { + + // login first + if (login(etd->password)) { + + // write 0x0 to each address but ignore addresses + // 0 -> password, 32 -> serial, 33 -> uid + // writing 34 words takes about 3.6 seconds -> high timeout needed + for (int i = 1; i <= EM4X50_NO_WORDS - 3; i++) + write(zero, i); + + // to verify result reset EM4x50 + if (reset()) { + + // login not necessary because protectd word has been set to 0 + // -> no read protected words + // -> selective read can be called immediately + if (selective_read(addresses)) { + + // check if everything is zero + bsuccess = true; + for (int i = 1; i <= EM4X50_NO_WORDS - 3; i++) + for (int j = 0; j < 4; j++) + bsuccess &= (tag.sectors[i][j] == 0) ? true : false; + + } + + if (bsuccess) { + + // so far everything is fine + // last task: reset password + if (login(etd->password)) + bsuccess = write_password(etd->password, zero); + + // verify by login with new password + if (bsuccess) + bsuccess = login(zero); + } + } + } + } + + lf_finalize(); + reply_ng(CMD_ACK, bsuccess, (uint8_t *)tag.sectors, 238); +} diff --git a/armsrc/em4x50.h b/armsrc/em4x50.h index d786e61c0..f9f1375f2 100644 --- a/armsrc/em4x50.h +++ b/armsrc/em4x50.h @@ -21,5 +21,6 @@ void em4x50_info(em4x50_data_t *etd); void em4x50_write(em4x50_data_t *etd); void em4x50_write_password(em4x50_data_t *etd); void em4x50_read(em4x50_data_t *etd); +void em4x50_wipe(em4x50_data_t *etd); #endif /* EM4X50_H */ diff --git a/client/src/cmdlfem4x.c b/client/src/cmdlfem4x.c index 8031ab20d..bb07adaaa 100644 --- a/client/src/cmdlfem4x.c +++ b/client/src/cmdlfem4x.c @@ -1400,6 +1400,7 @@ static command_t CommandTable[] = { {"4x50_write", CmdEM4x50Write, IfPm3EM4x50, "write word data to EM4x50"}, {"4x50_write_password", CmdEM4x50WritePassword, IfPm3EM4x50, "change passwword of EM4x50 tag"}, {"4x50_read", CmdEM4x50Read, IfPm3EM4x50, "read word data from EM4x50"}, + {"4x50_wipe", CmdEM4x50Wipe, IfPm3EM4x50, "wipe data from EM4x50"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index 1009f3bb6..8198bdc74 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -85,6 +85,18 @@ static int usage_lf_em4x50_dump(void) { PrintAndLogEx(NORMAL, _YELLOW_(" lf em 4x50_dump f card_nnn p 11223344")); return PM3_SUCCESS; } +static int usage_lf_em4x50_wipe(void) { + PrintAndLogEx(NORMAL, "Wipe data from EM4x50 tag. Tag must be on antenna. "); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, "Usage: lf em 4x50_wipe [h] [p ]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h - this help"); + PrintAndLogEx(NORMAL, " p - password (hex)"); + PrintAndLogEx(NORMAL, "Examples:"); + PrintAndLogEx(NORMAL, _YELLOW_(" lf em 4x50_wwipe p 11223344")); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} static void prepare_result(const uint8_t *byte, int fwr, int lwr, em4x50_word_t *words) { @@ -672,3 +684,57 @@ int CmdEM4x50Dump(const char *Cmd) { //saveFileJSON... return PM3_SUCCESS; } + +int CmdEM4x50Wipe(const char *Cmd) { + + // fills EM4x50 tag with zeros including password + + bool errors = false, bpwd = false; + uint8_t cmdp = 0; + em4x50_data_t etd; + PacketResponseNG resp; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'h': + return usage_lf_em4x50_wipe(); + + case 'p': + if (param_gethex(Cmd, cmdp + 1, etd.password, 8)) { + PrintAndLogEx(FAILED, "\npassword has to be 8 hex symbols\n"); + return PM3_EINVARG; + } + bpwd = true; + cmdp += 2; + break; + + default: + PrintAndLogEx(WARNING, "\nUnknown parameter '%c'\n", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + + if (errors || !bpwd) + return usage_lf_em4x50_wipe(); + + clearCommandBuffer(); + SendCommandNG(CMD_LF_EM4X50_WIPE, (uint8_t *)&etd, sizeof(etd)); + + if (!WaitForResponseTimeout(CMD_ACK, &resp, 2*TIMEOUT)) { + PrintAndLogEx(WARNING, "\ntimeout while waiting for reply.\n"); + return PM3_ETIMEOUT; + } + + // print response + bool isOK = resp.status; + if (isOK) { + PrintAndLogEx(SUCCESS,"\nwiping data " _GREEN_("ok") "\n"); + } else { + PrintAndLogEx(FAILED,"\nwiping data " _RED_("failed") "\n"); + return PM3_ESOFT; + } + + return PM3_SUCCESS; +} diff --git a/client/src/cmdlfem4x50.h b/client/src/cmdlfem4x50.h index 4519abbb4..01417aa1e 100644 --- a/client/src/cmdlfem4x50.h +++ b/client/src/cmdlfem4x50.h @@ -23,4 +23,6 @@ int CmdEM4x50Write(const char *Cmd); int CmdEM4x50WritePassword(const char *Cmd); int CmdEM4x50Read(const char *Cmd); int CmdEM4x50Dump(const char *Cmd); +int CmdEM4x50Wipe(const char *Cmd); + #endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 117eea672..9e20ab9c1 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -406,6 +406,7 @@ typedef struct { #define CMD_LF_EM4X50_WRITE 0x0241 #define CMD_LF_EM4X50_WRITE_PASSWORD 0x0242 #define CMD_LF_EM4X50_READ 0x0243 +#define CMD_LF_EM4X50_WIPE 0x0244 // Sampling configuration for LF reader/sniffer #define CMD_LF_SAMPLING_SET_CONFIG 0x021D #define CMD_LF_FSK_SIMULATE 0x021E