EM4x05: add support for Protect command

This commit is contained in:
Philippe Teuwen 2020-10-07 18:38:47 +02:00
commit 9962b8769a
5 changed files with 100 additions and 27 deletions

View file

@ -954,6 +954,16 @@ static void PacketReceived(PacketCommandNG *packet) {
EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd); EM4xWriteWord(payload->address, payload->data, payload->password, payload->usepwd);
break; 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: { case CMD_LF_AWID_WATCH: {
uint32_t high, low; uint32_t high, low;
int res = lf_awid_watch(0, &high, &low); int res = lf_awid_watch(0, &high, &low);

View file

@ -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_LOGIN 0xC
#define FWD_CMD_WRITE 0xA #define FWD_CMD_WRITE 0xA
#define FWD_CMD_READ 0x9 #define FWD_CMD_READ 0x9
#define FWD_CMD_PROTECT 0x3
#define FWD_CMD_DISABLE 0x5 #define FWD_CMD_DISABLE 0x5
static uint8_t forwardLink_data[64]; //array of forwarded bits 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); SendForward(len);
// Wait 20ms for write to complete? // Wait 20ms for write to complete?
WaitMS(7); WaitUS(10820); // tPC+tWEE
DoPartialAcquisition(20, false, 6000, 1000); DoPartialAcquisition(0, false, 6000, 1000);
StopTicks(); StopTicks();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -2583,6 +2584,42 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
LEDsoff(); 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. Reading COTAG.

View file

@ -58,6 +58,7 @@ void TurnReadLFOn(uint32_t delay);
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); 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 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 Cotag(uint32_t arg0);
void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c); void setT55xxConfig(uint8_t arg0, t55xx_configurations_t *c);

View file

@ -164,7 +164,7 @@ static int usage_lf_em4x05_write(void) {
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_write [h] <address> <data> <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x05_write [h] <address> <data> <pwd>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - this help"); 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, " data - data to write (hex)");
PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)"); PrintAndLogEx(NORMAL, " pwd - password (hex) (optional)");
PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, "Examples:");
@ -857,7 +857,6 @@ static int demodEM4x05resp(uint32_t *word) {
*word = 0; *word = 0;
if (detectASK_MAN() && doPreambleSearch(&idx)) if (detectASK_MAN() && doPreambleSearch(&idx))
return setDemodBufferEM(word, idx); return setDemodBufferEM(word, idx);
if (detectASK_BI() && doPreambleSearch(&idx)) if (detectASK_BI() && doPreambleSearch(&idx))
return setDemodBufferEM(word, idx); return setDemodBufferEM(word, idx);
@ -1101,37 +1100,62 @@ static int CmdEM4x05Write(const char *Cmd) {
data = param_get32ex(Cmd, 1, 0, 16); data = param_get32ex(Cmd, 1, 0, 16);
pwd = param_get32ex(Cmd, 2, 0xFFFFFFFF, 16); pwd = param_get32ex(Cmd, 2, 0xFFFFFFFF, 16);
if (addr > 15) { if ((addr > 13) && (addr != 99)) {
PrintAndLogEx(NORMAL, "Address must be between 0 and 15"); PrintAndLogEx(NORMAL, "Address must be between 0 and 13");
return PM3_EINVARG; return PM3_EINVARG;
} }
if (pwd == 0xFFFFFFFF) if (pwd == 0xFFFFFFFF) {
PrintAndLogEx(NORMAL, "Writing address %d data %08X", addr, data); if (addr == 99)
else { PrintAndLogEx(NORMAL, "Writing protection words data %08X", addr, data);
else
PrintAndLogEx(NORMAL, "Writing address %d data %08X", addr, data);
} else {
usePwd = true; 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 { if (addr == 99) { // set Protect Words
uint32_t password; struct {
uint32_t data; uint32_t password;
uint8_t address; uint32_t data;
uint8_t usepwd; uint8_t usepwd;
} PACKED payload; } PACKED payload;
payload.password = pwd; payload.password = pwd;
payload.data = data; payload.data = data;
payload.address = addr; payload.usepwd = usePwd;
payload.usepwd = usePwd;
clearCommandBuffer(); clearCommandBuffer();
SendCommandNG(CMD_LF_EM4X_WRITEWORD, (uint8_t *)&payload, sizeof(payload)); SendCommandNG(CMD_LF_EM4X_PROTECTWORD, (uint8_t *)&payload, sizeof(payload));
PacketResponseNG resp; PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_LF_EM4X_WRITEWORD, &resp, 2000)) { if (!WaitForResponseTimeout(CMD_LF_EM4X_PROTECTWORD, &resp, 2000)) {
PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation."); PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
return PM3_ETIMEOUT; 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()) if (!downloadSamplesEM())
return PM3_ENODATA; return PM3_ENODATA;

View file

@ -486,6 +486,7 @@ typedef struct {
#define CMD_LF_PCF7931_WRITE 0x0223 #define CMD_LF_PCF7931_WRITE 0x0223
#define CMD_LF_EM4X_READWORD 0x0218 #define CMD_LF_EM4X_READWORD 0x0218
#define CMD_LF_EM4X_WRITEWORD 0x0219 #define CMD_LF_EM4X_WRITEWORD 0x0219
#define CMD_LF_EM4X_PROTECTWORD 0x021B
#define CMD_LF_IO_WATCH 0x021A #define CMD_LF_IO_WATCH 0x021A
#define CMD_LF_EM410X_WATCH 0x021C #define CMD_LF_EM410X_WATCH 0x021C
#define CMD_LF_EM4X50_INFO 0x0240 #define CMD_LF_EM4X50_INFO 0x0240