mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
Implement new command hf 15 slixprotectpage to do ISO15693_PROTECT_PAGE on slix tags
This commit is contained in:
parent
dbbb20a510
commit
0e2a02bdf0
6 changed files with 176 additions and 9 deletions
|
@ -1467,6 +1467,17 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id);
|
WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_PROTECT_PAGE: {
|
||||||
|
struct p {
|
||||||
|
uint8_t read_pwd[4];
|
||||||
|
uint8_t write_pwd[4];
|
||||||
|
uint8_t divide_ptr;
|
||||||
|
uint8_t prot_status;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
ProtectPageSlixIso15693(payload->read_pwd, payload->write_pwd, payload->divide_ptr, payload->prot_status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: {
|
case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: {
|
||||||
struct p {
|
struct p {
|
||||||
uint8_t pwd[4];
|
uint8_t pwd[4];
|
||||||
|
|
|
@ -3020,14 +3020,7 @@ static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_ti
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid) {
|
static uint32_t set_pass_15693_SlixRnd(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid, uint8_t *rnd) {
|
||||||
|
|
||||||
|
|
||||||
uint8_t rnd[2];
|
|
||||||
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
|
||||||
return PM3_ETIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0x04, == NXP from manufacture id list.
|
// 0x04, == NXP from manufacture id list.
|
||||||
uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
@ -3047,6 +3040,18 @@ static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uin
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, const uint8_t *password, const uint8_t *uid) {
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return set_pass_15693_SlixRnd(start_time, eof_time, pass_id, password, uid, rnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, const uint8_t *password) {
|
static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, const uint8_t *password) {
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
@ -3154,6 +3159,26 @@ static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_tim
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t protect_page_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t divide_ptr, uint8_t prot_status, const uint8_t *uid) {
|
||||||
|
|
||||||
|
uint8_t protect_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_PROTECT_PAGE, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, divide_ptr, prot_status, 0x00, 0x00};
|
||||||
|
|
||||||
|
memcpy(&protect_cmd[3], uid, 8);
|
||||||
|
|
||||||
|
AddCrc15(protect_cmd, 13);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res_wrp = SendDataTag(protect_cmd, sizeof(protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res_wrp != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, const uint8_t *password) {
|
static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, const uint8_t *password) {
|
||||||
|
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
@ -3254,6 +3279,37 @@ void WritePasswordSlixIso15693(const uint8_t *old_password, const uint8_t *new_p
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProtectPageSlixIso15693(const uint8_t *read_password, const uint8_t *write_password, uint8_t divide_ptr, uint8_t prot_status) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = PM3_SUCCESS;
|
||||||
|
|
||||||
|
uint8_t uid[8], rnd[2];
|
||||||
|
get_uid_slix(start_time, &eof_time, uid);
|
||||||
|
|
||||||
|
if (get_rnd_15693_Slix(start_time, &eof_time, rnd) == false) {
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_PROTECT_PAGE, PM3_ETIMEOUT, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_password)
|
||||||
|
res = set_pass_15693_SlixRnd(start_time, &eof_time, 0x01, read_password, uid, rnd);
|
||||||
|
|
||||||
|
if (res == PM3_SUCCESS && write_password)
|
||||||
|
res = set_pass_15693_SlixRnd(start_time, &eof_time, 0x02, write_password, uid, rnd);
|
||||||
|
|
||||||
|
if (res == PM3_SUCCESS)
|
||||||
|
res = protect_page_15693_Slix(start_time, &eof_time, divide_ptr, prot_status, uid);
|
||||||
|
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_PROTECT_PAGE, res, NULL, 0);
|
||||||
|
|
||||||
|
switch_off();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void DisablePrivacySlixIso15693(const uint8_t *password) {
|
void DisablePrivacySlixIso15693(const uint8_t *password) {
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
Iso15693InitReader();
|
Iso15693InitReader();
|
||||||
|
|
|
@ -68,4 +68,5 @@ void EnableEAS_AFISlixIso15693(const uint8_t *password, bool usepwd);
|
||||||
void PassProtextEASSlixIso15693(const uint8_t *password);
|
void PassProtextEASSlixIso15693(const uint8_t *password);
|
||||||
void PassProtectAFISlixIso15693(const uint8_t *password);
|
void PassProtectAFISlixIso15693(const uint8_t *password);
|
||||||
void WriteAFIIso15693(const uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi);
|
void WriteAFIIso15693(const uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi);
|
||||||
|
void ProtectPageSlixIso15693(const uint8_t *read_password, const uint8_t *write_password, uint8_t divide_ptr, uint8_t prot_status);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -826,6 +826,8 @@ static int NxpSysInfo(uint8_t *uid) {
|
||||||
PrintAndLogEx(INFO, "");
|
PrintAndLogEx(INFO, "");
|
||||||
PrintAndLogEx(INFO, _CYAN_(" Password protection configuration"));
|
PrintAndLogEx(INFO, _CYAN_(" Password protection configuration"));
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, " Page prot. ptr. " _YELLOW_("%d"), d[1]);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " Page L read.... %s"
|
PrintAndLogEx(INFO, " Page L read.... %s"
|
||||||
, (d[2] & 0x01) ? _RED_("password") : _GREEN_("no password")
|
, (d[2] & 0x01) ? _RED_("password") : _GREEN_("no password")
|
||||||
);
|
);
|
||||||
|
@ -3203,6 +3205,101 @@ static int CmdHF15SlixWritePassword(const char *Cmd) {
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixProtectPage(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixprotectpage",
|
||||||
|
"Defines protection pointer address of user mem and access cond. for pages",
|
||||||
|
"hf 15 slixprotectpage -w deadbeef -p 3 -h 3");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0("r", "readpw", "<hex>", "read password, 4 hex bytes"),
|
||||||
|
arg_str0("w", "writepw", "<hex>", "write password, 4 hex bytes"),
|
||||||
|
arg_int0("p", "ptr", "<dec>", "protection pointer page (0-78), if 0 entire user mem"),
|
||||||
|
arg_int1("l", "lo", "<dec>", "page protection flags of lo page (0-None, 1-ReadPR, 2-WritePR)"),
|
||||||
|
arg_int1("i", "hi", "<dec>", "page protection flags of hi page (0-None, 1-ReadPR, 2-WritePR)"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
struct p {
|
||||||
|
uint8_t read_pwd[4];
|
||||||
|
uint8_t write_pwd[4];
|
||||||
|
uint8_t divide_ptr;
|
||||||
|
uint8_t prot_status;
|
||||||
|
} PACKED payload = {0};
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 1, payload.read_pwd, &pwdlen);
|
||||||
|
|
||||||
|
if (pwdlen > 0 && pwdlen != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "read password must be 4 hex bytes if provided");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 2, payload.write_pwd, &pwdlen);
|
||||||
|
|
||||||
|
if (pwdlen > 0 && pwdlen != 4) {
|
||||||
|
PrintAndLogEx(WARNING, "write password must be 4 hex bytes if provided");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
payload.divide_ptr = (uint8_t)arg_get_int_def(ctx, 3, 0);
|
||||||
|
if (payload.divide_ptr > 78) {
|
||||||
|
PrintAndLogEx(WARNING, "protection pointer page is invalid (is %d but should be <=78).", payload.divide_ptr);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwdlen = arg_get_int_def(ctx, 4, 0);
|
||||||
|
if (pwdlen > 3) {
|
||||||
|
PrintAndLogEx(WARNING, "page protection flags must be between 0 and 3");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
payload.prot_status = (uint8_t)pwdlen;
|
||||||
|
|
||||||
|
pwdlen = arg_get_int_def(ctx, 5, 0);
|
||||||
|
if (pwdlen > 3) {
|
||||||
|
PrintAndLogEx(WARNING, "page protection flags must be between 0 and 3");
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
payload.prot_status |= (uint8_t)pwdlen<<4;
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to set page protection pointer to " _YELLOW_("%d"), payload.divide_ptr);
|
||||||
|
PrintAndLogEx(INFO, _YELLOW_("LO") " page access %s%s", (payload.prot_status & 0x01)?_RED_("R"):_GREEN_("r"), (payload.prot_status & 0x02)?_RED_("W"):_GREEN_("w"));
|
||||||
|
PrintAndLogEx(INFO, _YELLOW_("HI") " page access %s%s", (payload.prot_status & 0x10)?_RED_("R"):_GREEN_("r"), (payload.prot_status & 0x20)?_RED_("W"):_GREEN_("w"));
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_PROTECT_PAGE, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PROTECT_PAGE, &resp, 2000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
|
DropField();
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
PrintAndLogEx(WARNING, "Protection flags were not accepted, locked? ( " _RED_("fail") " )");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "Page protection written ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHF15AFIPassProtect(const char *Cmd) {
|
static int CmdHF15AFIPassProtect(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
|
@ -3513,6 +3610,7 @@ static command_t CommandTable[] = {
|
||||||
{"slixeasenable", CmdHF15SlixEASEnable, IfPm3Iso15693, "Enable EAS mode on SLIX ISO-15693 tag"},
|
{"slixeasenable", CmdHF15SlixEASEnable, IfPm3Iso15693, "Enable EAS mode on SLIX ISO-15693 tag"},
|
||||||
{"slixprivacydisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"},
|
{"slixprivacydisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"},
|
||||||
{"slixprivacyenable", CmdHF15SlixEnable, IfPm3Iso15693, "Enable privacy mode on SLIX ISO-15693 tag"},
|
{"slixprivacyenable", CmdHF15SlixEnable, IfPm3Iso15693, "Enable privacy mode on SLIX ISO-15693 tag"},
|
||||||
|
{"slixprotectpage", CmdHF15SlixProtectPage, IfPm3Iso15693, "Protect pages on SLIX ISO-15693 tag"},
|
||||||
{"passprotectafi", CmdHF15AFIPassProtect, IfPm3Iso15693, "Password protect AFI - Cannot be undone"},
|
{"passprotectafi", CmdHF15AFIPassProtect, IfPm3Iso15693, "Password protect AFI - Cannot be undone"},
|
||||||
{"passprotecteas", CmdHF15EASPassProtect, IfPm3Iso15693, "Password protect EAS - Cannot be undone"},
|
{"passprotecteas", CmdHF15EASPassProtect, IfPm3Iso15693, "Password protect EAS - Cannot be undone"},
|
||||||
{"-----------", CmdHF15Help, IfPm3Iso15693, "-------------------------- " _CYAN_("afi") " ------------------------"},
|
{"-----------", CmdHF15Help, IfPm3Iso15693, "-------------------------- " _CYAN_("afi") " ------------------------"},
|
||||||
|
|
|
@ -202,6 +202,7 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 0, "hf 15 slixeasenable" },
|
{ 0, "hf 15 slixeasenable" },
|
||||||
{ 0, "hf 15 slixprivacydisable" },
|
{ 0, "hf 15 slixprivacydisable" },
|
||||||
{ 0, "hf 15 slixprivacyenable" },
|
{ 0, "hf 15 slixprivacyenable" },
|
||||||
|
{ 0, "hf 15 slixprotectpage" },
|
||||||
{ 0, "hf 15 passprotectafi" },
|
{ 0, "hf 15 passprotectafi" },
|
||||||
{ 0, "hf 15 passprotecteas" },
|
{ 0, "hf 15 passprotecteas" },
|
||||||
{ 0, "hf 15 findafi" },
|
{ 0, "hf 15 findafi" },
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -575,6 +574,7 @@ typedef struct {
|
||||||
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863
|
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863
|
||||||
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864
|
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864
|
||||||
#define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865
|
#define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865
|
||||||
|
#define CMD_HF_ISO15693_SLIX_PROTECT_PAGE 0x0868
|
||||||
#define CMD_HF_ISO15693_WRITE_AFI 0x0866
|
#define CMD_HF_ISO15693_WRITE_AFI 0x0866
|
||||||
#define CMD_HF_TEXKOM_SIMULATE 0x0320
|
#define CMD_HF_TEXKOM_SIMULATE 0x0320
|
||||||
#define CMD_HF_ISO15693_EML_CLEAR 0x0330
|
#define CMD_HF_ISO15693_EML_CLEAR 0x0330
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue