1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2020 iceman1001
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // High frequency ISO14443A / ST25TA commands
9 //-----------------------------------------------------------------------------
11 #include "cmdhfst25ta.h"
14 #include "fileutils.h"
15 #include "cmdparser.h" // command_t
16 #include "comms.h" // clearCommandBuffer
18 #include "cliparser.h"
21 #include "protocols.h" // definitions of ISO14A/7816 protocol
22 #include "iso7816/apduinfo.h" // GetAPDUCodeDescription
23 #include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint
24 #include "cmdnfc.h" // print_type4_cc_info
28 static int CmdHelp(const char *Cmd
);
30 static void print_st25ta_system_info(uint8_t *d
, uint8_t n
) {
32 PrintAndLogEx(WARNING
, "Not enough bytes read from system file");
36 PrintAndLogEx(NORMAL
, "");
37 PrintAndLogEx(SUCCESS
, "------------ " _CYAN_("ST System file") " ------------");
39 uint16_t len
= (d
[0] << 8 | d
[1]);
40 PrintAndLogEx(SUCCESS
, " len %u bytes (" _GREEN_("0x%04X") ")", len
, len
);
43 PrintAndLogEx(SUCCESS
, " ST reserved ( 0x%02X )", d
[2]);
45 PrintAndLogEx(SUCCESS
, " GPO Config ( 0x%02X )", d
[2]);
46 PrintAndLogEx(SUCCESS
, " config lock bit ( %s )", ((d
[2] & 0x80) == 0x80) ? _RED_("locked") : _GREEN_("unlocked"));
47 uint8_t conf
= (d
[2] & 0x70) >> 4;
50 PrintAndLogEx(SUCCESS
, "");
53 PrintAndLogEx(SUCCESS
, "Session opened");
56 PrintAndLogEx(SUCCESS
, "WIP");
59 PrintAndLogEx(SUCCESS
, "MIP");
62 PrintAndLogEx(SUCCESS
, "Interrupt");
65 PrintAndLogEx(SUCCESS
, "State Control");
68 PrintAndLogEx(SUCCESS
, "RF Busy");
71 PrintAndLogEx(SUCCESS
, "Field Detect");
76 PrintAndLogEx(SUCCESS
, " Event counter config ( 0x%02X )", d
[3]);
77 PrintAndLogEx(SUCCESS
, " config lock bit ( %s )", ((d
[3] & 0x80) == 0x80) ? _RED_("locked") : _GREEN_("unlocked"));
78 PrintAndLogEx(SUCCESS
, " counter ( %s )", ((d
[3] & 0x02) == 0x02) ? _RED_("enabled") : _GREEN_("disable"));
79 PrintAndLogEx(SUCCESS
, " counter increment on ( %s )", ((d
[3] & 0x01) == 0x01) ? _YELLOW_("write") : _YELLOW_("read"));
81 uint32_t counter
= (d
[4] << 16 | d
[5] << 8 | d
[6]);
82 PrintAndLogEx(SUCCESS
, " 20bit counter ( 0x%05X )", counter
& 0xFFFFF);
84 PrintAndLogEx(SUCCESS
, " Product version ( 0x%02X )", d
[7]);
86 PrintAndLogEx(SUCCESS
, " UID " _GREEN_("%s"), sprint_hex_inrow(d
+ 8, 7));
87 PrintAndLogEx(SUCCESS
, " MFG 0x%02X, " _YELLOW_("%s"), d
[8], getTagInfo(d
[8]));
88 PrintAndLogEx(SUCCESS
, " Product Code 0x%02X, " _YELLOW_("%s"), d
[9], get_st_chip_model(d
[9]));
89 PrintAndLogEx(SUCCESS
, " Device# " _YELLOW_("%s"), sprint_hex_inrow(d
+ 10, 5));
91 uint16_t mem
= (d
[0xF] << 8 | d
[0x10]);
92 PrintAndLogEx(SUCCESS
, " Memory Size - 1 %u bytes (" _GREEN_("0x%04X") ")", mem
, mem
);
94 PrintAndLogEx(SUCCESS
, " IC Reference code %u ( 0x%02X )", d
[0x12], d
[0x12]);
96 PrintAndLogEx(SUCCESS
, "----------------- " _CYAN_("raw") " -----------------");
97 PrintAndLogEx(SUCCESS
, "%s", sprint_hex_inrow(d
, n
));
98 PrintAndLogEx(NORMAL
, "");
102 80000000001302E2007D0E8DCC
106 static uint16_t get_sw(uint8_t *d
, uint8_t n
) {
111 return d
[n
] * 0x0100 + d
[n
+ 1];
115 static int infoHFST25TA(void) {
117 bool activate_field
= true;
118 bool keep_field_on
= true;
119 uint8_t response
[PM3_CMD_DATA_SIZE
];
122 // --------------- Select NDEF Tag application ----------------
123 uint8_t aSELECT_AID
[80];
124 int aSELECT_AID_n
= 0;
125 param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID
, sizeof(aSELECT_AID
), &aSELECT_AID_n
);
126 int res
= ExchangeAPDU14a(aSELECT_AID
, aSELECT_AID_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
127 if (res
!= PM3_SUCCESS
) {
137 uint16_t sw
= get_sw(response
, resplen
);
139 PrintAndLogEx(ERR
, "Selecting NDEF aid failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
144 activate_field
= false;
145 keep_field_on
= true;
146 // --------------- CC file reading ----------------
148 uint8_t aSELECT_FILE_CC
[30];
149 int aSELECT_FILE_CC_n
= 0;
150 param_gethex_to_eol("00a4000c02e103", 0, aSELECT_FILE_CC
, sizeof(aSELECT_FILE_CC
), &aSELECT_FILE_CC_n
);
151 res
= ExchangeAPDU14a(aSELECT_FILE_CC
, aSELECT_FILE_CC_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
152 if (res
!= PM3_SUCCESS
) {
157 sw
= get_sw(response
, resplen
);
159 PrintAndLogEx(ERR
, "Selecting CC file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
164 uint8_t aREAD_CC
[30];
166 param_gethex_to_eol("00b000000f", 0, aREAD_CC
, sizeof(aREAD_CC
), &aREAD_CC_n
);
167 res
= ExchangeAPDU14a(aREAD_CC
, aREAD_CC_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
168 if (res
!= PM3_SUCCESS
) {
173 sw
= get_sw(response
, resplen
);
175 PrintAndLogEx(ERR
, "reading CC file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
179 // store st cc data for later
180 uint8_t st_cc_data
[resplen
- 2];
181 memcpy(st_cc_data
, response
, sizeof(st_cc_data
));
183 // --------------- System file reading ----------------
184 uint8_t aSELECT_FILE_SYS
[30];
185 int aSELECT_FILE_SYS_n
= 0;
186 param_gethex_to_eol("00a4000c02e101", 0, aSELECT_FILE_SYS
, sizeof(aSELECT_FILE_SYS
), &aSELECT_FILE_SYS_n
);
187 res
= ExchangeAPDU14a(aSELECT_FILE_SYS
, aSELECT_FILE_SYS_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
188 if (res
!= PM3_SUCCESS
) {
193 sw
= get_sw(response
, resplen
);
195 PrintAndLogEx(ERR
, "Selecting system file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
200 keep_field_on
= false;
202 uint8_t aREAD_SYS
[30];
204 param_gethex_to_eol("00b0000012", 0, aREAD_SYS
, sizeof(aREAD_SYS
), &aREAD_SYS_n
);
205 res
= ExchangeAPDU14a(aREAD_SYS
, aREAD_SYS_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
206 if (res
!= PM3_SUCCESS
) {
211 sw
= get_sw(response
, resplen
);
213 PrintAndLogEx(ERR
, "reading system file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
220 PrintAndLogEx(NORMAL
, "");
221 PrintAndLogEx(INFO
, "--- " _CYAN_("Tag Information") " ---------------------------");
222 PrintAndLogEx(NORMAL
, "");
223 print_type4_cc_info(st_cc_data
, sizeof(st_cc_data
));
224 print_st25ta_system_info(response
, resplen
- 2);
228 // menu command to get and print all info known about any known ST25TA tag
229 static int CmdHFST25TAInfo(const char *Cmd
) {
230 CLIParserContext
*ctx
;
231 CLIParserInit(&ctx
, "hf st25ta info",
232 "Get info about ST25TA tag",
240 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
242 return infoHFST25TA();
245 static int CmdHFST25TASim(const char *Cmd
) {
247 uint8_t uid
[7] = {0};
249 CLIParserContext
*ctx
;
250 CLIParserInit(&ctx
, "hf st25ta sim",
251 "Emulating ST25TA512B tag with 7 byte UID",
252 "hf st25ta sim -u 02E2007D0FCA4C\n");
256 arg_str1("u", "uid", "<hex>", "7 byte UID"),
259 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
260 CLIGetHexWithReturn(ctx
, 1, uid
, &uidlen
);
264 PrintAndLogEx(ERR
, "UID must be 7 hex bytes");
269 snprintf(param
, sizeof(param
), "-t 10 -u %s", sprint_hex_inrow(uid
, uidlen
));
270 return CmdHF14ASim(param
);
273 int CmdHFST25TANdefRead(const char *Cmd
) {
275 uint8_t pwd
[16] = {0};
276 bool with_pwd
= false;
278 CLIParserContext
*ctx
;
279 CLIParserInit(&ctx
, "hf st25ta ndefread",
280 "Read NFC Data Exchange Format (NDEF) file on ST25TA",
281 "hf st25ta ndefread -p 82E80053D4CA5C0B656D852CC696C8A1\n");
285 arg_str0("p", "pwd", "<hex>", "16 byte read password"),
288 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
289 CLIGetHexWithReturn(ctx
, 1, pwd
, &pwdlen
);
296 PrintAndLogEx(ERR
, "Password must be 16 hex bytes");
302 bool activate_field
= true;
303 bool keep_field_on
= true;
304 uint8_t response
[PM3_CMD_DATA_SIZE
];
307 // --------------- Select NDEF Tag application ----------------
308 uint8_t aSELECT_AID
[80];
309 int aSELECT_AID_n
= 0;
310 param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID
, sizeof(aSELECT_AID
), &aSELECT_AID_n
);
311 int res
= ExchangeAPDU14a(aSELECT_AID
, aSELECT_AID_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
312 if (res
!= PM3_SUCCESS
) {
322 uint16_t sw
= get_sw(response
, resplen
);
324 PrintAndLogEx(ERR
, "Selecting NDEF aid failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
329 activate_field
= false;
330 keep_field_on
= true;
332 // --------------- NDEF file reading ----------------
333 uint8_t aSELECT_FILE_NDEF
[30];
334 int aSELECT_FILE_NDEF_n
= 0;
335 param_gethex_to_eol("00a4000c020001", 0, aSELECT_FILE_NDEF
, sizeof(aSELECT_FILE_NDEF
), &aSELECT_FILE_NDEF_n
);
336 res
= ExchangeAPDU14a(aSELECT_FILE_NDEF
, aSELECT_FILE_NDEF_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
337 if (res
!= PM3_SUCCESS
) {
342 sw
= get_sw(response
, resplen
);
344 PrintAndLogEx(ERR
, "Selecting NDEF file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
350 // --------------- VERIFY ----------------
353 param_gethex_to_eol("0020000100", 0, aVERIFY
, sizeof(aVERIFY
), &aVERIFY_n
);
354 res
= ExchangeAPDU14a(aVERIFY
, aVERIFY_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
355 if (res
!= PM3_SUCCESS
) {
360 sw
= get_sw(response
, resplen
);
362 // need to provide 16byte password
363 param_gethex_to_eol("0020000110", 0, aVERIFY
, sizeof(aVERIFY
), &aVERIFY_n
);
364 memcpy(aVERIFY
+ aVERIFY_n
, pwd
, pwdlen
);
365 res
= ExchangeAPDU14a(aVERIFY
, aVERIFY_n
+ pwdlen
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
366 if (res
!= PM3_SUCCESS
) {
371 sw
= get_sw(response
, resplen
);
373 PrintAndLogEx(ERR
, "Verify password failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
380 keep_field_on
= false;
381 uint8_t aREAD_NDEF
[30];
382 int aREAD_NDEF_n
= 0;
383 param_gethex_to_eol("00b000001d", 0, aREAD_NDEF
, sizeof(aREAD_NDEF
), &aREAD_NDEF_n
);
384 res
= ExchangeAPDU14a(aREAD_NDEF
, aREAD_NDEF_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
385 if (res
!= PM3_SUCCESS
) {
390 sw
= get_sw(response
, resplen
);
392 PrintAndLogEx(ERR
, "reading NDEF file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
397 NDEFRecordsDecodeAndPrint(response
+ 2, resplen
- 4);
401 static int CmdHFST25TAProtect(const char *Cmd
) {
404 uint8_t pwd
[16] = {0};
406 uint8_t state
[3] = {0x26, 0, 0x02};
408 bool disable_protection
= false;
409 bool enable_protection
= false;
410 bool read_protection
= false;
411 bool write_protection
= false;
413 CLIParserContext
*ctx
;
414 CLIParserInit(&ctx
, "hf st25ta protect",
415 "Change read or write protection for NFC Data Exchange Format (NDEF) file on ST25TA",
416 "hf st25ta protect -p 82E80053D4CA5C0B656D852CC696C8A1 -r -e -> enable read protection\n"
417 "hf st25ta protect -p 82E80053D4CA5C0B656D852CC696C8A1 -w -d -> disable write protection\n");
421 arg_lit0("e", "enable", "enable protection"),
422 arg_lit0("d", "disable", "disable protection (default)"),
423 arg_lit0("r", "read", "change read protection"),
424 arg_lit0("w", "write", "change write protection (default)"),
425 arg_str1("p", "password", "<hex>", "16 byte write password"),
428 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
430 enable_protection
= arg_get_lit(ctx
, 1);
431 disable_protection
= arg_get_lit(ctx
, 2);
432 read_protection
= arg_get_lit(ctx
, 3);
433 write_protection
= arg_get_lit(ctx
, 4);
434 CLIGetHexWithReturn(ctx
, 5, pwd
, &pwdlen
);
438 if (enable_protection
&& disable_protection
) {
439 PrintAndLogEx(ERR
, "Must specify either enable or disable protection, not both");
442 if (enable_protection
) {
445 if (disable_protection
) {
449 if (read_protection
&& write_protection
) {
450 PrintAndLogEx(ERR
, "Must specify either read or write protection, not both");
453 if (read_protection
) {
456 if (write_protection
) {
461 PrintAndLogEx(ERR
, "Missing 16 byte password");
465 bool activate_field
= true;
466 bool keep_field_on
= true;
467 uint8_t response
[PM3_CMD_DATA_SIZE
];
470 // --------------- Select NDEF Tag application ----------------
471 uint8_t aSELECT_AID
[80];
472 int aSELECT_AID_n
= 0;
473 param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID
, sizeof(aSELECT_AID
), &aSELECT_AID_n
);
474 int res
= ExchangeAPDU14a(aSELECT_AID
, aSELECT_AID_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
475 if (res
!= PM3_SUCCESS
) {
485 uint16_t sw
= get_sw(response
, resplen
);
487 PrintAndLogEx(ERR
, "Selecting NDEF aid failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
492 activate_field
= false;
493 keep_field_on
= true;
495 // --------------- Select NDEF file ----------------
496 uint8_t aSELECT_FILE_NDEF
[30];
497 int aSELECT_FILE_NDEF_n
= 0;
498 param_gethex_to_eol("00a4000c020001", 0, aSELECT_FILE_NDEF
, sizeof(aSELECT_FILE_NDEF
), &aSELECT_FILE_NDEF_n
);
499 res
= ExchangeAPDU14a(aSELECT_FILE_NDEF
, aSELECT_FILE_NDEF_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
500 if (res
!= PM3_SUCCESS
) {
505 sw
= get_sw(response
, resplen
);
507 PrintAndLogEx(ERR
, "Selecting NDEF file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
512 // --------------- VERIFY ----------------
515 // need to provide 16byte password
516 param_gethex_to_eol("0020000210", 0, aVERIFY
, sizeof(aVERIFY
), &aVERIFY_n
);
517 memcpy(aVERIFY
+ aVERIFY_n
, pwd
, pwdlen
);
518 res
= ExchangeAPDU14a(aVERIFY
, aVERIFY_n
+ pwdlen
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
519 if (res
!= PM3_SUCCESS
) {
524 sw
= get_sw(response
, resplen
);
526 PrintAndLogEx(ERR
, "Verify password failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
531 // --------------- Change protection ----------------
532 keep_field_on
= false;
533 uint8_t aPROTECT
[30];
535 param_gethex_to_eol("00", 0, aPROTECT
, sizeof(aPROTECT
), &aPROTECT_n
);
536 memcpy(aPROTECT
+ aPROTECT_n
, state
, statelen
);
537 res
= ExchangeAPDU14a(aPROTECT
, aPROTECT_n
+ statelen
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
538 if (res
!= PM3_SUCCESS
) {
543 sw
= get_sw(response
, resplen
);
545 PrintAndLogEx(ERR
, "changing protection failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
550 PrintAndLogEx(SUCCESS
, " %s protection ( %s )", ((state
[2] & 0x01) == 0x01) ? _YELLOW_("read") : _YELLOW_("write"),
551 ((state
[0] & 0x28) == 0x28) ? _RED_("enabled") : _GREEN_("disabled"));
556 static int CmdHFST25TAPwd(const char *Cmd
) {
559 uint8_t pwd
[16] = {0};
561 uint8_t newpwd
[16] = {0};
562 int changePwdlen
= 4;
563 uint8_t changePwd
[4] = {0x24, 0x00, 0x01, 0x10};
564 bool change_read_password
= false;
565 bool change_write_password
= false;
567 CLIParserContext
*ctx
;
568 CLIParserInit(&ctx
, "hf st25ta pwd",
569 "Change read or write password for NFC Data Exchange Format (NDEF) file on ST25TA",
570 "hf st25ta pwd -p 82E80053D4CA5C0B656D852CC696C8A1 -r -n 00000000000000000000000000000000 -> change read password\n"
571 "hf st25ta pwd -p 82E80053D4CA5C0B656D852CC696C8A1 -w -n 00000000000000000000000000000000 -> change write password\n");
575 arg_lit0("r", "read", "change the read password (default)"),
576 arg_lit0("w", "write", "change the write password"),
577 arg_str1("p", "password", "<hex>", "current 16 byte write password"),
578 arg_str1("n", "new", "<hex>", "new 16 byte password"),
581 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
583 change_read_password
= arg_get_lit(ctx
, 1);
584 change_write_password
= arg_get_lit(ctx
, 2);
585 CLIGetHexWithReturn(ctx
, 3, pwd
, &pwdlen
);
586 CLIGetHexWithReturn(ctx
, 4, newpwd
, &newpwdlen
);
589 if (change_read_password
&& change_write_password
) {
590 PrintAndLogEx(ERR
, "Must specify either read or write, not both");
593 if (change_read_password
) {
596 if (change_write_password
) {
601 PrintAndLogEx(ERR
, "Original write password must be 16 hex bytes");
604 if (newpwdlen
!= 16) {
605 PrintAndLogEx(ERR
, "New password must be 16 hex bytes");
609 bool activate_field
= true;
610 bool keep_field_on
= true;
611 uint8_t response
[PM3_CMD_DATA_SIZE
];
614 // --------------- Select NDEF Tag application ----------------
615 uint8_t aSELECT_AID
[80];
616 int aSELECT_AID_n
= 0;
617 param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID
, sizeof(aSELECT_AID
), &aSELECT_AID_n
);
618 int res
= ExchangeAPDU14a(aSELECT_AID
, aSELECT_AID_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
619 if (res
!= PM3_SUCCESS
) {
629 uint16_t sw
= get_sw(response
, resplen
);
631 PrintAndLogEx(ERR
, "Selecting NDEF aid failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
636 activate_field
= false;
637 keep_field_on
= true;
639 // --------------- Select NDEF file ----------------
640 uint8_t aSELECT_FILE_NDEF
[30];
641 int aSELECT_FILE_NDEF_n
= 0;
642 param_gethex_to_eol("00a4000c020001", 0, aSELECT_FILE_NDEF
, sizeof(aSELECT_FILE_NDEF
), &aSELECT_FILE_NDEF_n
);
643 res
= ExchangeAPDU14a(aSELECT_FILE_NDEF
, aSELECT_FILE_NDEF_n
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
644 if (res
!= PM3_SUCCESS
) {
649 sw
= get_sw(response
, resplen
);
651 PrintAndLogEx(ERR
, "Selecting NDEF file failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
656 // --------------- VERIFY ----------------
659 // need to provide 16byte password
660 param_gethex_to_eol("0020000210", 0, aVERIFY
, sizeof(aVERIFY
), &aVERIFY_n
);
661 memcpy(aVERIFY
+ aVERIFY_n
, pwd
, pwdlen
);
662 res
= ExchangeAPDU14a(aVERIFY
, aVERIFY_n
+ pwdlen
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
663 if (res
!= PM3_SUCCESS
) {
668 sw
= get_sw(response
, resplen
);
670 PrintAndLogEx(ERR
, "Verify password failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
675 // --------------- Change password ----------------
677 keep_field_on
= false;
678 uint8_t aCHG_PWD
[30];
680 param_gethex_to_eol("00", 0, aCHG_PWD
, sizeof(aCHG_PWD
), &aCHG_PWD_n
);
681 memcpy(aCHG_PWD
+ aCHG_PWD_n
, changePwd
, changePwdlen
);
682 memcpy(aCHG_PWD
+ aCHG_PWD_n
+ changePwdlen
, newpwd
, newpwdlen
);
683 res
= ExchangeAPDU14a(aCHG_PWD
, aCHG_PWD_n
+ changePwdlen
+ newpwdlen
, activate_field
, keep_field_on
, response
, sizeof(response
), &resplen
);
684 if (res
!= PM3_SUCCESS
) {
689 sw
= get_sw(response
, resplen
);
691 PrintAndLogEx(ERR
, "password change failed (%04x - %s).", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
695 PrintAndLogEx(SUCCESS
, " %s password changed", ((changePwd
[2] & 0x01) == 0x01) ? _YELLOW_("read") : _YELLOW_("write"));
699 static int CmdHFST25TAList(const char *Cmd
) {
700 return CmdTraceListAlias(Cmd
, "hf st25ta", "7816");
703 static command_t CommandTable
[] = {
704 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
705 {"info", CmdHFST25TAInfo
, IfPm3Iso14443a
, "Tag information"},
706 {"list", CmdHFST25TAList
, AlwaysAvailable
, "List ISO 14443A/7816 history"},
707 {"ndefread", CmdHFST25TANdefRead
, AlwaysAvailable
, "read NDEF file on tag"},
708 {"protect", CmdHFST25TAProtect
, IfPm3Iso14443a
, "change protection on tag"},
709 {"pwd", CmdHFST25TAPwd
, IfPm3Iso14443a
, "change password on tag"},
710 {"sim", CmdHFST25TASim
, IfPm3Iso14443a
, "Fake ISO 14443A/ST tag"},
711 {NULL
, NULL
, NULL
, NULL
}
714 static int CmdHelp(const char *Cmd
) {
715 (void)Cmd
; // Cmd is not used so far
716 CmdsHelp(CommandTable
);
720 int CmdHFST25TA(const char *Cmd
) {
721 clearCommandBuffer();
722 return CmdsParse(CommandTable
, Cmd
);