diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 2c6ace8ee..482d126a4 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -954,6 +954,16 @@ static void PacketReceived(PacketCommandNG *packet) { EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd); break; } + case CMD_LF_EM4X_PROTECTWORD: { + struct p { + uint32_t password; + uint32_t data; + uint8_t usepwd; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + EM4xProtectWord(payload->data, payload->password, payload->usepwd); + break; + } case CMD_LF_AWID_WATCH: { uint32_t high, low; int res = lf_awid_watch(0, &high, &low); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b68e54bbc..b2126fc76 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2369,6 +2369,7 @@ int copy_em410x_to_t55xx(uint8_t card, uint8_t clock, uint32_t id_hi, uint32_t i #define FWD_CMD_LOGIN 0xC #define FWD_CMD_WRITE 0xA #define FWD_CMD_READ 0x9 +#define FWD_CMD_PROTECT 0x3 #define FWD_CMD_DISABLE 0x5 static uint8_t forwardLink_data[64]; //array of forwarded bits @@ -2573,9 +2574,9 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { SendForward(len); // Wait 20ms for write to complete? - WaitMS(7); + WaitUS(10820); // tPC+tWEE - DoPartialAcquisition(20, false, 6000, 1000); + DoPartialAcquisition(0, false, 6000, 1000); StopTicks(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -2583,6 +2584,42 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { LEDsoff(); } +void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) { + + StartTicks(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + WaitMS(50); + + LED_A_ON(); + + // clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); + + /* should we read answer from Logincommand? + * + * should receive + * 0000 1010 ok. + * 0000 0001 fail + **/ + if (usepwd) EM4xLogin(pwd); + + forward_ptr = forwardLink_data; + uint8_t len = Prepare_Cmd(FWD_CMD_PROTECT); + len += Prepare_Data(data & 0xFFFF, data >> 16); + + SendForward(len); + + // Wait 20ms for write to complete? + WaitUS(13640); // tPC+tPR + + DoPartialAcquisition(0, false, 6000, 1000); + + StopTicks(); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + reply_ng(CMD_LF_EM4X_PROTECTWORD, PM3_SUCCESS, NULL, 0); + LEDsoff(); +} + /* Reading COTAG. diff --git a/armsrc/lfops.h b/armsrc/lfops.h index 0ac8066af..1c191d65d 100644 --- a/armsrc/lfops.h +++ b/armsrc/lfops.h @@ -58,6 +58,7 @@ void TurnReadLFOn(uint32_t delay); void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd); +void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd); void Cotag(uint32_t arg0); void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c); diff --git a/client/src/cmdlfem4x.c b/client/src/cmdlfem4x.c index c26bd2602..aa15c1fe9 100644 --- a/client/src/cmdlfem4x.c +++ b/client/src/cmdlfem4x.c @@ -164,7 +164,7 @@ static int usage_lf_em4x05_write(void) { PrintAndLogEx(NORMAL, "Usage: lf em 4x05_write [h]
"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - this help"); - PrintAndLogEx(NORMAL, " address - memory address to write to. (0-15)"); + PrintAndLogEx(NORMAL, " address - memory address to write to. (0-13, 99 for Protection Words)"); PrintAndLogEx(NORMAL, " data - data to write (hex)"); PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)"); PrintAndLogEx(NORMAL, "Examples:"); @@ -857,7 +857,6 @@ static int demodEM4x05resp(uint32_t *word) { *word = 0; if (detectASK_MAN() && doPreambleSearch(&idx)) return setDemodBufferEM(word, idx); - if (detectASK_BI() && doPreambleSearch(&idx)) return setDemodBufferEM(word, idx); @@ -1101,37 +1100,62 @@ static int CmdEM4x05Write(const char *Cmd) { data = param_get32ex(Cmd, 1, 0, 16); pwd = param_get32ex(Cmd, 2, 0xFFFFFFFF, 16); - if (addr > 15) { - PrintAndLogEx(NORMAL, "Address must be between 0 and 15"); + if ((addr > 13) && (addr != 99)) { + PrintAndLogEx(NORMAL, "Address must be between 0 and 13"); return PM3_EINVARG; } - if (pwd == 0xFFFFFFFF) - PrintAndLogEx(NORMAL, "Writing address %d data %08X", addr, data); - else { + if (pwd == 0xFFFFFFFF) { + if (addr == 99) + PrintAndLogEx(NORMAL, "Writing protection words data %08X", addr, data); + else + PrintAndLogEx(NORMAL, "Writing address %d data %08X", addr, data); + } else { usePwd = true; - PrintAndLogEx(NORMAL, "Writing address %d data %08X using password %08X", addr, data, pwd); + if (addr == 99) + PrintAndLogEx(NORMAL, "Writing protection words data %08X using password %08X", addr, data, pwd); + else + PrintAndLogEx(NORMAL, "Writing address %d data %08X using password %08X", addr, data, pwd); } - struct { - uint32_t password; - uint32_t data; - uint8_t address; - uint8_t usepwd; - } PACKED payload; + if (addr == 99) { // set Protect Words + struct { + uint32_t password; + uint32_t data; + uint8_t usepwd; + } PACKED payload; - payload.password = pwd; - payload.data = data; - payload.address = addr; - payload.usepwd = usePwd; + payload.password = pwd; + payload.data = data; + payload.usepwd = usePwd; - clearCommandBuffer(); - SendCommandNG(CMD_LF_EM4X_WRITEWORD, (uint8_t *)&payload, sizeof(payload)); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_LF_EM4X_WRITEWORD, &resp, 2000)) { - PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); - return PM3_ETIMEOUT; + clearCommandBuffer(); + SendCommandNG(CMD_LF_EM4X_PROTECTWORD, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_LF_EM4X_PROTECTWORD, &resp, 2000)) { + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); + return PM3_ETIMEOUT; + } + } else { + struct { + uint32_t password; + uint32_t data; + uint8_t address; + uint8_t usepwd; + } PACKED payload; + + payload.password = pwd; + payload.data = data; + payload.address = addr; + payload.usepwd = usePwd; + + clearCommandBuffer(); + SendCommandNG(CMD_LF_EM4X_WRITEWORD, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_LF_EM4X_WRITEWORD, &resp, 2000)) { + PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); + return PM3_ETIMEOUT; + } } - if (!downloadSamplesEM()) return PM3_ENODATA; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 6cacc5ef1..e96c58984 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -486,6 +486,7 @@ typedef struct { #define CMD_LF_PCF7931_WRITE 0x0223 #define CMD_LF_EM4X_READWORD 0x0218 #define CMD_LF_EM4X_WRITEWORD 0x0219 +#define CMD_LF_EM4X_PROTECTWORD 0x021B #define CMD_LF_IO_WATCH 0x021A #define CMD_LF_EM410X_WATCH 0x021C #define CMD_LF_EM4X50_INFO 0x0240