mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-30 11:39:14 -07:00
Add MIFARE Plus commands in trace list
This commit is contained in:
parent
0d682da676
commit
b314d1ef1c
7 changed files with 300 additions and 12 deletions
|
@ -3,6 +3,7 @@ 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 mfp list` - interprets MIFARE Plus commands in traces (@DidierA)
|
||||
- Changed `hf legic sim` - loop and return codes on deviceside updated to DEFINES (@iceman1001)
|
||||
- Changed `hf legic einfo` - now accepts the three different cardsizes as params (@iceman1001)
|
||||
- Fix `lf cotag reader -1` - now doesn't fail (@iceman1001)
|
||||
|
|
|
@ -1196,6 +1196,230 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// codes for which no data is interpreted, returns the message to print.
|
||||
const char *mfpGetAnnotationForCode(uint8_t code) {
|
||||
struct mfp_code_msg {
|
||||
uint8_t code;
|
||||
const char *annotation;
|
||||
} messages[] = {
|
||||
{ MFP_GETVERSION, "GET VERSION"},
|
||||
{ MFP_ADDITIONALFRAME, "NEXT FRAME"},
|
||||
{ MFP_AUTHENTICATENONFIRST, "FOLLOWING AUTH"},
|
||||
{ MFP_AUTHENTICATECONTINUE, "SECOND AUTH STEP"},
|
||||
{ MFP_RESETAUTH, "RESET AUTH"},
|
||||
{ MFP_COMMITPERSO, "COMMIT PERSO"},
|
||||
{ MFP_VCSUPPORTLASTISOL3, "CHECK VIRTUAL CARD"},
|
||||
{ MFP_ISOSELECT, "SELECT VIRTUAL CARD"},
|
||||
{ MFP_SETCONFIGSL1, "SET CONFIG SL1"},
|
||||
{ MFP_MF_PERSONALIZEUIDUSAGE, "PERSONALIZE UID USAGE"},
|
||||
{ MFP_READ_SIG, "READ SIGNATURE"},
|
||||
{ MFDES_PREPARE_PC, "PREPARE PROXIMITY CHECK"},
|
||||
{ MFDES_PROXIMITY_CHECK, "PROXIMITY CHECK"},
|
||||
{ MFDES_VERIFY_PC, "VERIFY PROXIMITY CHECK"},
|
||||
{ 0, NULL}
|
||||
} ;
|
||||
|
||||
for (struct mfp_code_msg *p=messages ; p->annotation != NULL ; p++) {
|
||||
if (p->code == code) {
|
||||
return p->annotation ;
|
||||
}
|
||||
}
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
// MIFARE Plus
|
||||
void annotateMfPlus(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||
|
||||
// If we are in Mifare Classic Authenticated mode, all the work has already be done elsewhere
|
||||
if ((MifareAuthState != masNone) && (MifareAuthState != masError)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
// it's basically a ISO14443a tag, so try annotation from there
|
||||
if (applyIso14443a(exp, size, cmd, cmdsize, false) == PM3_SUCCESS) {
|
||||
return ;
|
||||
}
|
||||
|
||||
// ok this part is copy paste from annotateMfDesfire, it seems to work for MIFARE Plus also
|
||||
if (((cmd[0] & 0xC0) == 0x00) && (cmdsize > 2)) {
|
||||
|
||||
// PCB [CID] [NAD] [INF] CRC CRC
|
||||
int pos = 1;
|
||||
if ((cmd[0] & 0x08) == 0x08) // cid byte following
|
||||
pos++;
|
||||
|
||||
if ((cmd[0] & 0x04) == 0x04) // nad byte following
|
||||
pos++;
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++, pos++) {
|
||||
bool found_annotation = true;
|
||||
|
||||
uint8_t *data = cmd + pos + 1;
|
||||
// if the byte prior to the command is 90 the command is wrapped, so data starts 3 bytes later
|
||||
if (i > 0 && cmd[pos - 1] == 0x90) {
|
||||
data += 3;
|
||||
}
|
||||
uint8_t data_size = 0;
|
||||
if (cmdsize > (data - cmd)) {
|
||||
data_size = cmdsize - (data - cmd);
|
||||
}
|
||||
|
||||
// Messages for commands that do not need args are treated first
|
||||
const char *annotation = mfpGetAnnotationForCode(cmd[pos]) ;
|
||||
if (annotation != NULL) {
|
||||
snprintf(exp, size, "%s", annotation) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
switch (cmd[pos]) {
|
||||
case MFP_AUTHENTICATEFIRST:
|
||||
case MFP_AUTHENTICATEFIRST_VARIANT:
|
||||
if (data_size > 1) {
|
||||
// key : uint16_t uKeyNum = 0x4000 + sectorNum * 2 + (keyB ? 1 : 0);
|
||||
uint16_t uKeyNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "FIRST AUTH (Keynr 0x%04X: %c sector %d)", uKeyNum, uKeyNum & 0x0001 ? 'B' : 'A', (uKeyNum - 0x4000)/2 );
|
||||
} else {
|
||||
snprintf(exp, size, "FIRST AUTH") ;
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_WRITEPERSO:
|
||||
if (data_size > 1) {
|
||||
uint16_t uKeyNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "WRITE PERSO (Keynr 0x%04X)", uKeyNum);
|
||||
} else {
|
||||
snprintf(exp, size, "WRITE PERSO");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_READENCRYPTEDNOMAC_MACED:
|
||||
case MFP_READENCRYPTEDMAC_MACED:
|
||||
case MFP_READENCRYPTEDNOMAC_UNMACED:
|
||||
case MFP_READENCRYPTEDMAC_UNMACED:
|
||||
if (data_size > 2) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
uint8_t uQty = data[2] ;
|
||||
if (uQty != 1) {
|
||||
snprintf(exp, size, "READ ENCRYPTED(%u-%u)", uBlockNum, uBlockNum+uQty-1);
|
||||
} else {
|
||||
snprintf(exp, size, "READ ENCRYPTED(%u)", uBlockNum);
|
||||
}
|
||||
} else {
|
||||
snprintf(exp, size, "READ ENCRYPTED ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_READPLAINNOMAC_MACED:
|
||||
case MFP_READPLAINMAC_MACED:
|
||||
case MFP_READPLAINNOMAC_UNMACED:
|
||||
case MFP_READPLAINMAC_UNMACED:
|
||||
if (data_size > 2) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
uint8_t uQty = data[2] ;
|
||||
if (uQty != 1) {
|
||||
snprintf(exp, size, "READ PLAIN(%u-%u)", uBlockNum, uBlockNum+uQty-1);
|
||||
} else {
|
||||
snprintf(exp, size, "READ PLAIN(%u)", uBlockNum);
|
||||
}
|
||||
} else {
|
||||
snprintf(exp, size, "READ PLAIN ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_WRITEPLAINNOMAC :
|
||||
case MFP_WRITEPLAINMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "WRITE PLAIN(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "WRITE PLAIN ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_WRITEENCRYPTEDNOMAC:
|
||||
case MFP_WRITEENCRYPTEDMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "WRITE ENCRYPTED(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "WRITE ENCRYPTED ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_INCREMENTNOMAC :
|
||||
case MFP_INCREMENTMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "INCREMENT(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "INCREMENT ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_DECREMENTNOMAC :
|
||||
case MFP_DECREMENTMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "DECREMENT(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "DECREMENT ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_TRANSFERNOMAC :
|
||||
case MFP_TRANSFERMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "TRANSFER(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "TRANSFER ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_INCREMENTTRANSFERNOMAC:
|
||||
case MFP_INCREMENTTRANSFERMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "INCREMENT, TRANSFER(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "INCREMENT, TRANSFER ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_DECREMENTTRANSFERNOMAC:
|
||||
case MFP_DECREMENTTRANSFERMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "DECREMENT, TRANSFER(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "DECREMENT, TRANSFER ?");
|
||||
}
|
||||
break;
|
||||
|
||||
case MFP_RESTORENOMAC :
|
||||
case MFP_RESTOREMAC :
|
||||
if (data_size > 1) {
|
||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||
snprintf(exp, size, "RESTORE(%u)", uBlockNum);
|
||||
} else {
|
||||
snprintf(exp, size, "RESTORE ?");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
found_annotation = false;
|
||||
break;
|
||||
}
|
||||
if (found_annotation) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// anything else
|
||||
snprintf(exp, size, "?");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
06 00 = INITIATE
|
||||
|
|
|
@ -56,6 +56,8 @@ void annotateIso7816(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
|||
void annotateIso14443b(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool is_response);
|
||||
void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
const char *mfpGetAnnotationForCode(uint8_t code);
|
||||
void annotateMfPlus(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize,
|
||||
const uint8_t *parity, uint8_t paritysize, bool isResponse);
|
||||
void annotateLTO(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||
|
|
|
@ -1811,7 +1811,7 @@ static int CmdHFMFPNDEFWrite(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdHFMFPList(const char *Cmd) {
|
||||
return CmdTraceListAlias(Cmd, "hf mf", "mf");
|
||||
return CmdTraceListAlias(Cmd, "hf mfp", "mfp");
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
|
|
|
@ -533,6 +533,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
crcStatus = !felica_CRC_check(frame + 2, data_len - 4);
|
||||
break;
|
||||
case PROTO_MIFARE:
|
||||
case PROTO_MFPLUS:
|
||||
crcStatus = mifare_CRC_check(hdr->isResponse, frame, data_len);
|
||||
break;
|
||||
case ISO_14443A:
|
||||
|
@ -603,7 +604,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
&& protocol != FELICA
|
||||
&& protocol != LTO
|
||||
&& protocol != PROTO_CRYPTORF
|
||||
&& (hdr->isResponse || protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == SEOS)
|
||||
&& (hdr->isResponse || protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == PROTO_MFPLUS || protocol == SEOS)
|
||||
&& (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) {
|
||||
|
||||
snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x! ", frame[j]);
|
||||
|
@ -701,6 +702,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
// mark short bytes (less than 8 Bit + Parity)
|
||||
if (protocol == ISO_14443A ||
|
||||
protocol == PROTO_MIFARE ||
|
||||
protocol == PROTO_MFPLUS ||
|
||||
protocol == THINFILM) {
|
||||
|
||||
// approximated with 128 * (9 * data_len);
|
||||
|
@ -747,6 +749,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
annotateIso14443a(explanation, sizeof(explanation), frame, data_len, hdr->isResponse);
|
||||
break;
|
||||
case PROTO_MIFARE:
|
||||
case PROTO_MFPLUS:
|
||||
annotateMifare(explanation, sizeof(explanation), frame, data_len, parityBytes, TRACELOG_PARITY_LEN(hdr), hdr->isResponse);
|
||||
break;
|
||||
case PROTO_HITAG1:
|
||||
|
@ -766,7 +769,6 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
}
|
||||
|
||||
if (hdr->isResponse == false) {
|
||||
|
||||
switch (protocol) {
|
||||
case LEGIC:
|
||||
annotateLegic(explanation, sizeof(explanation), frame, data_len);
|
||||
|
@ -774,6 +776,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
case MFDES:
|
||||
annotateMfDesfire(explanation, sizeof(explanation), frame, data_len);
|
||||
break;
|
||||
case PROTO_MFPLUS:
|
||||
annotateMfPlus(explanation, sizeof(explanation), frame, data_len);
|
||||
break;
|
||||
case ISO_14443B:
|
||||
annotateIso14443b(explanation, sizeof(explanation), frame, data_len);
|
||||
break;
|
||||
|
@ -901,7 +906,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
}
|
||||
}
|
||||
|
||||
if (protocol == PROTO_MIFARE) {
|
||||
if (protocol == PROTO_MIFARE || protocol == PROTO_MFPLUS) {
|
||||
uint8_t mfData[32] = {0};
|
||||
size_t mfDataLen = 0;
|
||||
if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen, mfDicKeys, mfDicKeysCount)) {
|
||||
|
@ -1200,6 +1205,7 @@ int CmdTraceList(const char *Cmd) {
|
|||
"trace list -t seos -> interpret as " _YELLOW_("SEOS") "\n"
|
||||
"trace list -t thinfilm -> interpret as " _YELLOW_("Thinfilm") "\n"
|
||||
"trace list -t topaz -> interpret as " _YELLOW_("Topaz") "\n"
|
||||
"trace list -t mfp -> interpret as " _YELLOW_("MIFARE Plus") "\n"
|
||||
"\n"
|
||||
"trace list -t mf -f mfc_default_keys.dic -> use default dictionary file\n"
|
||||
"trace list -t 14a --frame -> show frame delay times\n"
|
||||
|
@ -1266,6 +1272,7 @@ int CmdTraceList(const char *Cmd) {
|
|||
else if (strcmp(type, "seos") == 0) protocol = SEOS;
|
||||
else if (strcmp(type, "thinfilm") == 0) protocol = THINFILM;
|
||||
else if (strcmp(type, "topaz") == 0) protocol = TOPAZ;
|
||||
else if (strcmp(type, "mfp") == 0) protocol = PROTO_MFPLUS;
|
||||
else if (strcmp(type, "") == 0) protocol = -1;
|
||||
else {
|
||||
PrintAndLogEx(FAILED, "Unknown protocol \"%s\"", type);
|
||||
|
@ -1304,7 +1311,7 @@ int CmdTraceList(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, _YELLOW_("start") " = start of start frame " _YELLOW_("end") " = end of frame. " _YELLOW_("src") " = source of transfer");
|
||||
}
|
||||
|
||||
if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == TOPAZ || protocol == LTO) {
|
||||
if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == MFDES || protocol == PROTO_MFPLUS || protocol == TOPAZ || protocol == LTO) {
|
||||
if (use_us)
|
||||
PrintAndLogEx(INFO, _YELLOW_("ISO14443A") " - all times are in microseconds");
|
||||
else
|
||||
|
@ -1354,7 +1361,7 @@ int CmdTraceList(const char *Cmd) {
|
|||
uint32_t dicKeysCount = 0;
|
||||
bool dictionaryLoad = false;
|
||||
|
||||
if (protocol == PROTO_MIFARE) {
|
||||
if (protocol == PROTO_MIFARE || protocol == PROTO_MFPLUS) {
|
||||
if (diclen > 0) {
|
||||
uint8_t *keyBlock = NULL;
|
||||
int res = loadFileDICTIONARY_safe(dictionary, (void **) &keyBlock, 6, &dicKeysCount);
|
||||
|
@ -1387,7 +1394,7 @@ int CmdTraceList(const char *Cmd) {
|
|||
PrintAndLogEx(NORMAL, "------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------");
|
||||
|
||||
// clean authentication data used with the mifare classic decrypt fct
|
||||
if (protocol == ISO_14443A || protocol == PROTO_MIFARE)
|
||||
if (protocol == ISO_14443A || protocol == PROTO_MIFARE || protocol == PROTO_MFPLUS)
|
||||
ClearAuthData();
|
||||
|
||||
uint32_t previous_EOT = 0;
|
||||
|
|
|
@ -6159,10 +6159,10 @@
|
|||
},
|
||||
"hf mfp list": {
|
||||
"command": "hf mfp list",
|
||||
"description": "Alias of `trace list -t mf` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
||||
"description": "Alias of `trace list -t mfp` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
||||
"notes": [
|
||||
"hf mf list --frame -> show frame delay times",
|
||||
"hf mf list -1 -> use trace buffer"
|
||||
"hf mfp list --frame -> show frame delay times",
|
||||
"hf mfp list -1 -> use trace buffer"
|
||||
],
|
||||
"offline": true,
|
||||
"options": [
|
||||
|
@ -6176,7 +6176,7 @@
|
|||
"or to import into Wireshark using encapsulation type \"ISO 14443\"",
|
||||
"-f, --file <fn> filename of dictionary"
|
||||
],
|
||||
"usage": "hf mf list [-h1crux] [--frame] [-f <fn>]"
|
||||
"usage": "hf mfp list [-h1crux] [--frame] [-f <fn>]"
|
||||
},
|
||||
"hf mfp mad": {
|
||||
"command": "hf mfp mad",
|
||||
|
@ -11488,6 +11488,7 @@
|
|||
"trace list -t seos -> interpret as SEOS",
|
||||
"trace list -t thinfilm -> interpret as Thinfilm",
|
||||
"trace list -t topaz -> interpret as Topaz",
|
||||
"trace list -t mfp -> interpret as MIFARE Plus",
|
||||
"",
|
||||
"trace list -t mf -f mfc_default_keys.dic -> use default dictionary file",
|
||||
"trace list -t 14a --frame -> show frame delay times",
|
||||
|
@ -11694,6 +11695,6 @@
|
|||
"metadata": {
|
||||
"commands_extracted": 679,
|
||||
"extracted_by": "PM3Help2JSON v1.00",
|
||||
"extracted_on": "2023-07-17T15:46:12"
|
||||
"extracted_on": "2023-07-19T19:11:10"
|
||||
}
|
||||
}
|
|
@ -428,6 +428,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
#define PROTO_HITAGS 14
|
||||
#define PROTO_CRYPTORF 15
|
||||
#define SEOS 16
|
||||
#define PROTO_MFPLUS 17
|
||||
|
||||
// Picopass fuses
|
||||
#define FUSE_FPERS 0x80
|
||||
|
@ -620,6 +621,58 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
#define MFDES_E_FILE_NOT_FOUND 0xF0
|
||||
#define MFDES_E_FILE_INTEGRITY 0xF1
|
||||
|
||||
// MIFARE PLus EV2 Command set
|
||||
// source: https://www.nxp.com/docs/en/data-sheet/MF1P(H)x2.pdf in Look-Up Tables
|
||||
|
||||
#define MFP_READ_SIG 0x3C // same as DESFIRE
|
||||
#define MFP_WRITEPERSO 0xA8
|
||||
#define MFP_COMMITPERSO 0xAA
|
||||
|
||||
#define MFP_AUTHENTICATEFIRST 0x70
|
||||
#define MFP_AUTHENTICATEFIRST_VARIANT 0x73
|
||||
#define MFP_AUTHENTICATENONFIRST 0x76
|
||||
#define MFP_AUTHENTICATECONTINUE 0x72
|
||||
#define MFP_AUTHENTICATESECTORSWITCH 0x7A
|
||||
#define MFP_RESETAUTH 0x78
|
||||
|
||||
#define MFP_VCSUPPORTLASTISOL3 0x4B
|
||||
#define MFP_ISOSELECT 0xA4
|
||||
|
||||
#define MFP_GETVERSION 0x60 // same as DESFIRE
|
||||
#define MFP_ADDITIONALFRAME 0xAF
|
||||
#define MFP_SETCONFIGSL1 0x44
|
||||
#define MFP_MF_PERSONALIZEUIDUSAGE 0x40
|
||||
|
||||
// read commands
|
||||
#define MFP_READENCRYPTEDNOMAC_MACED 0X30
|
||||
#define MFP_READENCRYPTEDMAC_MACED 0x31
|
||||
#define MFP_READPLAINNOMAC_MACED 0x32
|
||||
#define MFP_READPLAINMAC_MACED 0x33
|
||||
#define MFP_READENCRYPTEDNOMAC_UNMACED 0x34
|
||||
#define MFP_READENCRYPTEDMAC_UNMACED 0X35
|
||||
#define MFP_READPLAINNOMAC_UNMACED 0x36
|
||||
#define MFP_READPLAINMAC_UNMACED 0x37
|
||||
|
||||
// write commands
|
||||
#define MFP_WRITEENCRYPTEDNOMAC 0xA0
|
||||
#define MFP_WRITEENCRYPTEDMAC 0xA1
|
||||
#define MFP_WRITEPLAINNOMAC 0xA2
|
||||
#define MFP_WRITEPLAINMAC 0xA3
|
||||
|
||||
// value commands
|
||||
#define MFP_INCREMENTNOMAC 0xB0
|
||||
#define MFP_INCREMENTMAC 0xB1
|
||||
#define MFP_DECREMENTNOMAC 0xB2
|
||||
#define MFP_DECREMENTMAC 0xB3
|
||||
#define MFP_TRANSFERNOMAC 0xB4
|
||||
#define MFP_TRANSFERMAC 0xB5
|
||||
#define MFP_INCREMENTTRANSFERNOMAC 0xB6
|
||||
#define MFP_INCREMENTTRANSFERMAC 0xB7
|
||||
#define MFP_DECREMENTTRANSFERNOMAC 0xB8
|
||||
#define MFP_DECREMENTTRANSFERMAC 0xB9
|
||||
#define MFP_RESTORENOMAC 0xC2
|
||||
#define MFP_RESTOREMAC 0xC3
|
||||
|
||||
|
||||
// LEGIC Commands
|
||||
#define LEGIC_MIM_22 0x0D
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue