mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge remote-tracking branch 'upstream/master' into felica_support_authV1
# Conflicts: # client/cmdhffelica.c
This commit is contained in:
@@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added `hf mf cwipe` magic chinese card (gen1a) wipe to default state (@merlokk)
|
||||
- Added 'pm3_mf7b_wipe.py' python script. Wipes magic S70 7B Gen2 card. (@vulnersCom)
|
||||
- Added `hf mfp chk` Mifare plus command for check keys from public keys list, from dictionary or 1 and 2-byte bruteforce (@merlokk)
|
||||
- Change `hf 15` - some refactoring (@grspy)
|
||||
- Added `hf 15 writeafi` and `hf 15 writedsfid` (@grspy)
|
||||
- Added detailed info for SLIX2 tags in `hf 15 info` (@grspy)
|
||||
- Fix hf list felica and hf felica sniff (@7homasSutter)
|
||||
- Added hf felica wrunencrypted (@7homasSutter)
|
||||
- Added hf felica rdunencrypted (@7homasSutter)
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
# RRG / Iceman repo - Proxmark3
|
||||
|
||||
This repo is based on iceman fork for Proxmark3.
|
||||
|
||||
It supports RDV4.0 and other Proxmark3 platforms as well.
|
||||
|
||||
|
||||
| Releases | Linux & OSX CI | Windows CI | Coverity |
|
||||
| ------------------- |:-------------------:| -------------------:| -------------------:|
|
||||
| [](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [](https://travis-ci.org/RfidResearchGroup/proxmark3) | [](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)|
|
||||
---
|
||||
|
||||
|
||||
|
||||
# PROXMARK INSTALLATION AND OVERVIEW
|
||||
|
||||
@@ -29,10 +26,12 @@ It supports RDV4.0 and other Proxmark3 platforms as well.
|
||||
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) ||
|
||||
|[Donations](#Donations)|||
|
||||
|
||||
## Support on other Proxmark3 platforms
|
||||
|
||||
## Build for non-RDV4 Proxmark3 platforms
|
||||
|
||||
In order to build this repo for other Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)
|
||||
|
||||
|
||||
## What has changed?
|
||||
|
||||
On the hardware side:
|
||||
@@ -110,4 +109,3 @@ Nothing says thank you as much as a donation. So if you feel the love, do feel f
|
||||
|
||||
https://www.patreon.com/iceman1001
|
||||
|
||||
All support is welcome!
|
||||
|
||||
+10
-1
@@ -929,6 +929,7 @@ void BruteforceIso15693Afi(uint32_t speed) {
|
||||
uint8_t buf[ISO15_MAX_FRAME];
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
int datalen = 0, recvlen = 0;
|
||||
bool aborted = false;
|
||||
|
||||
Iso15693InitReader();
|
||||
|
||||
@@ -966,7 +967,9 @@ void BruteforceIso15693Afi(uint32_t speed) {
|
||||
Dbprintf("AFI = %i UID = %s", i, sprintUID(NULL, buf + 2));
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS()) {
|
||||
aborted = BUTTON_PRESS();
|
||||
|
||||
if (aborted) {
|
||||
DbpString("button pressed, aborting..");
|
||||
break;
|
||||
}
|
||||
@@ -974,6 +977,12 @@ void BruteforceIso15693Afi(uint32_t speed) {
|
||||
|
||||
DbpString("AFI Bruteforcing done.");
|
||||
switch_off();
|
||||
|
||||
if (aborted) {
|
||||
reply_ng(CMD_ACK, PM3_EOPABORTED, NULL, 0);
|
||||
} else {
|
||||
reply_ng(CMD_ACK, PM3_SUCCESS, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Allows to directly send commands to the tag via the client
|
||||
|
||||
+8
-1
@@ -32,6 +32,7 @@
|
||||
#include "crc16.h"
|
||||
#include "dbprint.h"
|
||||
#include "ticks.h"
|
||||
#include "usb_cdc.h" // usb_poll_validate_length
|
||||
|
||||
#ifndef HARDNESTED_AUTHENTICATION_TIMEOUT
|
||||
# define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
||||
@@ -918,7 +919,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||
for (rtr = 0; rtr < 17; rtr++) {
|
||||
|
||||
// Test if the action was cancelled
|
||||
if (BUTTON_PRESS()) {
|
||||
if (BUTTON_PRESS() || usb_poll_validate_length()) {
|
||||
isOK = -2;
|
||||
break;
|
||||
}
|
||||
@@ -998,6 +999,12 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
||||
target_nt[i] = 0;
|
||||
while (target_nt[i] == 0) { // continue until we have an unambiguous nonce
|
||||
|
||||
// Test if the action was cancelled
|
||||
if (BUTTON_PRESS() || usb_poll_validate_length()) {
|
||||
isOK = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
// prepare next select. No need to power down the card.
|
||||
if (mifare_classic_halt(pcs, cuid)) {
|
||||
if (DBGLEVEL >= DBG_INFO) Dbprintf("Nested: Halt error");
|
||||
|
||||
@@ -134,6 +134,7 @@ CORESRCS = uart_posix.c \
|
||||
|
||||
CMDSRCS = crapto1/crapto1.c \
|
||||
crapto1/crypto1.c \
|
||||
mifare/mifaredefault.c \
|
||||
mifare/mfkey.c \
|
||||
tea.c \
|
||||
fido/additional_ca.c \
|
||||
|
||||
+4
-4
@@ -406,7 +406,7 @@ static int CmdSetDebugMode(const char *Cmd) {
|
||||
void printDemodBuff(void) {
|
||||
int len = DemodBufferLen;
|
||||
if (len < 1) {
|
||||
PrintAndLogEx(NORMAL, "(printDemodBuff) no bits found in demod buffer");
|
||||
PrintAndLogEx(INFO, "(printDemodBuff) no bits found in demod buffer");
|
||||
return;
|
||||
}
|
||||
if (len > 512) len = 512;
|
||||
@@ -458,7 +458,7 @@ int CmdPrintDemodBuff(const char *Cmd) {
|
||||
if (errors) return usage_data_printdemodbuf();
|
||||
|
||||
if (DemodBufferLen == 0) {
|
||||
PrintAndLogEx(NORMAL, "Demodbuffer is empty");
|
||||
PrintAndLogEx(WARNING, "Demodbuffer is empty");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
if (lstrip) {
|
||||
@@ -491,9 +491,9 @@ int CmdPrintDemodBuff(const char *Cmd) {
|
||||
if (numBits == 0) {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "DemodBuffer: %s", hex);
|
||||
PrintAndLogEx(SUCCESS, "DemodBuffer: %s", hex);
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "DemodBuffer:\n%s", sprint_bin_break(DemodBuffer + offset, length, 32));
|
||||
PrintAndLogEx(SUCCESS, "DemodBuffer:\n%s", sprint_bin_break(DemodBuffer + offset, length, 32));
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
+6
-7
@@ -77,7 +77,7 @@ int CmdHFSearch(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_search();
|
||||
|
||||
PrintAndLogEx(INFO, "Checking for known tags...\n");
|
||||
PrintAndLogEx(INFO, "Checking for known tags...");
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
|
||||
@@ -100,13 +100,10 @@ int CmdHFSearch(const char *Cmd) {
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for ISO15693 tag...");
|
||||
if (IfPm3Iso15693()) {
|
||||
if (readHF15Uid(false) == 1) {
|
||||
if (readHF15Uid(false)) {
|
||||
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n");
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
// until refactoring of ISO15693 cmds, this is needed.
|
||||
DropField();
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
@@ -155,8 +152,10 @@ int CmdHFSearch(const char *Cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(INPLACE, "No known/supported 13.56 MHz tags found");
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "done");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(FAILED, _RED_("No known/supported 13.56 MHz tags found"));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
@@ -166,7 +165,7 @@ int CmdHFTune(const char *Cmd) {
|
||||
int iter = param_get32ex(Cmd, 0, 0, 10);
|
||||
|
||||
PacketResponseNG resp;
|
||||
PrintAndLogEx(SUCCESS, "Measuring HF antenna, click button or press Enter to exit");
|
||||
PrintAndLogEx(SUCCESS, "Measuring HF antenna," _YELLOW_("click button") " or press" _YELLOW_("Enter") "to exit");
|
||||
clearCommandBuffer();
|
||||
uint8_t mode[] = {1};
|
||||
SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode));
|
||||
|
||||
+78
-77
@@ -256,20 +256,20 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
|
||||
}
|
||||
|
||||
if (select_status == 3) {
|
||||
PrintAndLogEx(NORMAL, "E->Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLogEx(NORMAL, "\tATQA : %02x %02x", card->atqa[1], card->atqa[0]);
|
||||
PrintAndLogEx(INFO, "E->Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLogEx(SUCCESS, "\tATQA : %02x %02x", card->atqa[1], card->atqa[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(card->uid, card->uidlen));
|
||||
PrintAndLogEx(NORMAL, "ATQA: %02x %02x", card->atqa[1], card->atqa[0]);
|
||||
PrintAndLogEx(NORMAL, " SAK: %02x [%" PRIu64 "]", card->sak, resp.oldarg[0]);
|
||||
PrintAndLogEx(SUCCESS, " UID: %s", sprint_hex(card->uid, card->uidlen));
|
||||
PrintAndLogEx(SUCCESS, "ATQA: %02x %02x", card->atqa[1], card->atqa[0]);
|
||||
PrintAndLogEx(SUCCESS, " SAK: %02x [%" PRIu64 "]", card->sak, resp.oldarg[0]);
|
||||
if (card->ats_len < 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
|
||||
PrintAndLogEx(NORMAL, "E-> Error ATS length(%d) : %s", card->ats_len, sprint_hex(card->ats, card->ats_len));
|
||||
PrintAndLogEx(INFO, "E-> Error ATS length(%d) : %s", card->ats_len, sprint_hex(card->ats, card->ats_len));
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " ATS: %s", sprint_hex(card->ats, card->ats_len));
|
||||
PrintAndLogEx(SUCCESS, " ATS: %s", sprint_hex(card->ats, card->ats_len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -334,18 +334,18 @@ static int CmdHF14AReader(const char *Cmd) {
|
||||
}
|
||||
|
||||
if (select_status == 3) {
|
||||
PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
DropField();
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]);
|
||||
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLogEx(SUCCESS, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]);
|
||||
|
||||
if (card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
|
||||
PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len));
|
||||
PrintAndLogEx(SUCCESS, " ATS : %s", sprint_hex(card.ats, card.ats_len));
|
||||
}
|
||||
|
||||
if (!disconnectAfter) {
|
||||
@@ -422,7 +422,7 @@ static int CmdHF14ACUIDs(const char *Cmd) {
|
||||
for (uint16_t m = 0; m < card->uidlen; m++) {
|
||||
sprintf(&uid_string[2 * m], "%02X", card->uid[m]);
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "%s", uid_string);
|
||||
PrintAndLogEx(SUCCESS, "%s", uid_string);
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "end: %" PRIu64 " seconds", (msclock() - t1) / 1000);
|
||||
@@ -528,9 +528,9 @@ int CmdHF14ASim(const char *Cmd) {
|
||||
|
||||
if (keypress && (flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) {
|
||||
// inform device to break the sim loop since client has exited
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
if (resp.status == PM3_EOPABORTED && ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK))
|
||||
showSectorTable();
|
||||
|
||||
@@ -551,30 +551,29 @@ int CmdHF14ASniff(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
|
||||
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode) {
|
||||
static uint8_t responseNum = 0;
|
||||
uint16_t cmdc = 0;
|
||||
*dataoutlen = 0;
|
||||
|
||||
if (activateField) {
|
||||
responseNum = 1;
|
||||
PacketResponseNG resp;
|
||||
|
||||
// Anticollision + SELECT card
|
||||
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(ERR, "Proxmark3 connection timeout.");
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check result
|
||||
if (resp.oldarg[0] == 0) {
|
||||
PrintAndLogEx(ERR, "No card in field.");
|
||||
if (!silentMode) PrintAndLogEx(ERR, "No card in field.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) {
|
||||
PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]);
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -583,12 +582,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
|
||||
SendCommandOLD(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, 2, 0, rats, 2);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(ERR, "Proxmark3 connection timeout.");
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Proxmark3 connection timeout.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (resp.oldarg[0] == 0) { // ats_len
|
||||
PrintAndLogEx(ERR, "Can't get ATS.");
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Can't get ATS.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -610,7 +609,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
int iLen = resp.oldarg[0];
|
||||
|
||||
if (!iLen) {
|
||||
PrintAndLogEx(ERR, "No card response.");
|
||||
if (!silentMode) PrintAndLogEx(ERR, "No card response.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -619,12 +618,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
*dataoutlen = 0;
|
||||
|
||||
if (maxdataoutlen && *dataoutlen > maxdataoutlen) {
|
||||
PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen);
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Buffer too small(%d). Needs %d bytes", *dataoutlen, maxdataoutlen);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (recv[0] != data[0]) {
|
||||
PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", dataout[0], data[0]);
|
||||
if (!silentMode) PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", dataout[0], data[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -632,12 +631,12 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
|
||||
// CRC Check
|
||||
if (iLen == -1) {
|
||||
PrintAndLogEx(ERR, "ISO 14443A CRC error.");
|
||||
if (!silentMode) PrintAndLogEx(ERR, "ISO 14443A CRC error.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Reply timeout.");
|
||||
if (!silentMode) PrintAndLogEx(ERR, "Reply timeout.");
|
||||
return 4;
|
||||
}
|
||||
|
||||
@@ -1273,16 +1272,18 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
return select_status;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
if (select_status == 3) {
|
||||
PrintAndLogEx(NORMAL, "Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision");
|
||||
PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
DropField();
|
||||
return select_status;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(NORMAL, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLogEx(NORMAL, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]);
|
||||
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(SUCCESS, "ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLogEx(SUCCESS, " SAK : %02x [%" PRIu64 "]", card.sak, resp.oldarg[0]);
|
||||
|
||||
bool isMifareClassic = true;
|
||||
switch (card.sak) {
|
||||
@@ -1296,7 +1297,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
if (tagT != UL_ERROR)
|
||||
ul_print_type(tagT, 0);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, "TYPE: Possible AZTEK (iso14443a compliant)");
|
||||
PrintAndLogEx(SUCCESS, "TYPE: Possible AZTEK (iso14443a compliant)");
|
||||
|
||||
// reconnect for further tests
|
||||
clearCommandBuffer();
|
||||
@@ -1313,49 +1314,49 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP TNP3xxx Activision Game Appliance");
|
||||
break;
|
||||
case 0x04:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)");
|
||||
isMifareClassic = false;
|
||||
break;
|
||||
case 0x08:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1");
|
||||
break;
|
||||
case 0x09:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Mini 0.3k");
|
||||
break;
|
||||
case 0x0A:
|
||||
PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : FM11RF005SH (Shanghai Metro)");
|
||||
break;
|
||||
case 0x10:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 2k SL2");
|
||||
break;
|
||||
case 0x11:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Plus 4k SL2");
|
||||
break;
|
||||
case 0x18:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1");
|
||||
break;
|
||||
case 0x20:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41");
|
||||
isMifareClassic = false;
|
||||
break;
|
||||
case 0x24:
|
||||
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire | DESFire EV1");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : NXP MIFARE DESFire | DESFire EV1");
|
||||
isMifareClassic = false;
|
||||
break;
|
||||
case 0x28:
|
||||
PrintAndLogEx(NORMAL, "TYPE : JCOP31 or JCOP41 v2.3.1");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : JCOP31 or JCOP41 v2.3.1");
|
||||
break;
|
||||
case 0x38:
|
||||
PrintAndLogEx(NORMAL, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K");
|
||||
break;
|
||||
case 0x88:
|
||||
PrintAndLogEx(NORMAL, "TYPE : Infineon MIFARE CLASSIC 1K");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : Infineon MIFARE CLASSIC 1K");
|
||||
break;
|
||||
case 0x98:
|
||||
PrintAndLogEx(NORMAL, "TYPE : Gemplus MPCOS");
|
||||
PrintAndLogEx(SUCCESS, "TYPE : Gemplus MPCOS");
|
||||
break;
|
||||
default:
|
||||
;
|
||||
@@ -1363,7 +1364,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
|
||||
// Double & triple sized UID, can be mapped to a manufacturer.
|
||||
if (card.uidlen > 4) {
|
||||
PrintAndLogEx(NORMAL, "MANUFACTURER : %s", getTagInfo(card.uid[0]));
|
||||
PrintAndLogEx(SUCCESS, "MANUFACTURER : %s", getTagInfo(card.uid[0]));
|
||||
}
|
||||
|
||||
// try to request ATS even if tag claims not to support it
|
||||
@@ -1382,12 +1383,12 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
int pos;
|
||||
|
||||
if (select_status == 2) {
|
||||
PrintAndLogEx(NORMAL, "SAK incorrectly claims that card doesn't support RATS");
|
||||
PrintAndLogEx(INFO, "SAK incorrectly claims that card doesn't support RATS");
|
||||
}
|
||||
PrintAndLogEx(NORMAL, " ATS : %s", sprint_hex(card.ats, card.ats_len));
|
||||
PrintAndLogEx(NORMAL, " - TL : length is %d bytes", card.ats[0]);
|
||||
PrintAndLogEx(SUCCESS, " ATS : %s", sprint_hex(card.ats, card.ats_len));
|
||||
PrintAndLogEx(SUCCESS, " - TL : length is %d bytes", card.ats[0]);
|
||||
if (card.ats[0] != card.ats_len - 2) {
|
||||
PrintAndLogEx(NORMAL, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len);
|
||||
PrintAndLogEx(SUCCESS, "ATS may be corrupted. Length of ATS (%d bytes incl. 2 Bytes CRC) doesn't match TL", card.ats_len);
|
||||
}
|
||||
|
||||
if (card.ats[0] > 1) { // there is a format byte (T0)
|
||||
@@ -1396,7 +1397,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
tc1 = (card.ats[1] & 0x40) == 0x40;
|
||||
int16_t fsci = card.ats[1] & 0x0f;
|
||||
|
||||
PrintAndLogEx(NORMAL, " - T0 : TA1 is%s present, TB1 is%s present, "
|
||||
PrintAndLogEx(SUCCESS, " - T0 : TA1 is%s present, TB1 is%s present, "
|
||||
"TC1 is%s present, FSCI is %d (FSC = %d)",
|
||||
(ta1 ? "" : " NOT"),
|
||||
(tb1 ? "" : " NOT"),
|
||||
@@ -1417,7 +1418,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
if (card.ats[pos] & 0x04) strcat(dr, "8, ");
|
||||
if (strlen(ds) != 0) ds[strlen(ds) - 2] = '\0';
|
||||
if (strlen(dr) != 0) dr[strlen(dr) - 2] = '\0';
|
||||
PrintAndLogEx(NORMAL, " - TA1 : different divisors are%s supported, "
|
||||
PrintAndLogEx(SUCCESS, " - TA1 : different divisors are%s supported, "
|
||||
"DR: [%s], DS: [%s]",
|
||||
((card.ats[pos] & 0x80) ? " NOT" : ""),
|
||||
dr,
|
||||
@@ -1429,7 +1430,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
if (tb1) {
|
||||
uint32_t sfgi = card.ats[pos] & 0x0F;
|
||||
uint32_t fwi = card.ats[pos] >> 4;
|
||||
PrintAndLogEx(NORMAL, " - TB1 : SFGI = %d (SFGT = %s%d/fc), FWI = %d (FWT = %d/fc)",
|
||||
PrintAndLogEx(SUCCESS, " - TB1 : SFGI = %d (SFGT = %s%d/fc), FWI = %d (FWT = %d/fc)",
|
||||
(sfgi),
|
||||
sfgi ? "" : "(not needed) ",
|
||||
sfgi ? (1 << 12) << sfgi : 0,
|
||||
@@ -1439,7 +1440,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
pos++;
|
||||
}
|
||||
if (tc1) {
|
||||
PrintAndLogEx(NORMAL, " - TC1 : NAD is%s supported, CID is%s supported",
|
||||
PrintAndLogEx(SUCCESS, " - TC1 : NAD is%s supported, CID is%s supported",
|
||||
(card.ats[pos] & 0x01) ? "" : " NOT",
|
||||
(card.ats[pos] & 0x02) ? "" : " NOT");
|
||||
pos++;
|
||||
@@ -1453,63 +1454,63 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
tip = "-> MIFARE Plus S 2K or 4K";
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, " - HB : %s%s", sprint_hex(card.ats + pos, card.ats[0] - pos), tip);
|
||||
PrintAndLogEx(SUCCESS, " - HB : %s%s", sprint_hex(card.ats + pos, card.ats[0] - pos), tip);
|
||||
if (card.ats[pos] == 0xC1) {
|
||||
PrintAndLogEx(NORMAL, " c1 -> Mifare or (multiple) virtual cards of various type");
|
||||
PrintAndLogEx(NORMAL, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]);
|
||||
PrintAndLogEx(SUCCESS, " c1 -> Mifare or (multiple) virtual cards of various type");
|
||||
PrintAndLogEx(SUCCESS, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]);
|
||||
switch (card.ats[pos + 2] & 0xf0) {
|
||||
case 0x10:
|
||||
PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire");
|
||||
PrintAndLogEx(SUCCESS, " 1x -> MIFARE DESFire");
|
||||
break;
|
||||
case 0x20:
|
||||
PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus");
|
||||
PrintAndLogEx(SUCCESS, " 2x -> MIFARE Plus");
|
||||
break;
|
||||
}
|
||||
switch (card.ats[pos + 2] & 0x0f) {
|
||||
case 0x00:
|
||||
PrintAndLogEx(NORMAL, " x0 -> <1 kByte");
|
||||
PrintAndLogEx(SUCCESS, " x0 -> <1 kByte");
|
||||
break;
|
||||
case 0x01:
|
||||
PrintAndLogEx(NORMAL, " x1 -> 1 kByte");
|
||||
PrintAndLogEx(SUCCESS, " x1 -> 1 kByte");
|
||||
break;
|
||||
case 0x02:
|
||||
PrintAndLogEx(NORMAL, " x2 -> 2 kByte");
|
||||
PrintAndLogEx(SUCCESS, " x2 -> 2 kByte");
|
||||
break;
|
||||
case 0x03:
|
||||
PrintAndLogEx(NORMAL, " x3 -> 4 kByte");
|
||||
PrintAndLogEx(SUCCESS, " x3 -> 4 kByte");
|
||||
break;
|
||||
case 0x04:
|
||||
PrintAndLogEx(NORMAL, " x4 -> 8 kByte");
|
||||
PrintAndLogEx(SUCCESS, " x4 -> 8 kByte");
|
||||
break;
|
||||
}
|
||||
switch (card.ats[pos + 3] & 0xf0) {
|
||||
case 0x00:
|
||||
PrintAndLogEx(NORMAL, " 0x -> Engineering sample");
|
||||
PrintAndLogEx(SUCCESS, " 0x -> Engineering sample");
|
||||
break;
|
||||
case 0x20:
|
||||
PrintAndLogEx(NORMAL, " 2x -> Released");
|
||||
PrintAndLogEx(SUCCESS, " 2x -> Released");
|
||||
break;
|
||||
}
|
||||
switch (card.ats[pos + 3] & 0x0f) {
|
||||
case 0x00:
|
||||
PrintAndLogEx(NORMAL, " x0 -> Generation 1");
|
||||
PrintAndLogEx(SUCCESS, " x0 -> Generation 1");
|
||||
break;
|
||||
case 0x01:
|
||||
PrintAndLogEx(NORMAL, " x1 -> Generation 2");
|
||||
PrintAndLogEx(SUCCESS, " x1 -> Generation 2");
|
||||
break;
|
||||
case 0x02:
|
||||
PrintAndLogEx(NORMAL, " x2 -> Generation 3");
|
||||
PrintAndLogEx(SUCCESS, " x2 -> Generation 3");
|
||||
break;
|
||||
}
|
||||
switch (card.ats[pos + 4] & 0x0f) {
|
||||
case 0x00:
|
||||
PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported");
|
||||
PrintAndLogEx(SUCCESS, " x0 -> Only VCSL supported");
|
||||
break;
|
||||
case 0x01:
|
||||
PrintAndLogEx(NORMAL, " x1 -> VCS, VCSL, and SVC supported");
|
||||
PrintAndLogEx(SUCCESS, " x1 -> VCS, VCSL, and SVC supported");
|
||||
break;
|
||||
case 0x0E:
|
||||
PrintAndLogEx(NORMAL, " xE -> no VCS command supported");
|
||||
PrintAndLogEx(SUCCESS, " xE -> no VCS command supported");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1552,9 +1553,9 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||
|
||||
if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) {
|
||||
if (sw == 0x9000) {
|
||||
if (verbose) PrintAndLogEx(NORMAL, "------------- Application OK -----------");
|
||||
if (verbose) PrintAndLogEx(SUCCESS, "------------- Application OK -----------");
|
||||
} else {
|
||||
if (verbose) PrintAndLogEx(NORMAL, "----------- Application blocked --------");
|
||||
if (verbose) PrintAndLogEx(WARNING, "----------- Application blocked --------");
|
||||
}
|
||||
|
||||
PrintAIDDescriptionBuf(root, vaid, vaidlen, verbose);
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||
// 2011, Merlok
|
||||
// 2015,216,2017 iceman, marshmellow, piwi
|
||||
// 2011,2019 Merlok
|
||||
// 2015,2016,2017 iceman, marshmellow, piwi
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
@@ -30,6 +30,6 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search);
|
||||
const char *getTagInfo(uint8_t uid);
|
||||
int Hf14443_4aGetCardData(iso14a_card_select_t *card);
|
||||
int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
|
||||
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
|
||||
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode);
|
||||
|
||||
#endif
|
||||
|
||||
+10
-8
@@ -528,9 +528,10 @@ static bool HF14B_Std_Info(bool verbose) {
|
||||
|
||||
switch (status) {
|
||||
case 0:
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(NORMAL, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
||||
PrintAndLogEx(NORMAL, " CHIPID : %02X", card.chipid);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
||||
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
|
||||
print_atqb_resp(card.atqb, card.cid);
|
||||
isSuccess = true;
|
||||
break;
|
||||
@@ -662,9 +663,10 @@ static bool HF14B_Std_Reader(bool verbose) {
|
||||
|
||||
switch (status) {
|
||||
case 0:
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(NORMAL, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
||||
PrintAndLogEx(NORMAL, " CHIPID : %02X", card.chipid);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
||||
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
|
||||
print_atqb_resp(card.atqb, card.cid);
|
||||
isSuccess = true;
|
||||
break;
|
||||
@@ -808,13 +810,13 @@ static int CmdHF14BWriteSri(const char *Cmd) {
|
||||
}
|
||||
|
||||
if (blockno == 0xff) {
|
||||
PrintAndLogEx(SUCCESS, "[%s] Write special block %02X [ %s ]",
|
||||
PrintAndLogEx(SUCCESS, "[%s] Write special block %02X [ " _YELLOW_("%s")" ]",
|
||||
(isSrix4k) ? "SRIX4K" : "SRI512",
|
||||
blockno,
|
||||
sprint_hex(data, 4)
|
||||
);
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, "[%s] Write block %02X [ %s ]",
|
||||
PrintAndLogEx(SUCCESS, "[%s] Write block %02X [ " _YELLOW_("%s")" ]",
|
||||
(isSrix4k) ? "SRIX4K" : "SRI512",
|
||||
blockno,
|
||||
sprint_hex(data, 4)
|
||||
|
||||
+476
-98
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -15,6 +15,6 @@
|
||||
|
||||
int CmdHF15(const char *Cmd);
|
||||
|
||||
int readHF15Uid(bool verbose);
|
||||
bool readHF15Uid(bool verbose);
|
||||
|
||||
#endif
|
||||
|
||||
+26
-26
@@ -16,7 +16,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "comms.h" // clearCommandBuffer
|
||||
#include "ui.h"
|
||||
#include "util_posix.h"
|
||||
@@ -38,8 +38,8 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) {
|
||||
m = m > 0 ? m : 1;
|
||||
n = n > 0 ? n : 1;
|
||||
|
||||
PrintAndLogEx(NORMAL, "Collecting %u %u byte nonces", n, m);
|
||||
PrintAndLogEx(NORMAL, "Start: %" PRIu64, msclock() / 1000);
|
||||
PrintAndLogEx(SUCCESS, "Collecting %u %u byte nonces", n, m);
|
||||
PrintAndLogEx(SUCCESS, "Start: %" PRIu64, msclock() / 1000);
|
||||
// repeat n times
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
// execute PACE
|
||||
@@ -58,15 +58,15 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) {
|
||||
sprintf(nonce + (2 * j), "%02X", resp.data.asBytes[j]);
|
||||
}
|
||||
// print nonce
|
||||
PrintAndLogEx(NORMAL, "Length: %zu, Nonce: %s", nonce_length, nonce);
|
||||
PrintAndLogEx(SUCCESS, "Length: %zu, Nonce: %s", nonce_length, nonce);
|
||||
free(nonce);
|
||||
}
|
||||
if (i < n - 1) {
|
||||
sleep(d);
|
||||
}
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "End: %" PRIu64, msclock() / 1000);
|
||||
return 1;
|
||||
PrintAndLogEx(SUCCESS, "End: %" PRIu64, msclock() / 1000);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// perform the PACE protocol by replaying APDUs
|
||||
@@ -98,9 +98,9 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
|
||||
);
|
||||
|
||||
if (scan_return < 1) {
|
||||
PrintAndLogEx(NORMAL, (char *)usage_msg);
|
||||
PrintAndLogEx(INFO, (char *)usage_msg);
|
||||
PrintAndLogEx(WARNING, "Not enough APDUs! Try again!");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
skip += skip_add;
|
||||
apdu_lengths[i]++;
|
||||
@@ -110,8 +110,8 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
|
||||
if (Cmd[skip] == '\0') {
|
||||
if (i < ARRAYLEN(apdu_lengths) - 1) {
|
||||
|
||||
PrintAndLogEx(NORMAL, (char *)usage_msg);
|
||||
return 0;
|
||||
PrintAndLogEx(INFO, (char *)usage_msg);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -146,7 +146,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
|
||||
WaitForResponse(CMD_ACK, &resp);
|
||||
if (resp.oldarg[0] != 0) {
|
||||
PrintAndLogEx(WARNING, "Transfer of APDU #%d Part %d failed!", i, j);
|
||||
return 0;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,22 +156,22 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
|
||||
SendCommandMIX(CMD_HF_EPA_REPLAY, 0, 0, 0, NULL, 0);
|
||||
WaitForResponse(CMD_ACK, &resp);
|
||||
if (resp.oldarg[0] != 0) {
|
||||
PrintAndLogEx(NORMAL, "\nPACE replay failed in step %u!", (uint32_t)resp.oldarg[0]);
|
||||
PrintAndLogEx(NORMAL, "Measured times:");
|
||||
PrintAndLogEx(NORMAL, "MSE Set AT: %u us", resp.data.asDwords[0]);
|
||||
PrintAndLogEx(NORMAL, "GA Get Nonce: %u us", resp.data.asDwords[1]);
|
||||
PrintAndLogEx(NORMAL, "GA Map Nonce: %u us", resp.data.asDwords[2]);
|
||||
PrintAndLogEx(NORMAL, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]);
|
||||
PrintAndLogEx(NORMAL, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]);
|
||||
PrintAndLogEx(SUCCESS, "\nPACE replay failed in step %u!", (uint32_t)resp.oldarg[0]);
|
||||
PrintAndLogEx(SUCCESS, "Measured times:");
|
||||
PrintAndLogEx(SUCCESS, "MSE Set AT: %u us", resp.data.asDwords[0]);
|
||||
PrintAndLogEx(SUCCESS, "GA Get Nonce: %u us", resp.data.asDwords[1]);
|
||||
PrintAndLogEx(SUCCESS, "GA Map Nonce: %u us", resp.data.asDwords[2]);
|
||||
PrintAndLogEx(SUCCESS, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]);
|
||||
PrintAndLogEx(SUCCESS, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]);
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "PACE replay successful!");
|
||||
PrintAndLogEx(NORMAL, "MSE Set AT: %u us", resp.data.asDwords[0]);
|
||||
PrintAndLogEx(NORMAL, "GA Get Nonce: %u us", resp.data.asDwords[1]);
|
||||
PrintAndLogEx(NORMAL, "GA Map Nonce: %u us", resp.data.asDwords[2]);
|
||||
PrintAndLogEx(NORMAL, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]);
|
||||
PrintAndLogEx(NORMAL, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]);
|
||||
PrintAndLogEx(SUCCESS, "PACE replay successful!");
|
||||
PrintAndLogEx(SUCCESS, "MSE Set AT: %u us", resp.data.asDwords[0]);
|
||||
PrintAndLogEx(SUCCESS, "GA Get Nonce: %u us", resp.data.asDwords[1]);
|
||||
PrintAndLogEx(SUCCESS, "GA Map Nonce: %u us", resp.data.asDwords[2]);
|
||||
PrintAndLogEx(SUCCESS, "GA Perform Key Agreement: %u us", resp.data.asDwords[3]);
|
||||
PrintAndLogEx(SUCCESS, "GA Mutual Authenticate: %u us", resp.data.asDwords[4]);
|
||||
}
|
||||
return 1;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
@@ -184,7 +184,7 @@ static command_t CommandTable[] = {
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int CmdHFEPA(const char *Cmd) {
|
||||
|
||||
+63
-74
@@ -320,12 +320,12 @@ static bool waitCmdFelica(uint8_t iSelect, PacketResponseNG *resp, bool verbose)
|
||||
if (WaitForResponseTimeout(CMD_ACK, resp, 2000)) {
|
||||
uint16_t len = iSelect ? (resp->oldarg[1] & 0xffff) : (resp->oldarg[0] & 0xffff);
|
||||
if (verbose) {
|
||||
PrintAndLogEx(NORMAL, "Client Received %i octets", len);
|
||||
PrintAndLogEx(SUCCESS, "Client Received %i octets", len);
|
||||
if (!len || len < 2) {
|
||||
PrintAndLogEx(ERR, "Could not receive data correctly!");
|
||||
return false;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "%s", sprint_hex(resp->data.asBytes, len));
|
||||
PrintAndLogEx(SUCCESS, "%s", sprint_hex(resp->data.asBytes, len));
|
||||
if (!check_crc(CRC_FELICA, resp->data.asBytes + 2, len - 2)) {
|
||||
PrintAndLogEx(WARNING, "Wrong or no CRC bytes");
|
||||
}
|
||||
@@ -400,7 +400,7 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat
|
||||
uint16_t numbits = 0;
|
||||
clearCommandBuffer();
|
||||
if (verbose) {
|
||||
PrintAndLogEx(NORMAL, "Send RAW COMMAND - Frame: %s", sprint_hex(data, datalen));
|
||||
PrintAndLogEx(INFO, "Send raw command - Frame: %s", sprint_hex(data, datalen));
|
||||
}
|
||||
SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen);
|
||||
}
|
||||
@@ -438,11 +438,11 @@ static void print_rd_noEncrpytion_response(felica_read_without_encryption_respon
|
||||
char bl_element_number[4];
|
||||
temp = sprint_hex(rd_noCry_resp->block_element_number, sizeof(rd_noCry_resp->block_element_number));
|
||||
strcpy(bl_element_number, temp);
|
||||
PrintAndLogEx(NORMAL, "\t%s\t| %s ", bl_element_number, bl_data);
|
||||
PrintAndLogEx(INFO, "\t%s\t| %s ", bl_element_number, bl_data);
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rd_noCry_resp->frame_response.IDm, sizeof(rd_noCry_resp->frame_response.IDm)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1)));
|
||||
PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rd_noCry_resp->frame_response.IDm, sizeof(rd_noCry_resp->frame_response.IDm)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag2: %s", sprint_hex(rd_noCry_resp->status_flags.status_flag1, sizeof(rd_noCry_resp->status_flags.status_flag1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +454,7 @@ int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool ve
|
||||
PacketResponseNG resp;
|
||||
if (datalen > 0) {
|
||||
if (!waitCmdFelica(0, &resp, 1)) {
|
||||
PrintAndLogEx(ERR, "\nGot no Response from card");
|
||||
PrintAndLogEx(ERR, "\nGot no response from card");
|
||||
return PM3_ERFTRANS;
|
||||
}
|
||||
felica_request_service_response_t rqs_response;
|
||||
@@ -462,9 +462,9 @@ int send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data, bool ve
|
||||
|
||||
if (rqs_response.frame_response.IDm[0] != 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nGot Service Response:");
|
||||
PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.frame_response.IDm, sizeof(rqs_response.frame_response.IDm)));
|
||||
PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number)));
|
||||
PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions)));
|
||||
PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rqs_response.frame_response.IDm, sizeof(rqs_response.frame_response.IDm)));
|
||||
PrintAndLogEx(SUCCESS, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number)));
|
||||
PrintAndLogEx(SUCCESS, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions)));
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
@@ -484,7 +484,7 @@ int send_rd_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver
|
||||
clear_and_send_command(flags, datalen, data, verbose);
|
||||
PacketResponseNG resp;
|
||||
if (!waitCmdFelica(0, &resp, verbose)) {
|
||||
PrintAndLogEx(ERR, "\nGot no Response from card");
|
||||
PrintAndLogEx(ERR, "\nGot no response from card");
|
||||
return PM3_ERFTRANS;
|
||||
} else {
|
||||
memcpy(rd_noCry_resp, (felica_read_without_encryption_response_t *)resp.data.asBytes, sizeof(felica_read_without_encryption_response_t));
|
||||
@@ -522,7 +522,7 @@ int send_wr_unencrypted(uint8_t flags, uint16_t datalen, uint8_t *data, bool ver
|
||||
clear_and_send_command(flags, datalen, data, verbose);
|
||||
PacketResponseNG resp;
|
||||
if (!waitCmdFelica(0, &resp, verbose)) {
|
||||
PrintAndLogEx(ERR, "\nGot no Response from card");
|
||||
PrintAndLogEx(ERR, "\nGot no response from card");
|
||||
return PM3_ERFTRANS;
|
||||
} else {
|
||||
memcpy(wr_noCry_resp, (felica_status_response_t *)resp.data.asBytes, sizeof(felica_status_response_t));
|
||||
@@ -548,8 +548,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_authentication1();
|
||||
case 'i':
|
||||
@@ -656,8 +655,7 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_write_without_encryption();
|
||||
case 'i':
|
||||
@@ -696,9 +694,9 @@ static int CmdHFFelicaWriteWithoutEncryption(const char *Cmd) {
|
||||
datalen += 2;
|
||||
felica_status_response_t wr_noCry_resp;
|
||||
if (send_wr_unencrypted(flags, datalen, data, 1, &wr_noCry_resp) == PM3_SUCCESS) {
|
||||
PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(wr_noCry_resp.frame_response.IDm, sizeof(wr_noCry_resp.frame_response.IDm)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(wr_noCry_resp.status_flags.status_flag1, sizeof(wr_noCry_resp.status_flags.status_flag1)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag2: %s\n", sprint_hex(wr_noCry_resp.status_flags.status_flag2, sizeof(wr_noCry_resp.status_flags.status_flag2)));
|
||||
PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(wr_noCry_resp.frame_response.IDm, sizeof(wr_noCry_resp.frame_response.IDm)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(wr_noCry_resp.status_flags.status_flag1, sizeof(wr_noCry_resp.status_flags.status_flag1)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag2: %s\n", sprint_hex(wr_noCry_resp.status_flags.status_flag2, sizeof(wr_noCry_resp.status_flags.status_flag2)));
|
||||
if (wr_noCry_resp.status_flags.status_flag1[0] == 0x00 && wr_noCry_resp.status_flags.status_flag2[0] == 0x00) {
|
||||
PrintAndLogEx(SUCCESS, "Writing data successful!\n");
|
||||
} else {
|
||||
@@ -727,8 +725,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_read_without_encryption();
|
||||
case 'i':
|
||||
@@ -781,7 +778,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) {
|
||||
if (long_block_numbers) {
|
||||
last_block_number = 0xFFFF;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "Block Element\t| Data ");
|
||||
PrintAndLogEx(INFO, "Block Element\t| Data ");
|
||||
for (int i = 0x00; i < last_block_number; i++) {
|
||||
data[15] = i;
|
||||
AddCrc(data, datalen);
|
||||
@@ -803,7 +800,7 @@ static int CmdHFFelicaReadWithoutEncryption(const char *Cmd) {
|
||||
datalen += 2;
|
||||
felica_read_without_encryption_response_t rd_noCry_resp;
|
||||
if (send_rd_unencrypted(flags, datalen, data, 1, &rd_noCry_resp) == PM3_SUCCESS) {
|
||||
PrintAndLogEx(NORMAL, "Block Element\t| Data ");
|
||||
PrintAndLogEx(INFO, "Block Element\t| Data ");
|
||||
print_rd_noEncrpytion_response(&rd_noCry_resp);
|
||||
}
|
||||
}
|
||||
@@ -825,8 +822,7 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_request_response();
|
||||
case 'i':
|
||||
@@ -856,15 +852,15 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) {
|
||||
clear_and_send_command(flags, datalen, data, 0);
|
||||
PacketResponseNG resp;
|
||||
if (!waitCmdFelica(0, &resp, 1)) {
|
||||
PrintAndLogEx(ERR, "\nGot no Response from card");
|
||||
PrintAndLogEx(ERR, "\nGot no response from card");
|
||||
return PM3_ERFTRANS;
|
||||
} else {
|
||||
felica_request_request_response_t rq_response;
|
||||
memcpy(&rq_response, (felica_request_request_response_t *)resp.data.asBytes, sizeof(felica_request_request_response_t));
|
||||
if (rq_response.frame_response.IDm[0] != 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nGot Request Response:");
|
||||
PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_response.frame_response.IDm, sizeof(rq_response.frame_response.IDm)));
|
||||
PrintAndLogEx(NORMAL, " -Mode: %s\n\n", sprint_hex(rq_response.mode, sizeof(rq_response.mode)));
|
||||
PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rq_response.frame_response.IDm, sizeof(rq_response.frame_response.IDm)));
|
||||
PrintAndLogEx(SUCCESS, " -Mode: %s\n\n", sprint_hex(rq_response.mode, sizeof(rq_response.mode)));
|
||||
}
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
@@ -887,8 +883,7 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_request_specification_version();
|
||||
case 'i':
|
||||
@@ -931,24 +926,24 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) {
|
||||
clear_and_send_command(flags, datalen, data, 0);
|
||||
PacketResponseNG resp;
|
||||
if (!waitCmdFelica(0, &resp, 1)) {
|
||||
PrintAndLogEx(ERR, "\nGot no Response from card");
|
||||
PrintAndLogEx(ERR, "\nGot no response from card");
|
||||
return PM3_ERFTRANS;
|
||||
} else {
|
||||
felica_request_spec_response_t spec_response;
|
||||
memcpy(&spec_response, (felica_request_spec_response_t *)resp.data.asBytes, sizeof(felica_request_spec_response_t));
|
||||
if (spec_response.frame_response.IDm[0] != 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nGot Request Response:");
|
||||
PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(spec_response.status_flags.status_flag1, sizeof(spec_response.status_flags.status_flag1)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag2: %s", sprint_hex(spec_response.status_flags.status_flag2, sizeof(spec_response.status_flags.status_flag2)));
|
||||
PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(spec_response.status_flags.status_flag1, sizeof(spec_response.status_flags.status_flag1)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag2: %s", sprint_hex(spec_response.status_flags.status_flag2, sizeof(spec_response.status_flags.status_flag2)));
|
||||
if (spec_response.status_flags.status_flag1[0] == 0x00) {
|
||||
PrintAndLogEx(NORMAL, "Format Version: %s", sprint_hex(spec_response.format_version, sizeof(spec_response.format_version)));
|
||||
PrintAndLogEx(NORMAL, "Basic Version: %s", sprint_hex(spec_response.basic_version, sizeof(spec_response.basic_version)));
|
||||
PrintAndLogEx(NORMAL, "Number of Option: %s", sprint_hex(spec_response.number_of_option, sizeof(spec_response.number_of_option)));
|
||||
PrintAndLogEx(SUCCESS, "Format Version: %s", sprint_hex(spec_response.format_version, sizeof(spec_response.format_version)));
|
||||
PrintAndLogEx(SUCCESS, "Basic Version: %s", sprint_hex(spec_response.basic_version, sizeof(spec_response.basic_version)));
|
||||
PrintAndLogEx(SUCCESS, "Number of Option: %s", sprint_hex(spec_response.number_of_option, sizeof(spec_response.number_of_option)));
|
||||
if (spec_response.number_of_option[0] == 0x01) {
|
||||
PrintAndLogEx(NORMAL, "Option Version List:");
|
||||
PrintAndLogEx(SUCCESS, "Option Version List:");
|
||||
for (uint8_t i = 0; i < spec_response.number_of_option[0]; i++) {
|
||||
PrintAndLogEx(NORMAL, " - %s", sprint_hex(spec_response.option_version_list + i * 2, sizeof(uint8_t) * 2));
|
||||
PrintAndLogEx(SUCCESS, " - %s", sprint_hex(spec_response.option_version_list + i * 2, sizeof(uint8_t) * 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -974,8 +969,7 @@ static int CmdHFFelicaResetMode(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_reset_mode();
|
||||
case 'i':
|
||||
@@ -1018,16 +1012,16 @@ static int CmdHFFelicaResetMode(const char *Cmd) {
|
||||
clear_and_send_command(flags, datalen, data, 0);
|
||||
PacketResponseNG resp;
|
||||
if (!waitCmdFelica(0, &resp, 1)) {
|
||||
PrintAndLogEx(ERR, "\nGot no Response from card");
|
||||
PrintAndLogEx(ERR, "\nGot no response from card");
|
||||
return PM3_ERFTRANS;
|
||||
} else {
|
||||
felica_status_response_t reset_mode_response;
|
||||
memcpy(&reset_mode_response, (felica_status_response_t *)resp.data.asBytes, sizeof(felica_status_response_t));
|
||||
if (reset_mode_response.frame_response.IDm[0] != 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nGot Request Response:");
|
||||
PrintAndLogEx(NORMAL, "\nIDm: %s", sprint_hex(reset_mode_response.frame_response.IDm, sizeof(reset_mode_response.frame_response.IDm)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag1: %s", sprint_hex(reset_mode_response.status_flags.status_flag1, sizeof(reset_mode_response.status_flags.status_flag1)));
|
||||
PrintAndLogEx(NORMAL, "Status Flag2: %s\n", sprint_hex(reset_mode_response.status_flags.status_flag2, sizeof(reset_mode_response.status_flags.status_flag2)));
|
||||
PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(reset_mode_response.frame_response.IDm, sizeof(reset_mode_response.frame_response.IDm)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag1: %s", sprint_hex(reset_mode_response.status_flags.status_flag1, sizeof(reset_mode_response.status_flags.status_flag1)));
|
||||
PrintAndLogEx(SUCCESS, "Status Flag2: %s\n", sprint_hex(reset_mode_response.status_flags.status_flag2, sizeof(reset_mode_response.status_flags.status_flag2)));
|
||||
}
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
@@ -1048,8 +1042,7 @@ static int CmdHFFelicaRequestSystemCode(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_request_system_code();
|
||||
case 'i':
|
||||
@@ -1079,18 +1072,18 @@ static int CmdHFFelicaRequestSystemCode(const char *Cmd) {
|
||||
clear_and_send_command(flags, datalen, data, 0);
|
||||
PacketResponseNG resp;
|
||||
if (!waitCmdFelica(0, &resp, 1)) {
|
||||
PrintAndLogEx(ERR, "\nGot no Response from card");
|
||||
PrintAndLogEx(ERR, "\nGot no response from card");
|
||||
return PM3_ERFTRANS;
|
||||
} else {
|
||||
felica_syscode_response_t rq_syscode_response;
|
||||
memcpy(&rq_syscode_response, (felica_syscode_response_t *)resp.data.asBytes, sizeof(felica_syscode_response_t));
|
||||
if (rq_syscode_response.frame_response.IDm[0] != 0) {
|
||||
PrintAndLogEx(SUCCESS, "\nGot Request Response:");
|
||||
PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rq_syscode_response.frame_response.IDm, sizeof(rq_syscode_response.frame_response.IDm)));
|
||||
PrintAndLogEx(NORMAL, " - Number of Systems: %s", sprint_hex(rq_syscode_response.number_of_systems, sizeof(rq_syscode_response.number_of_systems)));
|
||||
PrintAndLogEx(NORMAL, " - System Codes: enumerated in ascending order starting from System 0.");
|
||||
PrintAndLogEx(SUCCESS, "IDm: %s", sprint_hex(rq_syscode_response.frame_response.IDm, sizeof(rq_syscode_response.frame_response.IDm)));
|
||||
PrintAndLogEx(SUCCESS, " - Number of Systems: %s", sprint_hex(rq_syscode_response.number_of_systems, sizeof(rq_syscode_response.number_of_systems)));
|
||||
PrintAndLogEx(SUCCESS, " - System Codes: enumerated in ascending order starting from System 0.");
|
||||
for (uint8_t i = 0; i < rq_syscode_response.number_of_systems[0]; i++) {
|
||||
PrintAndLogEx(NORMAL, " - %s", sprint_hex(rq_syscode_response.system_code_list + i * 2, sizeof(uint8_t) * 2));
|
||||
PrintAndLogEx(SUCCESS, " - %s", sprint_hex(rq_syscode_response.system_code_list + i * 2, sizeof(uint8_t) * 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1114,8 +1107,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
|
||||
strip_cmds(Cmd);
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_request_service();
|
||||
case 'i':
|
||||
@@ -1151,7 +1143,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
|
||||
if (param_getlength(Cmd, paramCount) == 4) {
|
||||
param_gethex(Cmd, paramCount++, data + 11, 4);
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Incorrect Parameter length!");
|
||||
PrintAndLogEx(ERR, "Incorrect parameter length!");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
@@ -1186,7 +1178,8 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
|
||||
}
|
||||
|
||||
static int CmdHFFelicaNotImplementedYet(const char *Cmd) {
|
||||
PrintAndLogEx(NORMAL, "Feature not implemented Yet!");
|
||||
PrintAndLogEx(INFO, "Feature not implemented yet.");
|
||||
PrintAndLogEx(INFO, "Feel free to contribute!");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1198,12 +1191,10 @@ static int CmdHFFelicaSniff(const char *Cmd) {
|
||||
int i = 0;
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'h':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'H':
|
||||
return usage_hf_felica_sniff();
|
||||
case 's':
|
||||
case 'S':
|
||||
paramCount++;
|
||||
if (param_getlength(Cmd, paramCount) < 5) {
|
||||
samples2skip = param_get32ex(Cmd, paramCount++, 0, 10);
|
||||
@@ -1213,7 +1204,6 @@ static int CmdHFFelicaSniff(const char *Cmd) {
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
case 'T':
|
||||
paramCount++;
|
||||
if (param_getlength(Cmd, paramCount) < 5) {
|
||||
triggers2skip = param_get32ex(Cmd, paramCount++, 0, 10);
|
||||
@@ -1259,7 +1249,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) {
|
||||
}
|
||||
|
||||
static void printSep() {
|
||||
PrintAndLogEx(NORMAL, "------------------------------------------------------------------------------------");
|
||||
PrintAndLogEx(INFO, "------------------------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
static uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) {
|
||||
@@ -1495,8 +1485,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
|
||||
while (Cmd[i] != '\0') {
|
||||
if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; }
|
||||
if (Cmd[i] == '-') {
|
||||
switch (Cmd[i + 1]) {
|
||||
case 'H':
|
||||
switch (tolower(Cmd[i + 1])) {
|
||||
case 'h':
|
||||
return usage_hf_felica_raw();
|
||||
case 'r':
|
||||
@@ -1540,7 +1529,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
|
||||
*buf = 0;
|
||||
if (++datalen >= sizeof(data)) {
|
||||
if (crc)
|
||||
PrintAndLogEx(NORMAL, "Buffer is full, we can't add CRC to your data");
|
||||
PrintAndLogEx(WARNING, "Buffer is full, we can't add CRC to your data");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1574,12 +1563,12 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
|
||||
datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen;
|
||||
|
||||
clearCommandBuffer();
|
||||
PrintAndLogEx(NORMAL, "Data: %s", sprint_hex(data, datalen));
|
||||
PrintAndLogEx(SUCCESS, "Data: %s", sprint_hex(data, datalen));
|
||||
SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen);
|
||||
|
||||
if (reply) {
|
||||
if (active_select) {
|
||||
PrintAndLogEx(NORMAL, "Active select wait for FeliCa.");
|
||||
PrintAndLogEx(SUCCESS, "Active select wait for FeliCa.");
|
||||
PacketResponseNG resp_IDm;
|
||||
waitCmdFelica(1, &resp_IDm, 1);
|
||||
}
|
||||
@@ -1625,15 +1614,15 @@ int readFelicaUid(bool verbose) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, "FeliCa tag info");
|
||||
|
||||
PrintAndLogEx(NORMAL, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
|
||||
PrintAndLogEx(NORMAL, " - CODE %s", sprint_hex(card.code, sizeof(card.code)));
|
||||
PrintAndLogEx(NORMAL, " - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid)));
|
||||
PrintAndLogEx(SUCCESS, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
|
||||
PrintAndLogEx(SUCCESS, " - CODE %s", sprint_hex(card.code, sizeof(card.code)));
|
||||
PrintAndLogEx(SUCCESS, " - NFCID2 %s", sprint_hex(card.uid, sizeof(card.uid)));
|
||||
|
||||
PrintAndLogEx(NORMAL, "Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm)));
|
||||
PrintAndLogEx(NORMAL, " - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode)));
|
||||
PrintAndLogEx(NORMAL, " - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt)));
|
||||
PrintAndLogEx(SUCCESS, "Parameter (PAD) | %s", sprint_hex(card.PMm, sizeof(card.PMm)));
|
||||
PrintAndLogEx(SUCCESS, " - IC CODE %s", sprint_hex(card.iccode, sizeof(card.iccode)));
|
||||
PrintAndLogEx(SUCCESS, " - MRT %s", sprint_hex(card.mrt, sizeof(card.mrt)));
|
||||
|
||||
PrintAndLogEx(NORMAL, "SERVICE CODE %s", sprint_hex(card.servicecode, sizeof(card.servicecode)));
|
||||
PrintAndLogEx(SUCCESS, "SERVICE CODE %s", sprint_hex(card.servicecode, sizeof(card.servicecode)));
|
||||
set_last_known_card(card);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -334,15 +334,15 @@ static void fuse_config(const picopass_hdr *hdr) {
|
||||
if (isset(fuses, FUSE_FPERS))
|
||||
PrintAndLogEx(SUCCESS, " Mode: Personalization [Programmable]");
|
||||
else
|
||||
PrintAndLogEx(NORMAL, " Mode: Application [Locked]");
|
||||
PrintAndLogEx(SUCCESS, " Mode: Application [Locked]");
|
||||
|
||||
if (isset(fuses, FUSE_CODING1)) {
|
||||
PrintAndLogEx(NORMAL, " Coding: RFU");
|
||||
PrintAndLogEx(SUCCESS, " Coding: RFU");
|
||||
} else {
|
||||
if (isset(fuses, FUSE_CODING0))
|
||||
PrintAndLogEx(NORMAL, " Coding: ISO 14443-2 B/ISO 15693");
|
||||
PrintAndLogEx(SUCCESS, " Coding: ISO 14443-2 B/ISO 15693");
|
||||
else
|
||||
PrintAndLogEx(NORMAL, " Coding: ISO 14443B only");
|
||||
PrintAndLogEx(SUCCESS, " Coding: ISO 14443B only");
|
||||
}
|
||||
// 1 1
|
||||
if (isset(fuses, FUSE_CRYPT1) && isset(fuses, FUSE_CRYPT0)) PrintAndLogEx(SUCCESS, " Crypt: Secured page, keys not locked");
|
||||
@@ -354,7 +354,7 @@ static void fuse_config(const picopass_hdr *hdr) {
|
||||
if (notset(fuses, FUSE_CRYPT1) && notset(fuses, FUSE_CRYPT0)) PrintAndLogEx(NORMAL, " Crypt: No auth possible. Read only if RA is enabled");
|
||||
|
||||
if (isset(fuses, FUSE_RA))
|
||||
PrintAndLogEx(NORMAL, " RA: Read access enabled");
|
||||
PrintAndLogEx(SUCCESS, " RA: Read access enabled");
|
||||
else
|
||||
PrintAndLogEx(WARNING, " RA: Read access not enabled");
|
||||
}
|
||||
@@ -2827,12 +2827,13 @@ int readIclass(bool loop, bool verbose) {
|
||||
}
|
||||
|
||||
if (readStatus & FLAG_ICLASS_READER_CSN) {
|
||||
PrintAndLogEx(NORMAL, " CSN: %s", sprint_hex(data, 8));
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
PrintAndLogEx(SUCCESS, " CSN: %s", sprint_hex(data, 8));
|
||||
tagFound = true;
|
||||
}
|
||||
|
||||
if (readStatus & FLAG_ICLASS_READER_CC) {
|
||||
PrintAndLogEx(NORMAL, " CC: %s", sprint_hex(data + 16, 8));
|
||||
PrintAndLogEx(SUCCESS, " CC: %s", sprint_hex(data + 16, 8));
|
||||
}
|
||||
|
||||
if (readStatus & FLAG_ICLASS_READER_CONF) {
|
||||
@@ -2847,7 +2848,7 @@ int readIclass(bool loop, bool verbose) {
|
||||
|
||||
bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0);
|
||||
|
||||
PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8));
|
||||
PrintAndLogEx(SUCCESS, " App IA: %s", sprint_hex(data + 8 * 5, 8));
|
||||
|
||||
if (isHidRange) {
|
||||
if (legacy)
|
||||
|
||||
+23
-23
@@ -210,7 +210,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
crc = data[4];
|
||||
uint32_t calc_crc = CRC8Legic(data, 4);
|
||||
|
||||
PrintAndLogEx(NORMAL, _YELLOW_("CDF: System Area"));
|
||||
PrintAndLogEx(SUCCESS, _YELLOW_("CDF: System Area"));
|
||||
PrintAndLogEx(NORMAL, "------------------------------------------------------");
|
||||
PrintAndLogEx(NORMAL, "MCD: %02x, MSN: %02x %02x %02x, MCC: %02x %s",
|
||||
data[0],
|
||||
@@ -229,7 +229,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
// New unwritten media?
|
||||
if (dcf == 0xFFFF) {
|
||||
|
||||
PrintAndLogEx(NORMAL, "DCF: %d (%02x %02x), Token Type=NM (New Media)",
|
||||
PrintAndLogEx(SUCCESS, "DCF: %d (%02x %02x), Token Type=NM (New Media)",
|
||||
dcf,
|
||||
data[5],
|
||||
data[6]
|
||||
@@ -262,7 +262,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
stamp_len = 0xfc - data[6];
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "DCF: %d (%02x %02x), Token Type=" _YELLOW_("%s") " (OLE=%01u), OL=%02u, FL=%02u",
|
||||
PrintAndLogEx(SUCCESS, "DCF: %d (%02x %02x), Token Type=" _YELLOW_("%s") " (OLE=%01u), OL=%02u, FL=%02u",
|
||||
dcf,
|
||||
data[5],
|
||||
data[6],
|
||||
@@ -281,7 +281,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
strncpy(token_type, "IM", sizeof(token_type) - 1);
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "DCF: %d (%02x %02x), Token Type = %s (OLE = %01u)",
|
||||
PrintAndLogEx(SUCCESS, "DCF: %d (%02x %02x), Token Type = %s (OLE = %01u)",
|
||||
dcf,
|
||||
data[5],
|
||||
data[6],
|
||||
@@ -294,7 +294,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
if (dcf != 0xFFFF) {
|
||||
|
||||
if (bIsSegmented) {
|
||||
PrintAndLogEx(NORMAL, "WRP = %02u, WRC = %01u, RD = %01u, SSC = %02X",
|
||||
PrintAndLogEx(SUCCESS, "WRP = %02u, WRC = %01u, RD = %01u, SSC = %02X",
|
||||
data[7] & 0x0f,
|
||||
(data[7] & 0x70) >> 4,
|
||||
(data[7] & 0x80) >> 7,
|
||||
@@ -305,11 +305,11 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
// Header area is only available on IM-S cards, on master tokens this data is the master token data itself
|
||||
if (bIsSegmented || dcf > 60000) {
|
||||
if (dcf > 60000) {
|
||||
PrintAndLogEx(NORMAL, "Master token data");
|
||||
PrintAndLogEx(NORMAL, "%s", sprint_hex(data + 8, 14));
|
||||
PrintAndLogEx(SUCCESS, "Master token data");
|
||||
PrintAndLogEx(SUCCESS, "%s", sprint_hex(data + 8, 14));
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "Remaining Header Area");
|
||||
PrintAndLogEx(NORMAL, "%s", sprint_hex(data + 9, 13));
|
||||
PrintAndLogEx(SUCCESS, "Remaining Header Area");
|
||||
PrintAndLogEx(SUCCESS, "%s", sprint_hex(data + 9, 13));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -323,7 +323,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
if (dcf > 60000)
|
||||
goto out;
|
||||
|
||||
PrintAndLogEx(NORMAL, _YELLOW_("\nADF: User Area"));
|
||||
PrintAndLogEx(SUCCESS, _YELLOW_("\nADF: User Area"));
|
||||
PrintAndLogEx(NORMAL, "------------------------------------------------------");
|
||||
|
||||
if (bIsSegmented) {
|
||||
@@ -356,20 +356,20 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
segCalcCRC = CRC8Legic(segCrcBytes, 8);
|
||||
segCRC = data[i + 4] ^ crc;
|
||||
|
||||
PrintAndLogEx(NORMAL, "Segment | %02u ", segmentNum);
|
||||
PrintAndLogEx(NORMAL, "raw header | 0x%02X 0x%02X 0x%02X 0x%02X",
|
||||
PrintAndLogEx(SUCCESS, "Segment | %02u ", segmentNum);
|
||||
PrintAndLogEx(SUCCESS, "raw header | 0x%02X 0x%02X 0x%02X 0x%02X",
|
||||
data[i] ^ crc,
|
||||
data[i + 1] ^ crc,
|
||||
data[i + 2] ^ crc,
|
||||
data[i + 3] ^ crc
|
||||
);
|
||||
PrintAndLogEx(NORMAL, "Segment len | %u, Flag: 0x%X (valid:%01u, last:%01u)",
|
||||
PrintAndLogEx(SUCCESS, "Segment len | %u, Flag: 0x%X (valid:%01u, last:%01u)",
|
||||
segment_len,
|
||||
segment_flag,
|
||||
(segment_flag & 0x4) >> 2,
|
||||
(segment_flag & 0x8) >> 3
|
||||
);
|
||||
PrintAndLogEx(NORMAL, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)",
|
||||
PrintAndLogEx(SUCCESS, " | WRP: %02u, WRC: %02u, RD: %01u, CRC: 0x%02X (%s)",
|
||||
wrp,
|
||||
wrc,
|
||||
((data[i + 3] ^ crc) & 0x80) >> 7,
|
||||
@@ -380,7 +380,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
i += 5;
|
||||
|
||||
if (hasWRC) {
|
||||
PrintAndLogEx(NORMAL, "\nWRC protected area: (I %d | K %d| WRC %d)", i, k, wrc);
|
||||
PrintAndLogEx(SUCCESS, "\nWRC protected area: (I %d | K %d| WRC %d)", i, k, wrc);
|
||||
PrintAndLogEx(NORMAL, "\nrow | data");
|
||||
PrintAndLogEx(NORMAL, "-----+------------------------------------------------");
|
||||
|
||||
@@ -393,7 +393,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
}
|
||||
|
||||
if (hasWRP) {
|
||||
PrintAndLogEx(NORMAL, "Remaining write protected area: (I %d | K %d | WRC %d | WRP %d WRP_LEN %d)", i, k, wrc, wrp, wrp_len);
|
||||
PrintAndLogEx(SUCCESS, "Remaining write protected area: (I %d | K %d | WRC %d | WRP %d WRP_LEN %d)", i, k, wrc, wrp, wrp_len);
|
||||
PrintAndLogEx(NORMAL, "\nrow | data");
|
||||
PrintAndLogEx(NORMAL, "-----+------------------------------------------------");
|
||||
|
||||
@@ -406,7 +406,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
|
||||
// does this one work? (Answer: Only if KGH/BGH is used with BCD encoded card number! So maybe this will show just garbage...)
|
||||
if (wrp_len == 8) {
|
||||
PrintAndLogEx(NORMAL, "Card ID: " _YELLOW_("%2X%02X%02X"),
|
||||
PrintAndLogEx(SUCCESS, "Card ID: " _YELLOW_("%2X%02X%02X"),
|
||||
data[i - 4] ^ crc,
|
||||
data[i - 3] ^ crc,
|
||||
data[i - 2] ^ crc
|
||||
@@ -414,7 +414,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
}
|
||||
}
|
||||
if (remain_seg_payload_len > 0) {
|
||||
PrintAndLogEx(NORMAL, "Remaining segment payload: (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len);
|
||||
PrintAndLogEx(SUCCESS, "Remaining segment payload: (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len);
|
||||
PrintAndLogEx(NORMAL, "\nrow | data");
|
||||
PrintAndLogEx(NORMAL, "-----+------------------------------------------------");
|
||||
|
||||
@@ -444,14 +444,14 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
int wrp_len = (wrp - wrc);
|
||||
int remain_seg_payload_len = (card.cardsize - 22 - wrp);
|
||||
|
||||
PrintAndLogEx(NORMAL, "Unsegmented card - WRP: %02u, WRC: %02u, RD: %01u",
|
||||
PrintAndLogEx(SUCCESS, "Unsegmented card - WRP: %02u, WRC: %02u, RD: %01u",
|
||||
wrp,
|
||||
wrc,
|
||||
(data[7] & 0x80) >> 7
|
||||
);
|
||||
|
||||
if (hasWRC) {
|
||||
PrintAndLogEx(NORMAL, "WRC protected area: (I %d | WRC %d)", i, wrc);
|
||||
PrintAndLogEx(SUCCESS, "WRC protected area: (I %d | WRC %d)", i, wrc);
|
||||
PrintAndLogEx(NORMAL, "\nrow | data");
|
||||
PrintAndLogEx(NORMAL, "-----+------------------------------------------------");
|
||||
print_hex_break(data + i, wrc, 16);
|
||||
@@ -460,7 +460,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
}
|
||||
|
||||
if (hasWRP) {
|
||||
PrintAndLogEx(NORMAL, "Remaining write protected area: (I %d | WRC %d | WRP %d | WRP_LEN %d)", i, wrc, wrp, wrp_len);
|
||||
PrintAndLogEx(SUCCESS, "Remaining write protected area: (I %d | WRC %d | WRP %d | WRP_LEN %d)", i, wrc, wrp, wrp_len);
|
||||
PrintAndLogEx(NORMAL, "\nrow | data");
|
||||
PrintAndLogEx(NORMAL, "-----+------------------------------------------------");
|
||||
print_hex_break(data + i, wrp_len, 16);
|
||||
@@ -470,7 +470,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
// Q: does this one work?
|
||||
// A: Only if KGH/BGH is used with BCD encoded card number. Maybe this will show just garbage
|
||||
if (wrp_len == 8) {
|
||||
PrintAndLogEx(NORMAL, "Card ID: " _YELLOW_("%2X%02X%02X"),
|
||||
PrintAndLogEx(SUCCESS, "Card ID: " _YELLOW_("%2X%02X%02X"),
|
||||
data[i - 4],
|
||||
data[i - 3],
|
||||
data[i - 2]
|
||||
@@ -479,7 +479,7 @@ static int CmdLegicInfo(const char *Cmd) {
|
||||
}
|
||||
|
||||
if (remain_seg_payload_len > 0) {
|
||||
PrintAndLogEx(NORMAL, "Remaining segment payload: (I %d | Remain LEN %d)", i, remain_seg_payload_len);
|
||||
PrintAndLogEx(SUCCESS, "Remaining segment payload: (I %d | Remain LEN %d)", i, remain_seg_payload_len);
|
||||
PrintAndLogEx(NORMAL, "\nrow | data");
|
||||
PrintAndLogEx(NORMAL, "-----+------------------------------------------------");
|
||||
print_hex_break(data + i, remain_seg_payload_len, 16);
|
||||
|
||||
+53
-2
@@ -13,7 +13,7 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "comms.h" // clearCommandBuffer
|
||||
#include "fileutils.h"
|
||||
#include "cmdtrace.h"
|
||||
@@ -3665,6 +3665,56 @@ static int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF14AMfCWipe(const char *cmd) {
|
||||
uint8_t uid[8] = {0x00};
|
||||
int uidLen = 0;
|
||||
uint8_t atqa[2] = {0x00};
|
||||
int atqaLen = 0;
|
||||
uint8_t sak[1] = {0x00};
|
||||
int sakLen = 0;
|
||||
|
||||
CLIParserInit("hf mf cwipe",
|
||||
"Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.",
|
||||
"Usage:\n\thf mf cwipe -> wipe card.\n"
|
||||
"\thf mfp mf cwipe -u 09080706 -a 0004 -s 18 -> set UID, ATQA and SAK and wipe card.");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str0("uU", "uid", "<HEX UID (4b)>", "UID for card"),
|
||||
arg_str0("aA", "atqa", "<HEX ATQA (2b)>", "ATQA for card"),
|
||||
arg_str0("sS", "sak", "<HEX SAK (1b)>", "SAK for card"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
|
||||
CLIGetHexWithReturn(1, uid, &uidLen);
|
||||
CLIGetHexWithReturn(2, atqa, &atqaLen);
|
||||
CLIGetHexWithReturn(3, sak, &sakLen);
|
||||
CLIParserFree();
|
||||
|
||||
if (uidLen && uidLen != 4) {
|
||||
PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (atqaLen && atqaLen != 2) {
|
||||
PrintAndLogEx(ERR, "UID length must be 2 bytes instead of: %d", atqaLen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (sakLen && sakLen != 1) {
|
||||
PrintAndLogEx(ERR, "UID length must be 1 byte instead of: %d", sakLen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
int res = mfCWipe((uidLen) ? uid : NULL, (atqaLen) ? atqa : NULL, (sakLen) ? sak : NULL);
|
||||
if (res) {
|
||||
PrintAndLogEx(ERR, "Can't wipe card. error=%d", res);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Card wiped successfully");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF14AMfCSetBlk(const char *Cmd) {
|
||||
uint8_t block[16] = {0x00};
|
||||
uint8_t blockNo = 0;
|
||||
@@ -4211,7 +4261,7 @@ static int CmdHF14AMfAuth4(const char *Cmd) {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
return MifareAuth4(NULL, keyn, key, true, false, true);
|
||||
return MifareAuth4(NULL, keyn, key, true, false, true, true, false);
|
||||
}
|
||||
|
||||
// https://www.nxp.com/docs/en/application-note/AN10787.pdf
|
||||
@@ -4446,6 +4496,7 @@ static command_t CommandTable[] = {
|
||||
{"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"},
|
||||
{"-----------", CmdHelp, IfPm3Iso14443a, ""},
|
||||
{"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID (magic chinese card)"},
|
||||
{"cwipe", CmdHF14AMfCWipe, IfPm3Iso14443a, "Wipe card to default UID/Sectors/Keys"},
|
||||
{"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block (magic chinese card)"},
|
||||
{"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block (magic chinese card)"},
|
||||
{"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector (magic chinese card)"},
|
||||
|
||||
+40
-37
@@ -33,7 +33,7 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return 0;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||
if (!isOK) {
|
||||
@@ -49,7 +49,7 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||
PrintAndLogEx(WARNING, "Command unsuccessful");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "-- Desfire Information --------------------------------------");
|
||||
@@ -82,7 +82,7 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||
uint8_t data[1] = {GET_FREE_MEMORY};
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), 0x01, 0, data, sizeof(data));
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500))
|
||||
return 0;
|
||||
return PM3_ETIMEOUT;
|
||||
|
||||
uint8_t tmp[3];
|
||||
memcpy(tmp, resp.data.asBytes + 3, 3);
|
||||
@@ -105,7 +105,7 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||
|
||||
*/
|
||||
|
||||
return 1;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -189,10 +189,12 @@ void getKeySettings(uint8_t *aid) {
|
||||
PrintAndLogEx(NORMAL, " [0x02] Directory list access with CMK : %s", str);
|
||||
str = (resp.data.asBytes[3] & (1 << 0)) ? "YES" : "NO";
|
||||
PrintAndLogEx(NORMAL, " [0x01] CMK is changeable : %s", str);
|
||||
|
||||
{
|
||||
uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) { return; }
|
||||
isOK = resp.oldarg[0] & 0xff;
|
||||
if (!isOK) {
|
||||
@@ -206,24 +208,27 @@ void getKeySettings(uint8_t *aid) {
|
||||
|
||||
{
|
||||
uint8_t data[2] = {AUTHENTICATE, 0}; // 0x0A, KEY 0
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;}
|
||||
isOK = resp.data.asBytes[2] & 0xff;
|
||||
PrintAndLogEx(NORMAL, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : "YES");
|
||||
|
||||
{
|
||||
uint8_t data[2] = {AUTHENTICATE_ISO, 0}; // 0x1A, KEY 0
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;}
|
||||
isOK = resp.data.asBytes[2] & 0xff;
|
||||
PrintAndLogEx(NORMAL, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : "YES");
|
||||
|
||||
{
|
||||
uint8_t data[2] = {AUTHENTICATE_AES, 0}; // 0xAA, KEY 0
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;}
|
||||
isOK = resp.data.asBytes[2] & 0xff;
|
||||
PrintAndLogEx(NORMAL, " [0xAA] Authenticate AES : %s", (isOK == 0xAE) ? "NO" : "YES");
|
||||
@@ -237,7 +242,7 @@ void getKeySettings(uint8_t *aid) {
|
||||
{
|
||||
uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a
|
||||
memcpy(data + 1, aid, 3);
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | CLEARTRACE, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(WARNING, " Timed-out");
|
||||
@@ -252,8 +257,9 @@ void getKeySettings(uint8_t *aid) {
|
||||
// KEY SETTINGS
|
||||
{
|
||||
uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
return;
|
||||
}
|
||||
@@ -294,8 +300,9 @@ void getKeySettings(uint8_t *aid) {
|
||||
// KEY VERSION - AMK
|
||||
{
|
||||
uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(WARNING, " Timed-out");
|
||||
return;
|
||||
@@ -318,11 +325,10 @@ void getKeySettings(uint8_t *aid) {
|
||||
// LOOP over numOfKeys that we got before.
|
||||
// From 0x01 to numOfKeys. We already got 0x00. (AMK)
|
||||
// TODO (iceman)
|
||||
for (int i = 0x01; i <= 0x0f; ++i) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
for (int i = 0x01; i <= 0x0f; ++i) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,17 +339,18 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||
uint8_t aid[3];
|
||||
{
|
||||
uint8_t data[1] = {GET_APPLICATION_IDS}; //0x6a
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT | DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
return 0;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
isOK = resp.oldarg[0] & 0xff;
|
||||
if (!isOK) {
|
||||
PrintAndLogEx(NORMAL, "Command unsuccessful");
|
||||
return 0;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "-- Desfire Enumerate Applications ---------------------------");
|
||||
@@ -368,7 +375,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||
{
|
||||
uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a
|
||||
memcpy(data + 1, &resp.data.asBytes[i], 3);
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, INIT, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &respAid, 1500)) {
|
||||
@@ -384,7 +391,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||
// Get File IDs
|
||||
{
|
||||
uint8_t data[1] = {GET_FILE_IDS}; // 0x6f
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) {
|
||||
@@ -405,7 +412,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||
// Get ISO File IDs
|
||||
{
|
||||
uint8_t data[1] = {GET_ISOFILE_IDS}; // 0x61
|
||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, DISCONNECT, sizeof(data), 0, data, sizeof(data));
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &respFiles, 1500)) {
|
||||
@@ -422,13 +429,9 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "-------------------------------------------------------------");
|
||||
|
||||
|
||||
return 1;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// MIAFRE DesFire Authentication
|
||||
@@ -456,7 +459,7 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf mfdes auth 1 1 0 11223344");
|
||||
PrintAndLogEx(NORMAL, " hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
uint8_t cmdAuthMode = param_get8(Cmd, 0);
|
||||
uint8_t cmdAuthAlgo = param_get8(Cmd, 1);
|
||||
@@ -466,25 +469,24 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||
case 1:
|
||||
if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2) {
|
||||
PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode");
|
||||
return 1;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2 && cmdAuthAlgo != 3) {
|
||||
PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode");
|
||||
return 1;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (cmdAuthAlgo != 4) {
|
||||
PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode");
|
||||
return 1;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Wrong Auth mode");
|
||||
return 1;
|
||||
break;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
switch (cmdAuthAlgo) {
|
||||
@@ -510,8 +512,9 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||
// key
|
||||
if (param_gethex(Cmd, 3, key, keylength * 2)) {
|
||||
PrintAndLogEx(WARNING, "Key must include %d HEX symbols", keylength);
|
||||
return 1;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
// algo, keylength,
|
||||
uint8_t data[25] = {keylength}; // max length: 1 + 24 (3k3DES)
|
||||
memcpy(data + 1, key, keylength);
|
||||
@@ -521,7 +524,7 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) {
|
||||
PrintAndLogEx(WARNING, "Client command execute timeout");
|
||||
return 0;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||
@@ -536,7 +539,7 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||
PrintAndLogEx(NORMAL, "Client command failed.");
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "-------------------------------------------------------------");
|
||||
return 1;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -553,7 +556,7 @@ static command_t CommandTable[] = {
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int CmdHFMFDes(const char *Cmd) {
|
||||
|
||||
+343
-14
@@ -25,6 +25,8 @@
|
||||
#include "cliparser/cliparser.h"
|
||||
#include "emv/dump.h"
|
||||
#include "mifare/mifaredefault.h"
|
||||
#include "util_posix.h"
|
||||
#include "fileutils.h"
|
||||
|
||||
static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
@@ -88,7 +90,7 @@ static int CmdHFMFPInfo(const char *cmd) {
|
||||
int datalen = 0;
|
||||
// https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161
|
||||
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
|
||||
int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen);
|
||||
int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen, false);
|
||||
if (!res && datalen > 1 && data[0] == 0x09) {
|
||||
SLmode = 0;
|
||||
}
|
||||
@@ -105,7 +107,7 @@ static int CmdHFMFPInfo(const char *cmd) {
|
||||
|
||||
DropField();
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFMFPWritePerso(const char *cmd) {
|
||||
@@ -169,7 +171,7 @@ static int CmdHFMFPWritePerso(const char *cmd) {
|
||||
}
|
||||
PrintAndLogEx(INFO, "Write OK.");
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001};
|
||||
@@ -245,7 +247,7 @@ static int CmdHFMFPInitPerso(const char *cmd) {
|
||||
|
||||
PrintAndLogEx(INFO, "Done.");
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFMFPCommitPerso(const char *cmd) {
|
||||
@@ -286,7 +288,7 @@ static int CmdHFMFPCommitPerso(const char *cmd) {
|
||||
}
|
||||
PrintAndLogEx(INFO, "Switch level OK.");
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFMFPAuth(const char *cmd) {
|
||||
@@ -324,7 +326,7 @@ static int CmdHFMFPAuth(const char *cmd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return MifareAuth4(NULL, keyn, key, true, false, verbose);
|
||||
return MifareAuth4(NULL, keyn, key, true, false, true, verbose, false);
|
||||
}
|
||||
|
||||
static int CmdHFMFPRdbl(const char *cmd) {
|
||||
@@ -392,7 +394,7 @@ static int CmdHFMFPRdbl(const char *cmd) {
|
||||
PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockn, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum);
|
||||
|
||||
mf4Session mf4session;
|
||||
int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose);
|
||||
int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false);
|
||||
if (res) {
|
||||
PrintAndLogEx(ERR, "Authentication error: %d", res);
|
||||
return res;
|
||||
@@ -491,7 +493,7 @@ static int CmdHFMFPRdsc(const char *cmd) {
|
||||
PrintAndLogEx(INFO, "--sector[%d]:%02x key:%04x", mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum);
|
||||
|
||||
mf4Session mf4session;
|
||||
int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose);
|
||||
int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false);
|
||||
if (res) {
|
||||
PrintAndLogEx(ERR, "Authentication error: %d", res);
|
||||
return res;
|
||||
@@ -532,7 +534,7 @@ static int CmdHFMFPRdsc(const char *cmd) {
|
||||
}
|
||||
DropField();
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFMFPWrbl(const char *cmd) {
|
||||
@@ -595,7 +597,7 @@ static int CmdHFMFPWrbl(const char *cmd) {
|
||||
PrintAndLogEx(INFO, "--block:%d sector[%d]:%02x key:%04x", blockNum & 0xff, mfNumBlocksPerSector(sectorNum), sectorNum, uKeyNum);
|
||||
|
||||
mf4Session mf4session;
|
||||
int res = MifareAuth4(&mf4session, keyn, key, true, true, verbose);
|
||||
int res = MifareAuth4(&mf4session, keyn, key, true, true, true, verbose, false);
|
||||
if (res) {
|
||||
PrintAndLogEx(ERR, "Authentication error: %d", res);
|
||||
return res;
|
||||
@@ -634,7 +636,333 @@ static int CmdHFMFPWrbl(const char *cmd) {
|
||||
|
||||
DropField();
|
||||
PrintAndLogEx(INFO, "Write OK.");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
#define AES_KEY_LEN 16
|
||||
#define MAX_KEYS_LIST_LEN 1024
|
||||
|
||||
int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyAB, uint8_t endKeyAB,
|
||||
uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t keyListLen, uint8_t foundKeys[2][64][AES_KEY_LEN + 1],
|
||||
bool verbose) {
|
||||
int res;
|
||||
bool selectCard = true;
|
||||
uint8_t keyn[2] = {0};
|
||||
|
||||
// sector number from 0
|
||||
for (uint8_t sector = startSector; sector <= endSector; sector++) {
|
||||
// 0-keyA 1-keyB
|
||||
for (uint8_t keyAB = startKeyAB; keyAB <= endKeyAB; keyAB++) {
|
||||
// main cycle with key check
|
||||
for (int i = 0; i < keyListLen; i++) {
|
||||
if (i % 10 == 0) {
|
||||
if (!verbose)
|
||||
printf(".");
|
||||
if (kbd_enter_pressed()) {
|
||||
PrintAndLogEx(WARNING, "\nAborted via keyboard!\n");
|
||||
DropField();
|
||||
return PM3_EOPABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t uKeyNum = 0x4000 + sector * 2 + keyAB;
|
||||
keyn[0] = uKeyNum >> 8;
|
||||
keyn[1] = uKeyNum & 0xff;
|
||||
|
||||
for (int retry = 0; retry < 4; retry++) {
|
||||
res = MifareAuth4(NULL, keyn, keyList[i], selectCard, true, false, false, true);
|
||||
if (res != 2)
|
||||
break;
|
||||
|
||||
if (verbose)
|
||||
PrintAndLogEx(WARNING, "retried[%d]...", retry);
|
||||
else
|
||||
printf("R");
|
||||
|
||||
DropField();
|
||||
selectCard = true;
|
||||
msleep(100);
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
PrintAndLogEx(WARNING, "sector %02d key %d [%s] res: %d", sector, keyAB, sprint_hex_inrow(keyList[i], 16), res);
|
||||
|
||||
// key for [sector,keyAB] found
|
||||
if (res == 0) {
|
||||
if (verbose)
|
||||
PrintAndLogEx(INFO, "Found key for sector %d key %s [%s]", sector, keyAB == 0 ? "A" : "B", sprint_hex_inrow(keyList[i], 16));
|
||||
else
|
||||
printf("+");
|
||||
foundKeys[keyAB][sector][0] = 0x01;
|
||||
memcpy(&foundKeys[keyAB][sector][1], keyList[i], AES_KEY_LEN);
|
||||
DropField();
|
||||
selectCard = true;
|
||||
msleep(50);
|
||||
break;
|
||||
}
|
||||
|
||||
// 5 - auth error (rnd not equal)
|
||||
if (res != 5) {
|
||||
if (verbose)
|
||||
PrintAndLogEx(ERR, "Exchange error. Aborted.");
|
||||
else
|
||||
printf("E");
|
||||
DropField();
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
selectCard = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
void Fill2bPattern(uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN], size_t *keyListLen, uint32_t *startPattern) {
|
||||
for (uint32_t pt = *startPattern; pt < 0x10000; pt++) {
|
||||
keyList[*keyListLen][0] = (pt >> 8) & 0xff;
|
||||
keyList[*keyListLen][1] = pt & 0xff;
|
||||
memcpy(&keyList[*keyListLen][2], &keyList[*keyListLen][0], 2);
|
||||
memcpy(&keyList[*keyListLen][4], &keyList[*keyListLen][0], 4);
|
||||
memcpy(&keyList[*keyListLen][8], &keyList[*keyListLen][0], 8);
|
||||
(*keyListLen)++;
|
||||
*startPattern = pt;
|
||||
if (*keyListLen == MAX_KEYS_LIST_LEN)
|
||||
break;
|
||||
}
|
||||
(*startPattern)++;
|
||||
}
|
||||
|
||||
static int CmdHFMFPChk(const char *cmd) {
|
||||
int res;
|
||||
uint8_t keyList[MAX_KEYS_LIST_LEN][AES_KEY_LEN] = {{0}};
|
||||
size_t keyListLen = 0;
|
||||
uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}};
|
||||
|
||||
CLIParserInit("hf mfp chk",
|
||||
"Checks keys with Mifare Plus card.",
|
||||
"Usage:\n"
|
||||
" hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n"
|
||||
" hf mfp chk -s 2 -a -> check default key list on sector 2, key A\n"
|
||||
" hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n"
|
||||
" hf mfp chk --pattern1b -j keys -> check all 1-byte keys pattern and save found keys to json\n"
|
||||
" hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00\n");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("aA", "keya", "check only key A (by default check all keys)."),
|
||||
arg_lit0("bB", "keyb", "check only key B (by default check all keys)."),
|
||||
arg_int0("sS", "startsec", "Start sector Num (0..255)", NULL),
|
||||
arg_int0("eE", "endsec", "End sector Num (0..255)", NULL),
|
||||
arg_str0("kK", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
|
||||
arg_str0("dD", "dict", "<file>", "file with keys dictionary"),
|
||||
arg_lit0(NULL, "pattern1b", "check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
|
||||
arg_lit0(NULL, "pattern2b", "check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
|
||||
arg_str0(NULL, "startp2b", "<Pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
|
||||
arg_str0("jJ", "json", "<file>", "json file to save keys"),
|
||||
arg_lit0("vV", "verbose", "verbose mode."),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
|
||||
bool keyA = arg_get_lit(1);
|
||||
bool keyB = arg_get_lit(2);
|
||||
uint8_t startSector = arg_get_int_def(3, 0);
|
||||
uint8_t endSector = arg_get_int_def(4, 0);
|
||||
|
||||
uint8_t vkey[16] = {0};
|
||||
int vkeylen = 0;
|
||||
CLIGetHexWithReturn(5, vkey, &vkeylen);
|
||||
if (vkeylen > 0) {
|
||||
if (vkeylen == 16) {
|
||||
memcpy(&keyList[keyListLen], vkey, 16);
|
||||
keyListLen++;
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Specified key must have 16 bytes length.");
|
||||
CLIParserFree();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0};
|
||||
int dict_filenamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(6), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) {
|
||||
PrintAndLogEx(FAILED, "File name too long or invalid.");
|
||||
CLIParserFree();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
bool pattern1b = arg_get_lit(7);
|
||||
bool pattern2b = arg_get_lit(8);
|
||||
|
||||
if (pattern1b && pattern2b) {
|
||||
PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only.");
|
||||
CLIParserFree();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (dict_filenamelen && (pattern1b || pattern2b)) {
|
||||
PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command.");
|
||||
CLIParserFree();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t startPattern = 0x0000;
|
||||
uint8_t vpattern[2];
|
||||
int vpatternlen = 0;
|
||||
CLIGetHexWithReturn(9, vpattern, &vpatternlen);
|
||||
if (vpatternlen > 0) {
|
||||
if (vpatternlen > 0 && vpatternlen <= 2) {
|
||||
startPattern = (vpattern[0] << 8) + vpattern[1];
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "Pattern must be 2-byte length.");
|
||||
CLIParserFree();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (!pattern2b)
|
||||
PrintAndLogEx(WARNING, "Pattern entered, but search mode not is 2-byte search.");
|
||||
}
|
||||
|
||||
uint8_t jsonname[250] = {0};
|
||||
int jsonnamelen = 0;
|
||||
if (CLIParamStrToBuf(arg_get_str(10), jsonname, sizeof(jsonname), &jsonnamelen)) {
|
||||
PrintAndLogEx(ERR, "Invalid json name.");
|
||||
CLIParserFree();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
jsonname[jsonnamelen] = 0;
|
||||
|
||||
bool verbose = arg_get_lit(11);
|
||||
|
||||
CLIParserFree();
|
||||
|
||||
uint8_t startKeyAB = 0;
|
||||
uint8_t endKeyAB = 1;
|
||||
if (keyA && !keyB)
|
||||
endKeyAB = 0;
|
||||
if (!keyA && keyB)
|
||||
startKeyAB = 1;
|
||||
|
||||
if (endSector < startSector)
|
||||
endSector = startSector;
|
||||
|
||||
// 1-byte pattern search mode
|
||||
if (pattern1b) {
|
||||
for (int i = 0; i < 0x100; i++)
|
||||
memset(keyList[i], i, 16);
|
||||
|
||||
keyListLen = 0x100;
|
||||
}
|
||||
|
||||
// 2-byte pattern search mode
|
||||
if (pattern2b)
|
||||
Fill2bPattern(keyList, &keyListLen, &startPattern);
|
||||
|
||||
// dictionary mode
|
||||
size_t endFilePosition = 0;
|
||||
if (dict_filenamelen) {
|
||||
uint16_t keycnt = 0;
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, 0, &endFilePosition, true);
|
||||
keyListLen = keycnt;
|
||||
if (endFilePosition)
|
||||
PrintAndLogEx(SUCCESS, "First part of dictionary successfully loaded.");
|
||||
}
|
||||
|
||||
if (keyListLen == 0) {
|
||||
for (int i = 0; i < g_mifare_plus_default_keys_len; i++) {
|
||||
if (hex_to_bytes(g_mifare_plus_default_keys[i], keyList[keyListLen], 16) != 16)
|
||||
break;
|
||||
|
||||
keyListLen++;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyListLen == 0) {
|
||||
PrintAndLogEx(ERR, "Key list is empty. Nothing to check.");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (!verbose)
|
||||
printf("Search keys:");
|
||||
while (true) {
|
||||
res = MFPKeyCheck(startSector, endSector, startKeyAB, endKeyAB, keyList, keyListLen, foundKeys, verbose);
|
||||
if (res == PM3_EOPABORTED)
|
||||
break;
|
||||
if (pattern2b && startPattern < 0x10000) {
|
||||
if (!verbose)
|
||||
printf("p");
|
||||
keyListLen = 0;
|
||||
Fill2bPattern(keyList, &keyListLen, &startPattern);
|
||||
continue;
|
||||
}
|
||||
if (dict_filenamelen && endFilePosition) {
|
||||
if (!verbose)
|
||||
printf("d");
|
||||
uint16_t keycnt = 0;
|
||||
res = loadFileDICTIONARYEx((char *)dict_filename, keyList, sizeof(keyList), NULL, 16, &keycnt, endFilePosition, &endFilePosition, false);
|
||||
keyListLen = keycnt;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!verbose)
|
||||
printf("\n");
|
||||
|
||||
// print result
|
||||
bool printedHeader = false;
|
||||
for (uint8_t sector = startSector; sector <= endSector; sector++) {
|
||||
if (foundKeys[0][sector][0] || foundKeys[1][sector][0]) {
|
||||
if (!printedHeader) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, ".------.--------------------------------.--------------------------------.");
|
||||
PrintAndLogEx(INFO, "|sector| key A | key B |");
|
||||
PrintAndLogEx(INFO, "|------|--------------------------------|--------------------------------|");
|
||||
printedHeader = true;
|
||||
}
|
||||
PrintAndLogEx(INFO, "| %02d |%32s|%32s|",
|
||||
sector,
|
||||
(foundKeys[0][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[0][sector][1], AES_KEY_LEN),
|
||||
(foundKeys[1][sector][0] == 0) ? "------ " : sprint_hex_inrow(&foundKeys[1][sector][1], AES_KEY_LEN));
|
||||
}
|
||||
}
|
||||
if (!printedHeader)
|
||||
PrintAndLogEx(INFO, "No keys found(");
|
||||
else
|
||||
PrintAndLogEx(INFO, "'------'--------------------------------'--------------------------------'\n");
|
||||
|
||||
// save keys to json
|
||||
if ((jsonnamelen > 0) && printedHeader) {
|
||||
// Mifare Plus info
|
||||
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0);
|
||||
|
||||
PacketResponseNG resp;
|
||||
WaitForResponse(CMD_ACK, &resp);
|
||||
|
||||
iso14a_card_select_t card;
|
||||
memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t));
|
||||
|
||||
uint64_t select_status = resp.oldarg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
|
||||
|
||||
uint8_t data[10 + 1 + 2 + 1 + 256 + 2 * 64 * (AES_KEY_LEN + 1)] = {0};
|
||||
uint8_t atslen = 0;
|
||||
if (select_status == 1 || select_status == 2) {
|
||||
memcpy(data, card.uid, card.uidlen);
|
||||
data[10] = card.sak;
|
||||
data[11] = card.atqa[1];
|
||||
data[12] = card.atqa[0];
|
||||
atslen = card.ats_len;
|
||||
data[13] = atslen;
|
||||
memcpy(&data[14], card.ats, atslen);
|
||||
}
|
||||
|
||||
// length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1]
|
||||
memcpy(&data[14 + atslen], foundKeys, 2 * 64 * (AES_KEY_LEN + 1));
|
||||
saveFileJSON((char *)jsonname, jsfMfPlusKeys, data, 64);
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFMFPMAD(const char *cmd) {
|
||||
@@ -728,7 +1056,7 @@ static int CmdHFMFPMAD(const char *cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFMFPNDEF(const char *cmd) {
|
||||
@@ -832,7 +1160,7 @@ static int CmdHFMFPNDEF(const char *cmd) {
|
||||
|
||||
NDEFDecodeAndPrint(data, datalen, verbose);
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
@@ -845,6 +1173,7 @@ static command_t CommandTable[] = {
|
||||
{"rdbl", CmdHFMFPRdbl, IfPm3Iso14443a, "Read blocks"},
|
||||
{"rdsc", CmdHFMFPRdsc, IfPm3Iso14443a, "Read sectors"},
|
||||
{"wrbl", CmdHFMFPWrbl, IfPm3Iso14443a, "Write blocks"},
|
||||
{"chk", CmdHFMFPChk, IfPm3Iso14443a, "Check keys"},
|
||||
{"mad", CmdHFMFPMAD, IfPm3Iso14443a, "Checks and prints MAD"},
|
||||
{"ndef", CmdHFMFPNDEF, IfPm3Iso14443a, "Prints NDEF records from card"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
@@ -853,7 +1182,7 @@ static command_t CommandTable[] = {
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int CmdHFMFP(const char *Cmd) {
|
||||
|
||||
+32
-32
@@ -445,7 +445,7 @@ static int ul_ev1_pwdgen_selftest() {
|
||||
uint8_t uid4[] = {0x04, 0xC5, 0xDF, 0x4A, 0x6D, 0x51, 0x80};
|
||||
uint32_t pwd4 = ul_ev1_pwdgenD(uid4);
|
||||
PrintAndLogEx(NORMAL, "UID | %s | %08X | %s", sprint_hex(uid4, 7), pwd4, (pwd4 == 0x72B1EC61) ? "OK" : "->72B1EC61<--");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
@@ -565,7 +565,7 @@ static int ulc_requestAuthentication(uint8_t *nonce, uint16_t nonceLength) {
|
||||
static int ulc_authentication(uint8_t *key, bool switch_off_field) {
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREUC_AUTH, switch_off_field, 0, 0, key, 16);
|
||||
SendCommandMIX(CMD_HF_MIFAREUC_AUTH, switch_off_field, 0, 0, key, 16);
|
||||
PacketResponseNG resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 0;
|
||||
if (resp.oldarg[0] == 1) return 1;
|
||||
@@ -2262,7 +2262,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
|
||||
PrintAndLogEx(NORMAL, "special PWD block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PWD, sprint_hex(data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD, keytype, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD, keytype, 0, data, sizeof(data));
|
||||
|
||||
wait4response(MFU_NTAG_SPECIAL_PWD);
|
||||
|
||||
@@ -2278,7 +2278,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
data[3] = 0;
|
||||
PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK, keytype, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK, keytype, 0, data, sizeof(data));
|
||||
wait4response(MFU_NTAG_SPECIAL_PACK);
|
||||
|
||||
// Signature
|
||||
@@ -2286,7 +2286,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
memcpy(data, mem->signature + i, 4);
|
||||
PrintAndLogEx(NORMAL, "special SIG block written 0x%X - %s\n", s, sprint_hex(data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data));
|
||||
wait4response(s);
|
||||
}
|
||||
|
||||
@@ -2295,7 +2295,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
memcpy(data, mem->version + i, 4);
|
||||
PrintAndLogEx(NORMAL, "special VERSION block written 0x%X - %s\n", s, sprint_hex(data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data));
|
||||
wait4response(s);
|
||||
}
|
||||
}
|
||||
@@ -2309,7 +2309,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
//Send write Block
|
||||
memcpy(data, mem->data + (b * 4), 4);
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data));
|
||||
wait4response(b);
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
@@ -2329,7 +2329,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
uint8_t b = blocks[i];
|
||||
memcpy(data, mem->data + (b * 4), 4);
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data));
|
||||
wait4response(b);
|
||||
PrintAndLogEx(NORMAL, "special block written %u - %s\n", b, sprint_hex(data, 4));
|
||||
}
|
||||
@@ -2338,7 +2338,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
DropField();
|
||||
free(dump);
|
||||
PrintAndLogEx(INFO, "Finish restore");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
//
|
||||
// Load emulator with dump file
|
||||
@@ -2388,7 +2388,7 @@ static int CmdHF14AMfUCAuth(const char *Cmd) {
|
||||
else
|
||||
PrintAndLogEx(WARNING, "Authentication failed");
|
||||
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2500,11 +2500,11 @@ static int CmdHF14AMfUCSetPwd(const char *Cmd) {
|
||||
|
||||
if (param_gethex(Cmd, 0, pwd, 32)) {
|
||||
PrintAndLogEx(WARNING, "Password must include 32 HEX symbols");
|
||||
return 1;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREUC_SETPWD, 0, 0, 0, pwd, 16);
|
||||
SendCommandMIX(CMD_HF_MIFAREUC_SETPWD, 0, 0, 0, pwd, 16);
|
||||
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
@@ -2512,13 +2512,13 @@ static int CmdHF14AMfUCSetPwd(const char *Cmd) {
|
||||
PrintAndLogEx(INFO, "Ultralight-C new password: %s", sprint_hex(pwd, 16));
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Failed writing at block %u", (uint8_t)(resp.oldarg[1] & 0xff));
|
||||
return 1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
return 1;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2556,7 +2556,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||
data[2] = uid[2];
|
||||
data[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data));
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
@@ -2568,7 +2568,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||
data[2] = uid[5];
|
||||
data[3] = uid[6];
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data));
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
@@ -2580,7 +2580,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||
data[2] = oldblock2[2];
|
||||
data[3] = oldblock2[3];
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data));
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data));
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
@@ -2611,11 +2611,11 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
|
||||
|
||||
if (select_status == 0) {
|
||||
PrintAndLogEx(WARNING, "iso14443a card select failed");
|
||||
return 1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
if (card.uidlen != 4) {
|
||||
PrintAndLogEx(WARNING, "Wrong sized UID, expected 4bytes got %d", card.uidlen);
|
||||
return 1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
memcpy(uid, card.uid, sizeof(uid));
|
||||
} else {
|
||||
@@ -2654,13 +2654,13 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
|
||||
, divkey // output
|
||||
);
|
||||
|
||||
PrintAndLogEx(NORMAL, "-- 3DES version");
|
||||
PrintAndLogEx(NORMAL, "Masterkey :\t %s", sprint_hex(masterkey, sizeof(masterkey)));
|
||||
PrintAndLogEx(NORMAL, "UID :\t %s", sprint_hex(uid, sizeof(uid)));
|
||||
PrintAndLogEx(NORMAL, "block :\t %0d", block);
|
||||
PrintAndLogEx(NORMAL, "Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
|
||||
PrintAndLogEx(NORMAL, "Message :\t %s", sprint_hex(mix, sizeof(mix)));
|
||||
PrintAndLogEx(NORMAL, "Diversified key: %s", sprint_hex(divkey + 1, 6));
|
||||
PrintAndLogEx(SUCCESS, "-- 3DES version");
|
||||
PrintAndLogEx(SUCCESS, "Masterkey :\t %s", sprint_hex(masterkey, sizeof(masterkey)));
|
||||
PrintAndLogEx(SUCCESS, "UID :\t %s", sprint_hex(uid, sizeof(uid)));
|
||||
PrintAndLogEx(SUCCESS, "block :\t %0d", block);
|
||||
PrintAndLogEx(SUCCESS, "Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
|
||||
PrintAndLogEx(SUCCESS, "Message :\t %s", sprint_hex(mix, sizeof(mix)));
|
||||
PrintAndLogEx(SUCCESS, "Diversified key: %s", sprint_hex(divkey + 1, 6));
|
||||
|
||||
for (int i = 0; i < ARRAYLEN(mifarekeyA); ++i) {
|
||||
dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
|
||||
@@ -2690,11 +2690,11 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
|
||||
, newpwd // output
|
||||
);
|
||||
|
||||
PrintAndLogEx(NORMAL, "\n-- DES version");
|
||||
PrintAndLogEx(NORMAL, "Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
|
||||
PrintAndLogEx(NORMAL, "Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
|
||||
PrintAndLogEx(NORMAL, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
|
||||
PrintAndLogEx(NORMAL, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
|
||||
PrintAndLogEx(SUCCESS, "\n-- DES version");
|
||||
PrintAndLogEx(SUCCESS, "Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
|
||||
PrintAndLogEx(SUCCESS, "Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
|
||||
PrintAndLogEx(SUCCESS, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
|
||||
PrintAndLogEx(SUCCESS, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
|
||||
|
||||
mbedtls_des3_free(&ctx);
|
||||
// next. from the diversify_key method.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user