mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Add hf 15
sub-commands for EAS, AFI, privacy mode, and passwords on SLIX tags
This commit is contained in:
parent
e7f28a6b50
commit
9041627ae5
7 changed files with 993 additions and 135 deletions
|
@ -43,6 +43,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001)
|
- Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001)
|
||||||
- Fixed `make accessrights` on Fedora (@mooey5775)
|
- Fixed `make accessrights` on Fedora (@mooey5775)
|
||||||
- Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn)
|
- Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn)
|
||||||
|
- Added `hf 15` sub-commands for controlling EAS, AFI, privacy mode, and the setting of passwords on SLIX tags (@mjacksn)
|
||||||
|
|
||||||
|
|
||||||
## [Radium.4.15864][2022-10-29]
|
## [Radium.4.15864][2022-10-29]
|
||||||
- Changed `lf indala sim` - now accepts fc / cn (@iceman1001)
|
- Changed `lf indala sim` - now accepts fc / cn (@iceman1001)
|
||||||
|
|
|
@ -1287,20 +1287,76 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
SetTag15693Uid(payload->uid);
|
SetTag15693Uid(payload->uid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY: {
|
case CMD_HF_ISO15693_SLIX_DISABLE_EAS: {
|
||||||
struct p {
|
struct p {
|
||||||
uint8_t pwd[4];
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
struct p *payload = (struct p *) packet->data.asBytes;
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
DisablePrivacySlixLIso15693(payload->pwd);
|
DisableEAS_AFISlixIso15693(payload->pwd, payload->usepwd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI: {
|
case CMD_HF_ISO15693_SLIX_ENABLE_EAS: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
EnableEAS_AFISlixIso15693(payload->pwd, payload->usepwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_WRITE_PWD: {
|
||||||
|
struct p {
|
||||||
|
uint8_t old_pwd[4];
|
||||||
|
uint8_t new_pwd[4];
|
||||||
|
uint8_t pwd_id;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: {
|
||||||
struct p {
|
struct p {
|
||||||
uint8_t pwd[4];
|
uint8_t pwd[4];
|
||||||
} PACKED;
|
} PACKED;
|
||||||
struct p *payload = (struct p *) packet->data.asBytes;
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
DisableEAS_AFISlixLIso15693(payload->pwd);
|
DisablePrivacySlixIso15693(payload->pwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p* payload = (struct p*)packet->data.asBytes;
|
||||||
|
EnablePrivacySlixIso15693(payload->pwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p* payload = (struct p*)packet->data.asBytes;
|
||||||
|
PassProtectAFISlixIso15693(payload->pwd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_WRITE_AFI: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool use_pwd;
|
||||||
|
uint8_t uid[8];
|
||||||
|
bool use_uid;
|
||||||
|
uint8_t afi;
|
||||||
|
} PACKED;
|
||||||
|
struct p* payload = (struct p*)packet->data.asBytes;
|
||||||
|
WriteAFIIso15693(payload->pwd, payload->use_pwd, payload->uid, payload->use_uid, payload->afi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS: {
|
||||||
|
struct p {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p* payload = (struct p*)packet->data.asBytes;
|
||||||
|
PassProtextEASSlixIso15693(payload->pwd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,37 @@ static void CodeIso15693AsReaderEOF(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int get_uid_slix(uint32_t start_time, uint32_t* eof_time, uint8_t* uid) {
|
||||||
|
|
||||||
|
uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
|
||||||
|
uint8_t cmd[5] = {0};
|
||||||
|
BuildIdentifyRequest(cmd);
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
SendDataTag(cmd, sizeof(cmd), false, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, eof_time, &recvlen);
|
||||||
|
|
||||||
|
if(recvlen != 12)
|
||||||
|
{
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uid[0] = answer[2];
|
||||||
|
uid[1] = answer[3];
|
||||||
|
uid[2] = answer[4];
|
||||||
|
uid[3] = answer[5];
|
||||||
|
uid[4] = answer[6];
|
||||||
|
uid[5] = answer[7];
|
||||||
|
uid[6] = answer[8];
|
||||||
|
uid[7] = answer[9];
|
||||||
|
|
||||||
|
BigBuf_free();
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// encode data using "1 out of 256" scheme
|
// encode data using "1 out of 256" scheme
|
||||||
// data rate is 1,66 kbit/s (fc/8192)
|
// data rate is 1,66 kbit/s (fc/8192)
|
||||||
// is designed for more robust communication over longer distances
|
// is designed for more robust communication over longer distances
|
||||||
|
@ -2431,6 +2462,8 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
||||||
case ISO15693_WRITE_AFI:
|
case ISO15693_WRITE_AFI:
|
||||||
case ISO15693_LOCK_AFI:
|
case ISO15693_LOCK_AFI:
|
||||||
case ISO15693_WRITE_DSFID:
|
case ISO15693_WRITE_DSFID:
|
||||||
|
case ISO15693_WRITE_PASSWORD:
|
||||||
|
case ISO15693_PASSWORD_PROTECT_EAS:
|
||||||
case ISO15693_LOCK_DSFID:
|
case ISO15693_LOCK_DSFID:
|
||||||
timeout = ISO15693_READER_TIMEOUT_WRITE;
|
timeout = ISO15693_READER_TIMEOUT_WRITE;
|
||||||
request_answer = data[0] & ISO15_REQ_OPTION;
|
request_answer = data[0] & ISO15_REQ_OPTION;
|
||||||
|
@ -2640,7 +2673,7 @@ void SetTag15693Uid(const uint8_t *uid) {
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) {
|
static void init_password_15693_Slix(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) {
|
||||||
memcpy(buffer, pwd, 4);
|
memcpy(buffer, pwd, 4);
|
||||||
if (rnd) {
|
if (rnd) {
|
||||||
buffer[0] ^= rnd[0];
|
buffer[0] ^= rnd[0];
|
||||||
|
@ -2650,14 +2683,14 @@ static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) {
|
static bool get_rnd_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) {
|
||||||
// 0x04, == NXP from manufacture id list.
|
// 0x04, == NXP from manufacture id list.
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 };
|
||||||
AddCrc15(c, 3);
|
AddCrc15(c, 3);
|
||||||
|
|
||||||
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
uint16_t recvlen = 0;
|
uint16_t recvlen = 0;
|
||||||
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
int res = SendDataTag(c, sizeof(c), true, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
if (res != PM3_SUCCESS && recvlen != 5) {
|
if (res != PM3_SUCCESS && recvlen != 5) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2668,15 +2701,16 @@ static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password) {
|
static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t pass_id, uint8_t* password) {
|
||||||
|
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x04, == NXP from manufacture id list.
|
// 0x04, == NXP from manufacture id list.
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
init_password_15693_slixl(&c[4], password, rnd);
|
init_password_15693_Slix(&c[4], password, rnd);
|
||||||
AddCrc15(c, 8);
|
AddCrc15(c, 8);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2689,16 +2723,236 @@ static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, ui
|
||||||
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, uint8_t* password, uint8_t* uid) {
|
||||||
static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
|
||||||
|
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 };
|
||||||
|
|
||||||
|
init_password_15693_Slix(&c[12], password, rnd);
|
||||||
|
|
||||||
|
memcpy(&c[3], uid, 8);
|
||||||
|
AddCrc15(c, 16);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password) {
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x04, == NXP from manufacture id list.
|
||||||
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xBA, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
init_password_15693_Slix(&c[3], password, rnd);
|
||||||
|
AddCrc15(c, 7);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password, bool usepwd) {
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(usepwd)
|
||||||
|
{
|
||||||
|
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if(res_setpass != PM3_SUCCESS)
|
||||||
|
{
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0x04, == NXP from manufacture id list.
|
||||||
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA3, 0x04, 0x00, 0x00};
|
||||||
|
AddCrc15(c, 3);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password, bool usepwd) {
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(usepwd)
|
||||||
|
{
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if(res_setpass != PM3_SUCCESS)
|
||||||
|
{
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 0x04, == NXP from manufacture id list.
|
||||||
|
uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA2, 0x04, 0x00, 0x00};
|
||||||
|
//init_password_15693_Slix(&c[3], password, rnd);
|
||||||
|
AddCrc15(c, 3);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, uint8_t *password, uint8_t* uid) {
|
||||||
|
|
||||||
|
uint8_t new_pwd_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pwd_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
memcpy(&new_pwd_cmd[3], uid, 8);
|
||||||
|
memcpy(&new_pwd_cmd[12], password, 4);
|
||||||
|
|
||||||
|
AddCrc15(new_pwd_cmd, 16);
|
||||||
|
|
||||||
|
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(new_pwd_cmd, sizeof(new_pwd_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, uint8_t* password) {
|
||||||
|
|
||||||
|
uint8_t flags;
|
||||||
|
|
||||||
|
if(set_option_flag)
|
||||||
|
flags = ISO15_REQ_DATARATE_HIGH | ISO15_REQ_OPTION;
|
||||||
|
else
|
||||||
|
flags = ISO15_REQ_DATARATE_HIGH;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if(res_setpass != PM3_SUCCESS)
|
||||||
|
{
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t new_pass_protect_cmd[] = { flags, ISO15693_PASSWORD_PROTECT_EAS, 0x04, 0x00, 0x00};
|
||||||
|
AddCrc15(new_pass_protect_cmd, 3);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res = SendDataTag(new_pass_protect_cmd, sizeof(new_pass_protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS && recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t write_afi_15693(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(!use_uid)
|
||||||
|
{
|
||||||
|
int res_getuid = get_uid_slix(start_time, eof_time, uid);
|
||||||
|
|
||||||
|
if(res_getuid != PM3_SUCCESS)
|
||||||
|
{
|
||||||
|
return res_getuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(usepwd)
|
||||||
|
{
|
||||||
|
int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid);
|
||||||
|
|
||||||
|
if(res_setpass != PM3_SUCCESS)
|
||||||
|
{
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t cmd[] = { ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_AFI, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
|
memcpy(&cmd[2], uid, 8);
|
||||||
|
cmd[10] = afi;
|
||||||
|
AddCrc15(cmd, 11);
|
||||||
|
|
||||||
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
uint16_t recvlen = 0;
|
||||||
|
|
||||||
|
int res = SendDataTag(cmd, sizeof(cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen);
|
||||||
|
if (res != PM3_SUCCESS || recvlen != 3) {
|
||||||
|
return PM3_EWRONGANSWER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
static uint32_t enable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
||||||
|
uint8_t rnd[2];
|
||||||
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_ENABLE_PRIVACY, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_ENABLE_PRIVACY, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
memcpy(&c[3], uid, 8);
|
memcpy(&c[3], uid, 8);
|
||||||
init_password_15693_slixl(&c[11], password, rnd);
|
init_password_15693_Slix(&c[11], password, rnd);
|
||||||
AddCrc15(c, 15);
|
AddCrc15(c, 15);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2711,16 +2965,16 @@ static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_ti
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) {
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
memcpy(&c[3], uid, 8);
|
memcpy(&c[3], uid, 8);
|
||||||
c[11] = pass_id;
|
c[11] = pass_id;
|
||||||
init_password_15693_slixl(&c[12], password, NULL);
|
init_password_15693_Slix(&c[12], password, NULL);
|
||||||
AddCrc15(c, 16);
|
AddCrc15(c, 16);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2734,16 +2988,16 @@ static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_ti
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) {
|
static uint32_t destroy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) {
|
||||||
|
|
||||||
uint8_t rnd[2];
|
uint8_t rnd[2];
|
||||||
if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) {
|
if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_DESTROY, ISO15693_ENABLE_PRIVACY, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_DESTROY, ISO15693_ENABLE_PRIVACY, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
memcpy(&c[3], uid, 8);
|
memcpy(&c[3], uid, 8);
|
||||||
init_password_15693_slixl(&c[11], password, rnd);
|
init_password_15693_Slix(&c[11], password, rnd);
|
||||||
AddCrc15(c, 15);
|
AddCrc15(c, 15);
|
||||||
|
|
||||||
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER;
|
||||||
|
@ -2758,8 +3012,33 @@ static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uin
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Sets a PRIVACY password to all ZEROS
|
void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id) {
|
||||||
void DisablePrivacySlixLIso15693(uint8_t *password) {
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = PM3_EFAILED;
|
||||||
|
|
||||||
|
uint8_t uid[8];
|
||||||
|
get_uid_slix(start_time, &eof_time, uid);
|
||||||
|
|
||||||
|
res = set_pass_15693_Slix(start_time, &eof_time, pwd_id, old_password, uid);
|
||||||
|
if(res != PM3_SUCCESS)
|
||||||
|
{
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = write_password_15693_Slix(start_time, &eof_time, pwd_id, new_password, uid);
|
||||||
|
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0);
|
||||||
|
|
||||||
|
switch_off();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisablePrivacySlixIso15693(uint8_t *password) {
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
Iso15693InitReader();
|
Iso15693InitReader();
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
@ -2769,13 +3048,12 @@ void DisablePrivacySlixLIso15693(uint8_t *password) {
|
||||||
// 0x04 Privacy
|
// 0x04 Privacy
|
||||||
// 0x08 Destroy SLIX-L
|
// 0x08 Destroy SLIX-L
|
||||||
// 0x10 EAS/AFI
|
// 0x10 EAS/AFI
|
||||||
int res = set_pass_15693_slixl(start_time, &eof_time, 0x04, password);
|
int res = disable_privacy_15693_Slix(start_time, &eof_time, 0x04, password);
|
||||||
reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, res, NULL, 0);
|
reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, res, NULL, 0);
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets a EAS/AFI password to all ZEROS
|
void EnablePrivacySlixIso15693(uint8_t* password) {
|
||||||
void DisableEAS_AFISlixLIso15693(uint8_t *password) {
|
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
Iso15693InitReader();
|
Iso15693InitReader();
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
@ -2785,8 +3063,71 @@ void DisableEAS_AFISlixLIso15693(uint8_t *password) {
|
||||||
// 0x04 Privacy
|
// 0x04 Privacy
|
||||||
// 0x08 Destroy SLIX-L
|
// 0x08 Destroy SLIX-L
|
||||||
// 0x10 EAS/AFI
|
// 0x10 EAS/AFI
|
||||||
int res = set_pass_15693_slixl(start_time, &eof_time, 0x10, password);
|
int res = set_privacy_15693_Slix(start_time, &eof_time, password);
|
||||||
reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI, res, NULL, 0);
|
reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, res, NULL, 0);
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
|
||||||
|
// Password identifier Password byte
|
||||||
|
// 0x04 Privacy
|
||||||
|
// 0x08 Destroy SLIX-L
|
||||||
|
// 0x10 EAS/AFI
|
||||||
|
int res = disable_eas_15693_Slix(start_time, &eof_time, password, usepwd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_EAS, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
|
||||||
|
// Password identifier Password byte
|
||||||
|
// 0x04 Privacy
|
||||||
|
// 0x08 Destroy SLIX-L
|
||||||
|
// 0x10 EAS/AFI
|
||||||
|
int res = enable_eas_15693_Slix(start_time, &eof_time, password, usepwd);
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_EAS, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PassProtextEASSlixIso15693(uint8_t *password) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, false, password);
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
void PassProtectAFISlixIso15693(uint8_t *password) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, true, password);
|
||||||
|
reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteAFIIso15693(uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi) {
|
||||||
|
LED_D_ON();
|
||||||
|
Iso15693InitReader();
|
||||||
|
StartCountSspClk();
|
||||||
|
uint32_t start_time = 0, eof_time = 0;
|
||||||
|
int res = write_afi_15693(start_time, &eof_time, password, use_pwd, uid, use_uid, afi);
|
||||||
|
//int res = PM3_SUCCESS;
|
||||||
|
reply_ng(CMD_HF_ISO15693_WRITE_AFI, res, NULL, 0);
|
||||||
|
switch_off();
|
||||||
|
}
|
|
@ -62,6 +62,12 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui
|
||||||
|
|
||||||
void SetTag15693Uid(const uint8_t *uid);
|
void SetTag15693Uid(const uint8_t *uid);
|
||||||
|
|
||||||
void DisablePrivacySlixLIso15693(uint8_t *password);
|
void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id);
|
||||||
void DisableEAS_AFISlixLIso15693(uint8_t *password);
|
void DisablePrivacySlixIso15693(uint8_t *password);
|
||||||
|
void EnablePrivacySlixIso15693(uint8_t* password);
|
||||||
|
void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd);
|
||||||
|
void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd);
|
||||||
|
void PassProtextEASSlixIso15693(uint8_t *password);
|
||||||
|
void PassProtectAFISlixIso15693(uint8_t *password);
|
||||||
|
void WriteAFIIso15693(uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1352,94 +1352,83 @@ static int CmdHF15WriteAfi(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf 15 writeafi",
|
CLIParserInit(&ctx, "hf 15 writeafi",
|
||||||
"Write AFI on card",
|
"Write AFI on card",
|
||||||
"hf 15 writeafi -* --afi 12\n"
|
"hf 15 writeafi -* --afi 12\n"
|
||||||
"hf 15 writeafi -u E011223344556677 --afi 12"
|
"hf 15 writeafi -u E011223344556677 --afi 12 -p 0F0F0F0F"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[6 + 2] = {};
|
void *argtable[5] = {};
|
||||||
uint8_t arglen = arg_add_default(argtable);
|
argtable[0] = arg_param_begin;
|
||||||
argtable[arglen++] = arg_int1(NULL, "afi", "<dec>", "AFI number (0-255)");
|
argtable[1] = arg_str0("u", "uid", "<hex>", "full UID, 8 bytes");
|
||||||
argtable[arglen++] = arg_param_end;
|
argtable[2] = arg_int1(NULL, "afi", "<dec>", "AFI number (0-255)");
|
||||||
|
argtable[3] = arg_str0("p", "pwd", "<hex>", "optional AFI/EAS password");
|
||||||
|
argtable[4] = arg_param_end;
|
||||||
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool use_pwd;
|
||||||
uint8_t uid[8];
|
uint8_t uid[8];
|
||||||
int uidlen = 0;
|
bool use_uid;
|
||||||
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
|
uint8_t afi;
|
||||||
bool unaddressed = arg_get_lit(ctx, 2);
|
} PACKED payload;
|
||||||
bool scan = arg_get_lit(ctx, 3);
|
|
||||||
int fast = (arg_get_lit(ctx, 4) == false);
|
int uidlen = 0;
|
||||||
bool add_option = arg_get_lit(ctx, 5);
|
CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen);
|
||||||
|
|
||||||
|
payload.afi = arg_get_int_def(ctx, 2, 0);
|
||||||
|
|
||||||
|
int pwdlen;
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 3, payload.pwd, &pwdlen);
|
||||||
|
|
||||||
int afi = arg_get_int_def(ctx, 6, 0);
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if(pwdlen == 4)
|
||||||
|
{
|
||||||
|
payload.use_pwd = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uidlen == 8)
|
||||||
|
{
|
||||||
|
payload.use_uid = true;
|
||||||
|
}
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if ((scan + unaddressed + uidlen) > 1) {
|
if (uidlen != 0 && uidlen != 8) {
|
||||||
PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid");
|
PrintAndLogEx(WARNING, "uid must be 8 hex bytes if provided");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// request to be sent to device/card
|
if(pwdlen > 0 && pwdlen != 4)
|
||||||
uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option);
|
{
|
||||||
uint8_t req[16] = {flags, ISO15693_WRITE_AFI};
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided");
|
||||||
uint16_t reqlen = 2;
|
return PM3_ESOFT;
|
||||||
|
|
||||||
if (unaddressed == false) {
|
|
||||||
if (scan) {
|
|
||||||
if (getUID(false, uid) != PM3_SUCCESS) {
|
|
||||||
PrintAndLogEx(WARNING, "no tag found");
|
|
||||||
return PM3_EINVARG;
|
|
||||||
}
|
}
|
||||||
uidlen = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uidlen == 8) {
|
|
||||||
// add UID (scan, uid)
|
|
||||||
memcpy(req + reqlen, uid, sizeof(uid));
|
|
||||||
reqlen += sizeof(uid);
|
|
||||||
}
|
|
||||||
PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid));
|
|
||||||
}
|
|
||||||
|
|
||||||
// enforce, since we are writing
|
|
||||||
req[0] |= ISO15_REQ_OPTION;
|
|
||||||
|
|
||||||
req[reqlen++] = (uint8_t)afi;
|
|
||||||
|
|
||||||
AddCrc15(req, reqlen);
|
|
||||||
reqlen += 2;
|
|
||||||
|
|
||||||
// arg: len, speed, recv?
|
|
||||||
// arg0 (datalen, cmd len? .arg0 == crc?)
|
|
||||||
// arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 )
|
|
||||||
// arg2 (recv == 1 == expect a response)
|
|
||||||
uint8_t read_response = 1;
|
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_response, req, reqlen);
|
SendCommandNG(CMD_HF_ISO15693_WRITE_AFI, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_WRITE_AFI, &resp, 2000) == false) {
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
PrintAndLogEx(ERR, "iso15693 timeout");
|
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
DropField();
|
|
||||||
|
|
||||||
if (resp.status == PM3_ETEAROFF) {
|
switch (resp.status) {
|
||||||
|
case PM3_ETIMEOUT: {
|
||||||
|
PrintAndLogEx(WARNING, "no tag found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_EWRONGANSWER: {
|
||||||
|
PrintAndLogEx(WARNING, "error writing AFI");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", payload.afi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *data = resp.data.asBytes;
|
|
||||||
|
|
||||||
if ((data[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) {
|
|
||||||
PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", data[0], TagErrorStr(data[0]));
|
|
||||||
return PM3_EWRONGANSWER;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", afi);
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Writes the DSFID (Data Storage Format Identifier) of a card
|
// Writes the DSFID (Data Storage Format Identifier) of a card
|
||||||
|
@ -2378,10 +2367,164 @@ static int CmdHF15CSetUID(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixEASEnable(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixeasenable",
|
||||||
|
"Enable EAS mode on SLIX ISO-15693 tag",
|
||||||
|
"hf 15 slixeasenable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen);
|
||||||
|
if((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
|
||||||
|
if(pwdlen > 0 )
|
||||||
|
{
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS mode using password " _GREEN_("%s")
|
||||||
|
, sprint_hex_inrow(payload.pwd, sizeof(payload.pwd))
|
||||||
|
);
|
||||||
|
payload.usepwd = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password");
|
||||||
|
payload.usepwd = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_EAS, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_EAS, &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: {
|
||||||
|
if(pwdlen > 0 )
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "the password provided was not accepted");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "EAS mode is now enabled ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixEASDisable(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixeasdisable",
|
||||||
|
"Disable EAS mode on SLIX ISO-15693 tag",
|
||||||
|
"hf 15 slixeasdisable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0("p", "pwd", "<hex>", "optional password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
bool usepwd;
|
||||||
|
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen);
|
||||||
|
if((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
|
||||||
|
if(pwdlen > 0 )
|
||||||
|
{
|
||||||
|
PrintAndLogEx(INFO, "Trying to disable EAS mode using password " _GREEN_("%s")
|
||||||
|
, sprint_hex_inrow(payload.pwd, sizeof(payload.pwd))
|
||||||
|
);
|
||||||
|
payload.usepwd = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password");
|
||||||
|
payload.usepwd = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_EAS, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_EAS, &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: {
|
||||||
|
if(pwdlen > 0 )
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "the password provided was not accepted");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "EAS mode is now disabled ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHF15SlixDisable(const char *Cmd) {
|
static int CmdHF15SlixDisable(const char *Cmd) {
|
||||||
|
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf 15 slixdisable",
|
CLIParserInit(&ctx, "hf 15 slixprivacydisable",
|
||||||
"Disable privacy mode on SLIX ISO-15693 tag",
|
"Disable privacy mode on SLIX ISO-15693 tag",
|
||||||
"hf 15 slixdisable -p 0F0F0F0F");
|
"hf 15 slixdisable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
@ -2404,8 +2547,8 @@ static int CmdHF15SlixDisable(const char *Cmd) {
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload));
|
SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload));
|
||||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, &resp, 2000) == false) {
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, &resp, 2000) == false) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply");
|
||||||
DropField();
|
DropField();
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -2428,6 +2571,298 @@ static int CmdHF15SlixDisable(const char *Cmd) {
|
||||||
return resp.status;
|
return resp.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixEnable(const char* Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext* ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixprivacyenable",
|
||||||
|
"Enable privacy mode on SLIX ISO-15693 tag",
|
||||||
|
"hf 15 slixenable -p 0F0F0F0F");
|
||||||
|
|
||||||
|
void* argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("p", "pwd", "<hex>", "password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable privacy mode using password " _GREEN_("%s")
|
||||||
|
, sprint_hex_inrow(payload.pwd, sizeof(payload.pwd))
|
||||||
|
);
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, (uint8_t*)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, &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, "password was not accepted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "privacy mode is now enabled ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15SlixWritePassword(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 slixwritepwd",
|
||||||
|
"Write a password on a SLIX family ISO-15693 tag",
|
||||||
|
"hf 15 slixwritepwd -t READ -o 00000000 -n 12131415");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("t", "type", "<read|write|privacy|destroy|easafi>", "which password field to write to (some tags do not support all password types)"),
|
||||||
|
arg_str0("o", "old", "<hex>", "old password (if present), 8 hex bytes"),
|
||||||
|
arg_str1("n", "new", "<hex>", "new password, 8 hex bytes"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t old_pwd[4];
|
||||||
|
uint8_t new_pwd[4];
|
||||||
|
uint8_t pwd_id;
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 2, payload.old_pwd, &pwdlen);
|
||||||
|
|
||||||
|
if(pwdlen > 0 && pwdlen != 4)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "old password must be 4 hex bytes if provided");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 3, payload.new_pwd, &pwdlen);
|
||||||
|
|
||||||
|
if(pwdlen != 4)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "new password must be 4 hex bytes");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vlen = 0;
|
||||||
|
char value[10];
|
||||||
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)value, sizeof(value), &vlen);
|
||||||
|
|
||||||
|
if (vlen > 0) {
|
||||||
|
if (strcmp(value, "read") == 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected read pass");
|
||||||
|
payload.pwd_id = 0x01;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "write") == 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected write pass");
|
||||||
|
payload.pwd_id = 0x02;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "privacy") == 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected privacy pass");
|
||||||
|
payload.pwd_id = 0x04;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "destroy") == 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected destroy pass");
|
||||||
|
payload.pwd_id = 0x08;
|
||||||
|
}
|
||||||
|
else if (strcmp(value, "easafi") == 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(SUCCESS, "Selected easafi pass");
|
||||||
|
payload.pwd_id = 0x10;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintAndLogEx(ERR, "t argument must be 'read', 'write', 'privacy', 'destroy', or 'easafi'");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to write " _YELLOW_("%s") " as " _YELLOW_("%s") " password"
|
||||||
|
, sprint_hex_inrow(payload.new_pwd, sizeof(payload.new_pwd)), value);
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_WRITE_PWD, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_WRITE_PWD, &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, "password was not accepted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "password written ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15AFIPassProtect(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 passprotectafi",
|
||||||
|
"Password protect AFI. Cannot be undone.",
|
||||||
|
"hf 15 passprotectafi -p 00000000 -c");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("p", "password", "<hex>", "EAS/AFI password, 8 hex bytes"),
|
||||||
|
arg_lit0("c", "confirm", "confirm the execution of this irreversible command"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
|
||||||
|
bool confirmation = arg_get_lit(ctx, 2);
|
||||||
|
|
||||||
|
if(pwdlen != 4)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(confirmation == 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable AFI password protection");
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, (uint8_t*)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, &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, "error enabling AFI password protection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "AFI password protected ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHF15EASPassProtect(const char *Cmd) {
|
||||||
|
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf 15 passprotecteas",
|
||||||
|
"Password protect EAS. Cannot be undone.",
|
||||||
|
"hf 15 passprotecteas -p 00000000 -c");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str1("p", "password", "<hex>", "EAS/AFI password, 8 hex bytes"),
|
||||||
|
arg_lit0("c", "confirm", "confirm the execution of this irreversible command"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t pwd[4];
|
||||||
|
} PACKED payload;
|
||||||
|
int pwdlen = 0;
|
||||||
|
|
||||||
|
CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen);
|
||||||
|
|
||||||
|
bool confirmation = arg_get_lit(ctx, 2);
|
||||||
|
|
||||||
|
if(pwdlen != 4)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "password must be 4 hex bytes");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(confirmation == 0)
|
||||||
|
{
|
||||||
|
PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Trying to enable EAS password protection");
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, (uint8_t*)&payload, sizeof(payload));
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, &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, "error enabling EAS password protection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PM3_SUCCESS: {
|
||||||
|
PrintAndLogEx(SUCCESS, "EAS password protected ( " _GREEN_("ok") " ) ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
|
{"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
|
||||||
{"help", CmdHF15Help, AlwaysAvailable, "This help"},
|
{"help", CmdHF15Help, AlwaysAvailable, "This help"},
|
||||||
|
@ -2446,7 +2881,13 @@ static command_t CommandTable[] = {
|
||||||
{"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"},
|
{"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"},
|
||||||
{"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"},
|
{"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"},
|
||||||
{"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"},
|
{"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"},
|
||||||
{"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"},
|
{"slixwritepwd", CmdHF15SlixWritePassword, IfPm3Iso15693, "Writes a password on a SLIX ISO-15693 tag"},
|
||||||
|
{"slixeasdisable", CmdHF15SlixEASDisable, IfPm3Iso15693, "Disable 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"},
|
||||||
|
{"slixprivacyenable", CmdHF15SlixEnable, IfPm3Iso15693, "Enable privacy mode on SLIX ISO-15693 tag"},
|
||||||
|
{"passprotectafi", CmdHF15AFIPassProtect, IfPm3Iso15693, "Password protect AFI - Cannot be undone"},
|
||||||
|
{"passprotecteas", CmdHF15EASPassProtect, IfPm3Iso15693, "Password protect EAS - Cannot be undone"},
|
||||||
{"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"},
|
{"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"},
|
||||||
{"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"},
|
{"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"},
|
||||||
{"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"},
|
{"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"},
|
||||||
|
|
|
@ -177,7 +177,13 @@ const static vocabulory_t vocabulory[] = {
|
||||||
{ 0, "hf 15 esave" },
|
{ 0, "hf 15 esave" },
|
||||||
{ 0, "hf 15 eview" },
|
{ 0, "hf 15 eview" },
|
||||||
{ 0, "hf 15 sim" },
|
{ 0, "hf 15 sim" },
|
||||||
{ 0, "hf 15 slixdisable" },
|
{ 0, "hf 15 slixwritepwd" },
|
||||||
|
{ 0, "hf 15 slixeasdisable" },
|
||||||
|
{ 0, "hf 15 slixeasenable" },
|
||||||
|
{ 0, "hf 15 slixprivacydisable" },
|
||||||
|
{ 0, "hf 15 slixprivacyenable" },
|
||||||
|
{ 0, "hf 15 passprotectafi" },
|
||||||
|
{ 0, "hf 15 passprotecteas" },
|
||||||
{ 0, "hf 15 wrbl" },
|
{ 0, "hf 15 wrbl" },
|
||||||
{ 0, "hf 15 findafi" },
|
{ 0, "hf 15 findafi" },
|
||||||
{ 0, "hf 15 writeafi" },
|
{ 0, "hf 15 writeafi" },
|
||||||
|
|
|
@ -519,8 +519,14 @@ typedef struct {
|
||||||
#define CMD_HF_ISO15693_COMMAND 0x0313
|
#define CMD_HF_ISO15693_COMMAND 0x0313
|
||||||
#define CMD_HF_ISO15693_FINDAFI 0x0315
|
#define CMD_HF_ISO15693_FINDAFI 0x0315
|
||||||
#define CMD_HF_ISO15693_CSETUID 0x0316
|
#define CMD_HF_ISO15693_CSETUID 0x0316
|
||||||
#define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317
|
#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0xA317
|
||||||
#define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318
|
#define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317
|
||||||
|
#define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318
|
||||||
|
#define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862
|
||||||
|
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863
|
||||||
|
#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864
|
||||||
|
#define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865
|
||||||
|
#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
|
||||||
#define CMD_HF_ISO15693_EML_SETMEM 0x0331
|
#define CMD_HF_ISO15693_EML_SETMEM 0x0331
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue