From 9041627ae55676003e5023507a2da3122d816012 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Fri, 27 Jan 2023 22:46:40 -0600 Subject: [PATCH] Add `hf 15` sub-commands for EAS, AFI, privacy mode, and passwords on SLIX tags --- CHANGELOG.md | 2 + armsrc/appmain.c | 68 +++- armsrc/iso15693.c | 391 +++++++++++++++++-- armsrc/iso15693.h | 10 +- client/src/cmdhf15.c | 639 +++++++++++++++++++++++++++----- client/src/pm3line_vocabulory.h | 8 +- include/pm3_cmd.h | 10 +- 7 files changed, 993 insertions(+), 135 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f31361d9d..3a6e2f72c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 `make accessrights` on Fedora (@mooey5775) - 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] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 76d9ac3c0..b26225ccf 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1287,23 +1287,79 @@ static void PacketReceived(PacketCommandNG *packet) { SetTag15693Uid(payload->uid); break; } - case CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY: { + case CMD_HF_ISO15693_SLIX_DISABLE_EAS: { + struct p { + uint8_t pwd[4]; + bool usepwd; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + DisableEAS_AFISlixIso15693(payload->pwd, payload->usepwd); + break; + } + 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 { uint8_t pwd[4]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - DisablePrivacySlixLIso15693(payload->pwd); + DisablePrivacySlixIso15693(payload->pwd); break; } - case CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI: { + case CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY: { struct p { uint8_t pwd[4]; } PACKED; - struct p *payload = (struct p *) packet->data.asBytes; - DisableEAS_AFISlixLIso15693(payload->pwd); + 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; + } + #endif #ifdef WITH_LEGICRF diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index ab650da8f..3ca186305 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -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 // data rate is 1,66 kbit/s (fc/8192) // 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_LOCK_AFI: case ISO15693_WRITE_DSFID: + case ISO15693_WRITE_PASSWORD: + case ISO15693_PASSWORD_PROTECT_EAS: case ISO15693_LOCK_DSFID: timeout = ISO15693_READER_TIMEOUT_WRITE; request_answer = data[0] & ISO15_REQ_OPTION; @@ -2640,7 +2673,7 @@ void SetTag15693Uid(const uint8_t *uid) { 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); if (rnd) { 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. uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 }; AddCrc15(c, 3); 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); + 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) { return false; } @@ -2668,15 +2701,16 @@ static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t 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]; - 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, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - init_password_15693_slixl(&c[4], password, rnd); + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + init_password_15693_Slix(&c[4], password, rnd); AddCrc15(c, 8); 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; } -/* -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) { +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) { + + 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; } 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); - init_password_15693_slixl(&c[11], password, rnd); + init_password_15693_Slix(&c[11], password, rnd); AddCrc15(c, 15); 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; } -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]; - 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; } 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); c[11] = pass_id; - init_password_15693_slixl(&c[12], password, NULL); + init_password_15693_Slix(&c[12], password, NULL); AddCrc15(c, 16); 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; } -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]; - 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; } 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); - init_password_15693_slixl(&c[11], password, rnd); + init_password_15693_Slix(&c[11], password, rnd); AddCrc15(c, 15); 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 DisablePrivacySlixLIso15693(uint8_t *password) { +void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id) { + 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(); Iso15693InitReader(); StartCountSspClk(); @@ -2769,13 +3048,12 @@ void DisablePrivacySlixLIso15693(uint8_t *password) { // 0x04 Privacy // 0x08 Destroy SLIX-L // 0x10 EAS/AFI - int res = set_pass_15693_slixl(start_time, &eof_time, 0x04, password); - reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, res, NULL, 0); + int res = disable_privacy_15693_Slix(start_time, &eof_time, 0x04, password); + reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, res, NULL, 0); switch_off(); } -// Sets a EAS/AFI password to all ZEROS -void DisableEAS_AFISlixLIso15693(uint8_t *password) { +void EnablePrivacySlixIso15693(uint8_t* password) { LED_D_ON(); Iso15693InitReader(); StartCountSspClk(); @@ -2785,8 +3063,71 @@ void DisableEAS_AFISlixLIso15693(uint8_t *password) { // 0x04 Privacy // 0x08 Destroy SLIX-L // 0x10 EAS/AFI - int res = set_pass_15693_slixl(start_time, &eof_time, 0x10, password); - reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI, res, NULL, 0); + int res = set_privacy_15693_Slix(start_time, &eof_time, password); + reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, res, NULL, 0); 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(); +} \ No newline at end of file diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 2097b3769..c0ff44929 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -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 DisablePrivacySlixLIso15693(uint8_t *password); -void DisableEAS_AFISlixLIso15693(uint8_t *password); +void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id); +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 diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 035a2218e..46a89a0c9 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -698,7 +698,7 @@ static int NxpCheckSig(uint8_t *uid) { PacketResponseNG resp; uint16_t reqlen = 0; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; - + // Check if we can also read the signature req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; req[reqlen++] = ISO15693_READ_SIGNATURE; @@ -736,7 +736,7 @@ static int NxpCheckSig(uint8_t *uid) { memcpy(signature, recv + 1, 32); nxp_15693_print_signature(uid, signature); - + return PM3_SUCCESS; } @@ -1352,94 +1352,83 @@ static int CmdHF15WriteAfi(const char *Cmd) { CLIParserInit(&ctx, "hf 15 writeafi", "Write AFI on card", "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] = {}; - uint8_t arglen = arg_add_default(argtable); - argtable[arglen++] = arg_int1(NULL, "afi", "", "AFI number (0-255)"); - argtable[arglen++] = arg_param_end; + void *argtable[5] = {}; + argtable[0] = arg_param_begin; + argtable[1] = arg_str0("u", "uid", "", "full UID, 8 bytes"); + argtable[2] = arg_int1(NULL, "afi", "", "AFI number (0-255)"); + argtable[3] = arg_str0("p", "pwd", "", "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]; + bool use_uid; + uint8_t afi; + } PACKED payload; - uint8_t uid[8]; int uidlen = 0; - CLIGetHexWithReturn(ctx, 1, uid, &uidlen); - bool unaddressed = arg_get_lit(ctx, 2); - bool scan = arg_get_lit(ctx, 3); - int fast = (arg_get_lit(ctx, 4) == false); - bool add_option = arg_get_lit(ctx, 5); + CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); - int afi = arg_get_int_def(ctx, 6, 0); + payload.afi = arg_get_int_def(ctx, 2, 0); + + int pwdlen; + + CLIGetHexWithReturn(ctx, 3, payload.pwd, &pwdlen); + CLIParserFree(ctx); + + if(pwdlen == 4) + { + payload.use_pwd = true; + } + + if(uidlen == 8) + { + payload.use_uid = true; + } // sanity checks - if ((scan + unaddressed + uidlen) > 1) { - PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid"); + if (uidlen != 0 && uidlen != 8) { + PrintAndLogEx(WARNING, "uid must be 8 hex bytes if provided"); return PM3_EINVARG; } - - // request to be sent to device/card - uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option); - uint8_t req[16] = {flags, ISO15693_WRITE_AFI}; - uint16_t reqlen = 2; - - 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)); + + if(pwdlen > 0 && pwdlen != 4) + { + PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + return PM3_ESOFT; } - // 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; clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_response, req, reqlen); - - if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { - PrintAndLogEx(ERR, "iso15693 timeout"); + SendCommandNG(CMD_HF_ISO15693_WRITE_AFI, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_WRITE_AFI, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); - return PM3_ETIMEOUT; - } - DropField(); - - if (resp.status == PM3_ETEAROFF) { - return resp.status; + return PM3_ESOFT; } - 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; + 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; + } } - - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", afi); - return PM3_SUCCESS; + return resp.status; } // 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", "", "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", "", "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) { CLIParserContext *ctx; - CLIParserInit(&ctx, "hf 15 slixdisable", + CLIParserInit(&ctx, "hf 15 slixprivacydisable", "Disable privacy mode on SLIX ISO-15693 tag", "hf 15 slixdisable -p 0F0F0F0F"); @@ -2404,8 +2547,8 @@ static int CmdHF15SlixDisable(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); - if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, &resp, 2000) == false) { + SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, &resp, 2000) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); return PM3_ESOFT; @@ -2428,32 +2571,330 @@ static int CmdHF15SlixDisable(const char *Cmd) { 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", "", "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", "", "which password field to write to (some tags do not support all password types)"), + arg_str0("o", "old", "", "old password (if present), 8 hex bytes"), + arg_str1("n", "new", "", "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", "", "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", "", "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[] = { - {"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, - {"help", CmdHF15Help, AlwaysAvailable, "This help"}, - {"list", CmdHF15List, AlwaysAvailable, "List ISO-15693 history"}, - {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO-15693 from tag"}, - {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO-15693 tag, save to file"}, - {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, - {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO-15693 traffic"}, - {"raw", CmdHF15Raw, IfPm3Iso15693, "Send raw hex data to tag"}, - {"rdbl", CmdHF15Readblock, IfPm3Iso15693, "Read a block"}, - {"rdmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple blocks"}, - {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, - {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, - {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, - {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"}, - {"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"}, - {"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"}, - {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, - {"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, - {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, - {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"}, - {"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"}, - {"writeafi", CmdHF15WriteAfi, IfPm3Iso15693, "Writes the AFI on an ISO-15693 tag"}, - {"writedsfid", CmdHF15WriteDsfid, IfPm3Iso15693, "Writes the DSFID on an ISO-15693 tag"}, - {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("magic") " -----------------------"}, - {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic card"}, + {"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, + {"help", CmdHF15Help, AlwaysAvailable, "This help"}, + {"list", CmdHF15List, AlwaysAvailable, "List ISO-15693 history"}, + {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO-15693 from tag"}, + {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO-15693 tag, save to file"}, + {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, + {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO-15693 traffic"}, + {"raw", CmdHF15Raw, IfPm3Iso15693, "Send raw hex data to tag"}, + {"rdbl", CmdHF15Readblock, IfPm3Iso15693, "Read a block"}, + {"rdmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple blocks"}, + {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, + {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, + {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, + {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"}, + {"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"}, + {"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"}, + {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an 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"}, + {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"}, + {"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"}, + {"writeafi", CmdHF15WriteAfi, IfPm3Iso15693, "Writes the AFI on an ISO-15693 tag"}, + {"writedsfid", CmdHF15WriteDsfid, IfPm3Iso15693, "Writes the DSFID on an ISO-15693 tag"}, + {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("magic") " -----------------------"}, + {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic card"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 4cd9457b5..ee94f7ec0 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -177,7 +177,13 @@ const static vocabulory_t vocabulory[] = { { 0, "hf 15 esave" }, { 0, "hf 15 eview" }, { 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 findafi" }, { 0, "hf 15 writeafi" }, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 95750b9b7..43fd44ac0 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -519,8 +519,14 @@ typedef struct { #define CMD_HF_ISO15693_COMMAND 0x0313 #define CMD_HF_ISO15693_FINDAFI 0x0315 #define CMD_HF_ISO15693_CSETUID 0x0316 -#define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317 -#define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318 +#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0xA317 +#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_ISO15693_EML_CLEAR 0x0330 #define CMD_HF_ISO15693_EML_SETMEM 0x0331