mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
hf mfdes info - remake to work with Desfire Light. Switch to apdu framing. WIP
This commit is contained in:
parent
8341309754
commit
7a7a3d014e
2 changed files with 160 additions and 92 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include "crc16.h"
|
#include "crc16.h"
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define MAX_APPLICATION_COUNT 28
|
#define MAX_APPLICATION_COUNT 28
|
||||||
#define MAX_FILE_COUNT 16
|
#define MAX_FILE_COUNT 16
|
||||||
|
@ -83,7 +84,7 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||||
|
|
||||||
int len = DesfireAPDU(datain, datalen, resp);
|
int len = DesfireAPDU(datain, datalen, resp);
|
||||||
if (DBGLEVEL >= 4)
|
if (DBGLEVEL >= 4)
|
||||||
print_result("ERR <--: ", resp, len);
|
print_result("RESP <--: ", resp, len);
|
||||||
|
|
||||||
if (!len) {
|
if (!len) {
|
||||||
OnError(2);
|
OnError(2);
|
||||||
|
@ -96,16 +97,25 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||||
if (flags & DISCONNECT)
|
if (flags & DISCONNECT)
|
||||||
OnSuccess();
|
OnSuccess();
|
||||||
|
|
||||||
reply_old(CMD_ACK, 1, len, 0, resp, len);
|
reply_mix(CMD_ACK, 1, len, 0, resp, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MifareDesfireGetInformation() {
|
void MifareDesfireGetInformation() {
|
||||||
|
|
||||||
|
LEDsoff();
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
iso14a_card_select_t card;
|
iso14a_card_select_t card;
|
||||||
uint8_t resp[PM3_CMD_DATA_SIZE] = {0x00};
|
uint8_t resp[PM3_CMD_DATA_SIZE] = {0x00};
|
||||||
uint8_t dataout[PM3_CMD_DATA_SIZE] = {0x00};
|
|
||||||
|
|
||||||
|
struct p {
|
||||||
|
uint8_t isOK;
|
||||||
|
uint8_t uid[7];
|
||||||
|
uint8_t versionHW[7];
|
||||||
|
uint8_t versionSW[7];
|
||||||
|
uint8_t details[14];
|
||||||
|
} PACKED payload;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1 = PCB 1
|
1 = PCB 1
|
||||||
2 = cid 2
|
2 = cid 2
|
||||||
|
@ -122,61 +132,65 @@ void MifareDesfireGetInformation() {
|
||||||
// card select - information
|
// card select - information
|
||||||
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||||
if (DBGLEVEL >= DBG_ERROR) DbpString("Can't select card");
|
if (DBGLEVEL >= DBG_ERROR) DbpString("Can't select card");
|
||||||
OnError(1);
|
payload.isOK = 1; // 2 == can not select
|
||||||
|
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
switch_off();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card.uidlen != 7) {
|
if (card.uidlen != 7) {
|
||||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen);
|
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen);
|
||||||
OnError(2);
|
payload.isOK = 2; // 2 == WRONG UID
|
||||||
|
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
switch_off();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// add uid.
|
||||||
memcpy(dataout, card.uid, 7);
|
memcpy(payload.uid, card.uid, sizeof(card.uid));
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
LED_B_OFF();
|
uint8_t cmd[] = {GET_VERSION, 0x00, 0x00, 0x00};
|
||||||
LED_C_OFF();
|
|
||||||
|
|
||||||
uint8_t cmd[] = {GET_VERSION};
|
|
||||||
size_t cmd_len = sizeof(cmd);
|
size_t cmd_len = sizeof(cmd);
|
||||||
|
|
||||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||||
if (!len) {
|
if (!len) {
|
||||||
print_result("ERROR <--: ", resp, len);
|
print_result("ERROR <--: ", resp, len);
|
||||||
OnError(3);
|
payload.isOK = 3; // 3 == DOESNT ANSWER TO GET_VERSION
|
||||||
|
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
switch_off();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_OFF();
|
memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW));
|
||||||
LED_B_ON();
|
|
||||||
memcpy(dataout + 7, resp + 3, 7);
|
|
||||||
|
|
||||||
// ADDITION_FRAME 1
|
// ADDITION_FRAME 1
|
||||||
cmd[0] = ADDITIONAL_FRAME;
|
cmd[0] = ADDITIONAL_FRAME;
|
||||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||||
if (!len) {
|
if (!len) {
|
||||||
print_result("ERROR <--: ", resp, len);
|
print_result("ERROR <--: ", resp, len);
|
||||||
OnError(3);
|
payload.isOK = 3; // 3 == DOESNT ANSWER TO GET_VERSION
|
||||||
|
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
switch_off();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW));
|
||||||
LED_B_OFF();
|
|
||||||
LED_C_ON();
|
|
||||||
memcpy(dataout + 7 + 7, resp + 3, 7);
|
|
||||||
|
|
||||||
// ADDITION_FRAME 2
|
// ADDITION_FRAME 2
|
||||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||||
if (!len) {
|
if (!len) {
|
||||||
print_result("ERROR <--: ", resp, len);
|
print_result("ERROR <--: ", resp, len);
|
||||||
OnError(3);
|
payload.isOK = 3; // 3 == DOESNT ANSWER TO GET_VERSION
|
||||||
|
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
switch_off();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dataout + 7 + 7 + 7, resp + 3, 14);
|
memcpy(payload.details, resp + 1, sizeof(payload.details));
|
||||||
|
|
||||||
reply_old(CMD_ACK, 1, 0, 0, dataout, sizeof(dataout));
|
|
||||||
|
|
||||||
|
LED_B_ON();
|
||||||
|
reply_ng(CMD_HF_DESFIRE_INFO, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
LED_B_OFF();
|
||||||
|
|
||||||
// reset the pcb_blocknum,
|
// reset the pcb_blocknum,
|
||||||
pcb_blocknum = 0;
|
pcb_blocknum = 0;
|
||||||
OnSuccess();
|
OnSuccess();
|
||||||
|
@ -517,7 +531,7 @@ void MifareDES_Auth1(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
}
|
}
|
||||||
|
|
||||||
OnSuccess();
|
OnSuccess();
|
||||||
reply_old(CMD_ACK, 1, len, 0, resp, len);
|
reply_mix(CMD_ACK, 1, len, 0, resp, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3 different ISO ways to send data to a DESFIRE (direct, capsuled, capsuled ISO)
|
// 3 different ISO ways to send data to a DESFIRE (direct, capsuled, capsuled ISO)
|
||||||
|
@ -565,15 +579,20 @@ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout) {
|
||||||
uint8_t cmd[cmdlen];
|
uint8_t cmd[cmdlen];
|
||||||
memset(cmd, 0, cmdlen);
|
memset(cmd, 0, cmdlen);
|
||||||
|
|
||||||
cmd[0] = 0x0A; // 0x0A = send cid, 0x02 = no cid.
|
cmd[0] = 0x02; // 0x0A = send cid, 0x02 = no cid.
|
||||||
cmd[0] |= pcb_blocknum; // OR the block number into the PCB
|
cmd[0] |= pcb_blocknum; // OR the block number into the PCB
|
||||||
cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards
|
|
||||||
|
cmd[1] = 0x90; // CID: 0x00 //TODO: allow multiple selected cards
|
||||||
|
|
||||||
memcpy(cmd + 2, datain, len);
|
memcpy(cmd + 2, datain, len);
|
||||||
AddCrc14A(cmd, len + 2);
|
AddCrc14A(cmd, len + 2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
hf 14a apdu -sk 90 60 00 00 00
|
||||||
|
hf 14a apdu -k 90 AF 00 00 00
|
||||||
|
hf 14a apdu 90AF000000
|
||||||
|
*/
|
||||||
memcpy(dataout, cmd, cmdlen);
|
memcpy(dataout, cmd, cmdlen);
|
||||||
|
|
||||||
return cmdlen;
|
return cmdlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,24 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||||
SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0);
|
SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0);
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (!WaitForResponseTimeout(CMD_HF_DESFIRE_INFO, &resp, 1500)) {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
|
||||||
if (!isOK) {
|
struct p {
|
||||||
switch (resp.oldarg[1]) {
|
uint8_t isOK;
|
||||||
|
uint8_t uid[7];
|
||||||
|
uint8_t versionHW[7];
|
||||||
|
uint8_t versionSW[7];
|
||||||
|
uint8_t details[14];
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
struct p *package = (struct p *) resp.data.asBytes;
|
||||||
|
|
||||||
|
if (resp.status != PM3_SUCCESS) {
|
||||||
|
|
||||||
|
switch (package->isOK) {
|
||||||
case 1:
|
case 1:
|
||||||
PrintAndLogEx(WARNING, "Can't select card");
|
PrintAndLogEx(WARNING, "Can't select card");
|
||||||
break;
|
break;
|
||||||
|
@ -51,45 +62,49 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||||
}
|
}
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "-- Desfire Information --------------------------------------");
|
PrintAndLogEx(INFO, "-- Desfire Information --------------------------------------");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(resp.data.asBytes, 7));
|
PrintAndLogEx(SUCCESS, " UID : " _GREEN_("%s"), sprint_hex(package->uid, sizeof(package->uid)));
|
||||||
PrintAndLogEx(SUCCESS, " Batch number : " _GREEN_("%s"), sprint_hex(resp.data.asBytes + 28, 5));
|
PrintAndLogEx(SUCCESS, " Batch number : " _GREEN_("%s"), sprint_hex(package->details + 7, 5));
|
||||||
PrintAndLogEx(SUCCESS, " Production date : week %02x, 20%02x", resp.data.asBytes[33], resp.data.asBytes[34]);
|
PrintAndLogEx(SUCCESS, " Production date : week " _GREEN_("%02x") "/ " _GREEN_("20%02x"), package->details[12], package->details[13]);
|
||||||
PrintAndLogEx(INFO, " -----------------------------------------------------------");
|
PrintAndLogEx(INFO, " -----------------------------------------------------------");
|
||||||
PrintAndLogEx(INFO, " Hardware Information");
|
PrintAndLogEx(INFO, " Hardware Information");
|
||||||
PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[7]));
|
PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(package->versionHW[0]));
|
||||||
PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[8]);
|
PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), package->versionHW[1]);
|
||||||
PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[9]);
|
PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), package->versionHW[2]);
|
||||||
PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%s"), getVersionStr(resp.data.asBytes[10], resp.data.asBytes[11]));
|
PrintAndLogEx(SUCCESS, " Version : %s", getVersionStr(package->versionHW[3], package->versionHW[4]));
|
||||||
PrintAndLogEx(SUCCESS, " Storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[12]));
|
PrintAndLogEx(SUCCESS, " Storage size : %s", getCardSizeStr(package->versionHW[5]));
|
||||||
PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[13]));
|
PrintAndLogEx(SUCCESS, " Protocol : %s", getProtocolStr(package->versionHW[6]));
|
||||||
PrintAndLogEx(INFO, " -----------------------------------------------------------");
|
PrintAndLogEx(INFO, " -----------------------------------------------------------");
|
||||||
PrintAndLogEx(INFO, " Software Information");
|
PrintAndLogEx(INFO, " Software Information");
|
||||||
PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(resp.data.asBytes[14]));
|
PrintAndLogEx(SUCCESS, " Vendor Id : " _YELLOW_("%s"), getTagInfo(package->versionSW[0]));
|
||||||
PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), resp.data.asBytes[15]);
|
PrintAndLogEx(SUCCESS, " Type : " _YELLOW_("0x%02X"), package->versionSW[1]);
|
||||||
PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), resp.data.asBytes[16]);
|
PrintAndLogEx(SUCCESS, " Subtype : " _YELLOW_("0x%02X"), package->versionSW[2]);
|
||||||
PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%d.%d"), resp.data.asBytes[17], resp.data.asBytes[18]);
|
PrintAndLogEx(SUCCESS, " Version : " _YELLOW_("%d.%d"), package->versionSW[3], package->versionSW[4]);
|
||||||
PrintAndLogEx(SUCCESS, " storage size : " _YELLOW_("%s"), getCardSizeStr(resp.data.asBytes[19]));
|
PrintAndLogEx(SUCCESS, " storage size : %s", getCardSizeStr(package->versionSW[5]));
|
||||||
PrintAndLogEx(SUCCESS, " Protocol : " _YELLOW_("%s"), getProtocolStr(resp.data.asBytes[20]));
|
PrintAndLogEx(SUCCESS, " Protocol : %s", getProtocolStr(package->versionSW[6]));
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
|
|
||||||
// Master Key settings
|
// Master Key settings
|
||||||
getKeySettings(NULL);
|
getKeySettings(NULL);
|
||||||
|
|
||||||
// Free memory on card
|
// Free memory on card
|
||||||
uint8_t data[1] = {GET_FREE_MEMORY};
|
uint8_t c[] = {GET_FREE_MEMORY, 0x00, 0x00, 0x00}; // 0x6E
|
||||||
SendCommandOLD(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), 0x01, 0, data, sizeof(data));
|
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, (INIT | DISCONNECT), sizeof(c), 0, c, sizeof(c));
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500))
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500))
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
|
|
||||||
uint8_t tmp[3];
|
// Desfire Light doesn't support FREEMEM (len = 5)
|
||||||
memcpy(tmp, resp.data.asBytes + 3, 3);
|
if (resp.length == 8) {
|
||||||
|
uint8_t tmp[3];
|
||||||
PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), le24toh(tmp));
|
memcpy(tmp, resp.data.asBytes + 1, 3);
|
||||||
|
PrintAndLogEx(SUCCESS, " Available free memory on card : " _GREEN_("%d bytes"), le24toh(tmp));
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(SUCCESS, " Card doesn't support 'free mem' cmd");
|
||||||
|
}
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Card Master key (CMK) 0x00 AID = 00 00 00 (card level)
|
Card Master key (CMK) 0x00 AID = 00 00 00 (card level)
|
||||||
Application Master Key (AMK) 0x00 AID != 00 00 00
|
Application Master Key (AMK) 0x00 AID != 00 00 00
|
||||||
|
@ -116,7 +131,7 @@ static int CmdHF14ADesInfo(const char *Cmd) {
|
||||||
*/
|
*/
|
||||||
char *getCardSizeStr(uint8_t fsize) {
|
char *getCardSizeStr(uint8_t fsize) {
|
||||||
|
|
||||||
static char buf[30] = {0x00};
|
static char buf[40] = {0x00};
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
uint16_t usize = 1 << ((fsize >> 1) + 1);
|
uint16_t usize = 1 << ((fsize >> 1) + 1);
|
||||||
|
@ -124,37 +139,39 @@ char *getCardSizeStr(uint8_t fsize) {
|
||||||
|
|
||||||
// is LSB set?
|
// is LSB set?
|
||||||
if (fsize & 1)
|
if (fsize & 1)
|
||||||
sprintf(retStr, "0x%02X (%d - %d bytes)", fsize, usize, lsize);
|
sprintf(retStr, "0x%02X ( " _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize);
|
sprintf(retStr, "0x%02X ( " _YELLOW_("%d bytes") ")", fsize, lsize);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *getProtocolStr(uint8_t id) {
|
char *getProtocolStr(uint8_t id) {
|
||||||
|
|
||||||
static char buf[30] = {0x00};
|
static char buf[40] = {0x00};
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
if (id == 0x05)
|
if (id == 0x05)
|
||||||
sprintf(retStr, "0x%02X (ISO 14443-3, 14443-4)", id);
|
sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") ")", id);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "0x%02X (Unknown)", id);
|
sprintf(retStr, "0x%02X ( " _YELLOW_("Unknown") ")", id);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *getVersionStr(uint8_t major, uint8_t minor) {
|
char *getVersionStr(uint8_t major, uint8_t minor) {
|
||||||
|
|
||||||
static char buf[30] = {0x00};
|
static char buf[40] = {0x00};
|
||||||
char *retStr = buf;
|
char *retStr = buf;
|
||||||
|
|
||||||
if (major == 0x00)
|
if (major == 0x00)
|
||||||
sprintf(retStr, "%d.%d (Desfire MF3ICD40)", major, minor);
|
sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire MF3ICD40") ")", major, minor);
|
||||||
else if (major == 0x01 && minor == 0x00)
|
else if (major == 0x01 && minor == 0x00)
|
||||||
sprintf(retStr, "%d.%d (Desfire EV1)", major, minor);
|
sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire EV1") ")", major, minor);
|
||||||
else if (major == 0x12 && minor == 0x00)
|
else if (major == 0x12 && minor == 0x00)
|
||||||
sprintf(retStr, "%d.%d (Desfire EV2)", major, minor);
|
sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire EV2") ")", major, minor);
|
||||||
|
else if (major == 0x30 && minor == 0x00)
|
||||||
|
sprintf(retStr, "%x.%x ( " _YELLOW_("Desfire Light") ")", major, minor);
|
||||||
else
|
else
|
||||||
sprintf(retStr, "%d.%d (Unknown)", major, minor);
|
sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,14 +182,15 @@ void getKeySettings(uint8_t *aid) {
|
||||||
uint8_t isOK = 0;
|
uint8_t isOK = 0;
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
//memset(messStr, 0x00, 512);
|
|
||||||
|
|
||||||
if (aid == NULL) {
|
if (aid == NULL) {
|
||||||
|
|
||||||
|
// CARD MASTER KEY
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " CMK - PICC, Card Master Key settings");
|
PrintAndLogEx(SUCCESS, " CMK - PICC, Card Master Key settings");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
{
|
{
|
||||||
uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45
|
uint8_t data[] = {GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45
|
||||||
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;}
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {return;}
|
||||||
isOK = resp.oldarg[0] & 0xff;
|
isOK = resp.oldarg[0] & 0xff;
|
||||||
|
@ -180,18 +198,41 @@ void getKeySettings(uint8_t *aid) {
|
||||||
PrintAndLogEx(WARNING, _RED_(" Can't select master application"));
|
PrintAndLogEx(WARNING, _RED_(" Can't select master application"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Not supported 02 91 1c c4 ca
|
||||||
|
// OK - 02 0f 01 91 00 7e fe
|
||||||
|
if (resp.length == 7 ) {
|
||||||
|
|
||||||
|
// number of Master keys (0x01)
|
||||||
|
PrintAndLogEx(SUCCESS, " [0x08] Number of Masterkeys : %u", resp.data.asBytes[2]);
|
||||||
|
uint8_t setting = (resp.data.asBytes[2] >> 6);
|
||||||
|
switch(setting) {
|
||||||
|
case 0:
|
||||||
|
PrintAndLogEx(SUCCESS, " [00] (3)DES operation of PICC master key");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
PrintAndLogEx(SUCCESS, " [01] 3K3DES operation of PICC master key");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
PrintAndLogEx(SUCCESS, " [02] AES operation of PICC master key");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = (resp.data.asBytes[2] & (1 << 3)) ? _GREEN_("YES") : "NO";
|
||||||
|
PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str);
|
||||||
|
str = (resp.data.asBytes[2] & (1 << 2)) ? "NO" : _GREEN_("YES");
|
||||||
|
PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str);
|
||||||
|
str = (resp.data.asBytes[2] & (1 << 1)) ? "NO" : _GREEN_("YES");
|
||||||
|
PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str);
|
||||||
|
str = (resp.data.asBytes[2] & (1 << 0)) ? _GREEN_("YES") : "NO";
|
||||||
|
PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str);
|
||||||
|
}
|
||||||
|
|
||||||
str = (resp.data.asBytes[3] & (1 << 3)) ? _GREEN_("YES") : "NO";
|
// dd == key version
|
||||||
PrintAndLogEx(SUCCESS, " [0x08] Configuration changeable : %s", str);
|
// cla ins p1 p2 lc dd le
|
||||||
str = (resp.data.asBytes[3] & (1 << 2)) ? "NO" : _GREEN_("YES");
|
{ // 90, 64,
|
||||||
PrintAndLogEx(SUCCESS, " [0x04] CMK required for create/delete : %s", str);
|
uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x64
|
||||||
str = (resp.data.asBytes[3] & (1 << 1)) ? "NO" : _GREEN_("YES");
|
|
||||||
PrintAndLogEx(SUCCESS, " [0x02] Directory list access with CMK : %s", str);
|
|
||||||
str = (resp.data.asBytes[3] & (1 << 0)) ? _GREEN_("YES") : "NO";
|
|
||||||
PrintAndLogEx(SUCCESS, " [0x01] CMK is changeable : %s", str);
|
|
||||||
|
|
||||||
{
|
|
||||||
uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64
|
|
||||||
SendCommandMIX(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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,13 +242,17 @@ void getKeySettings(uint8_t *aid) {
|
||||||
PrintAndLogEx(WARNING, _RED_(" Can't read key-version"));
|
PrintAndLogEx(WARNING, _RED_(" Can't read key-version"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, "");
|
if (resp.length == 6) {
|
||||||
PrintAndLogEx(SUCCESS, " Max number of keys : " _YELLOW_("%d"), resp.data.asBytes[4]);
|
PrintAndLogEx(SUCCESS, "");
|
||||||
PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]);
|
PrintAndLogEx(SUCCESS, " Max number of keys : " _YELLOW_("%d"), resp.data.asBytes[1]);
|
||||||
PrintAndLogEx(INFO, " ----------------------------------------------------------");
|
PrintAndLogEx(SUCCESS, " Master key Version : " _YELLOW_("%d (0x%02x)"), resp.data.asBytes[3], resp.data.asBytes[3]);
|
||||||
|
PrintAndLogEx(INFO, " ----------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
uint8_t data[2] = {AUTHENTICATE, 0}; // 0x0A, KEY 0
|
// cla ins p1 p2 lc dd le
|
||||||
|
uint8_t data[] = {AUTHENTICATE, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x0A, KEY 0
|
||||||
SendCommandMIX(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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +261,7 @@ void getKeySettings(uint8_t *aid) {
|
||||||
PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES"));
|
PrintAndLogEx(SUCCESS, " [0x0A] Authenticate : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES"));
|
||||||
|
|
||||||
{
|
{
|
||||||
uint8_t data[2] = {AUTHENTICATE_ISO, 0}; // 0x1A, KEY 0
|
uint8_t data[] = {AUTHENTICATE_ISO, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0x1A, KEY 0
|
||||||
SendCommandMIX(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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +270,7 @@ void getKeySettings(uint8_t *aid) {
|
||||||
PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES"));
|
PrintAndLogEx(SUCCESS, " [0x1A] Authenticate ISO : %s", (isOK == 0xAE) ? "NO" : _YELLOW_("YES"));
|
||||||
|
|
||||||
{
|
{
|
||||||
uint8_t data[2] = {AUTHENTICATE_AES, 0}; // 0xAA, KEY 0
|
uint8_t data[] = {AUTHENTICATE_AES, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; // 0xAA, KEY 0
|
||||||
SendCommandMIX(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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,15 +280,20 @@ void getKeySettings(uint8_t *aid) {
|
||||||
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------------------------------");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// AID - APPLICATIO MASTER KEYS
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " AMK - Application Master Key settings");
|
PrintAndLogEx(SUCCESS, " AMK - Application Master Key settings");
|
||||||
PrintAndLogEx(INFO, " ----------------------------------------------------------");
|
PrintAndLogEx(INFO, " ----------------------------------------------------------");
|
||||||
|
PrintAndLogEx(INFO, "Selecting AID: %s", sprint_hex(aid, 3) );
|
||||||
|
|
||||||
// SELECT AID
|
// SELECT AID
|
||||||
{
|
{
|
||||||
uint8_t data[4] = {SELECT_APPLICATION}; // 0x5a
|
uint8_t data[] = {SELECT_APPLICATION, 0x00, 0x00, 0x00}; // 0x5a
|
||||||
memcpy(data + 1, aid, 3);
|
memcpy(data + 1, aid, 3);
|
||||||
SendCommandMIX(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)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
PrintAndLogEx(WARNING, _RED_(" Timed-out"));
|
PrintAndLogEx(WARNING, _RED_(" Timed-out"));
|
||||||
return;
|
return;
|
||||||
|
@ -256,7 +306,7 @@ void getKeySettings(uint8_t *aid) {
|
||||||
|
|
||||||
// KEY SETTINGS
|
// KEY SETTINGS
|
||||||
{
|
{
|
||||||
uint8_t data[1] = {GET_KEY_SETTINGS}; // 0x45
|
uint8_t data[] = {GET_KEY_SETTINGS, 0x00, 0x00, 0x00}; // 0x45
|
||||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +349,7 @@ void getKeySettings(uint8_t *aid) {
|
||||||
|
|
||||||
// KEY VERSION - AMK
|
// KEY VERSION - AMK
|
||||||
{
|
{
|
||||||
uint8_t data[2] = {GET_KEY_VERSION, 0}; // 0x64
|
uint8_t data[] = {GET_KEY_VERSION, 0x00, 0x00, 0x00}; // 0x64
|
||||||
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(data), 0, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +591,6 @@ static int CmdHF14ADesAuth(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"info", CmdHF14ADesInfo, IfPm3Iso14443a, "Tag information"},
|
{"info", CmdHF14ADesInfo, IfPm3Iso14443a, "Tag information"},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue