mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Merge pull request #2050 from DidierA/trace_list_mfp
MIFARE Plus traces: Adds MAC, UnMACed to annotations, and code factorisation
This commit is contained in:
commit
498bfa56e9
2 changed files with 91 additions and 79 deletions
|
@ -273,7 +273,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i
|
||||||
MifareAuthState = masNone;
|
MifareAuthState = masNone;
|
||||||
break;
|
break;
|
||||||
case ISO14443A_CMD_RATS:
|
case ISO14443A_CMD_RATS:
|
||||||
snprintf(exp, size, "RATS - FSDI=0x%x, CID=0x%x", (cmd[1] & 0xF0) >> 4, (cmd[1] & 0x0F) );
|
snprintf(exp, size, "RATS - FSDI=%x, CID=%x", (cmd[1] & 0xF0) >> 4, (cmd[1] & 0x0F) );
|
||||||
break;
|
break;
|
||||||
/* Actually, PPSS is Dx
|
/* Actually, PPSS is Dx
|
||||||
case ISO14443A_CMD_PPS:
|
case ISO14443A_CMD_PPS:
|
||||||
|
@ -429,7 +429,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ( (cmd[0] & 0xF0) == 0xD0 && ( cmdsize == 4 || cmdsize == 5 )) {
|
if ( (cmd[0] & 0xF0) == 0xD0 && ( cmdsize == 4 || cmdsize == 5 )) {
|
||||||
snprintf(exp, size, "PPSS - CID=0x%x", cmd[0] & 0x0F) ;
|
snprintf(exp, size, "PPS - CID=%x", cmd[0] & 0x0F) ;
|
||||||
} else {
|
} else {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
@ -1202,7 +1202,10 @@ 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.
|
|
||||||
|
// MIFARE Plus
|
||||||
|
|
||||||
|
// returns the message to print for a given opcode.
|
||||||
const char *mfpGetAnnotationForCode(uint8_t code) {
|
const char *mfpGetAnnotationForCode(uint8_t code) {
|
||||||
struct mfp_code_msg {
|
struct mfp_code_msg {
|
||||||
uint8_t code;
|
uint8_t code;
|
||||||
|
@ -1222,6 +1225,19 @@ const char *mfpGetAnnotationForCode(uint8_t code) {
|
||||||
{ MFDES_PREPARE_PC, "PREPARE PROXIMITY CHECK"},
|
{ MFDES_PREPARE_PC, "PREPARE PROXIMITY CHECK"},
|
||||||
{ MFDES_PROXIMITY_CHECK, "PROXIMITY CHECK"},
|
{ MFDES_PROXIMITY_CHECK, "PROXIMITY CHECK"},
|
||||||
{ MFDES_VERIFY_PC, "VERIFY PROXIMITY CHECK"},
|
{ MFDES_VERIFY_PC, "VERIFY PROXIMITY CHECK"},
|
||||||
|
{ MFDES_COMMIT_READER_ID, "COMMIT READER ID"},
|
||||||
|
{ MFP_INCREMENTNOMAC, "INCREMENT"},
|
||||||
|
{ MFP_INCREMENTMAC, "INCREMENT"},
|
||||||
|
{ MFP_DECREMENTMAC, "DECREMENT"},
|
||||||
|
{ MFP_DECREMENTNOMAC, "DECREMENT"},
|
||||||
|
{ MFP_TRANSFERNOMAC, "TRANSFER"},
|
||||||
|
{ MFP_TRANSFERMAC, "TRANSFER"},
|
||||||
|
{ MFP_INCREMENTTRANSFERNOMAC, "INCREMENT, TRANSFER"},
|
||||||
|
{ MFP_INCREMENTTRANSFERMAC, "INCREMENT, TRANSFER"},
|
||||||
|
{ MFP_DECREMENTTRANSFERNOMAC, "DECREMENT, TRANSFER"},
|
||||||
|
{ MFP_DECREMENTTRANSFERMAC, "DECREMENT, TRANSFER"},
|
||||||
|
{ MFP_RESTORENOMAC, "RESTORE"},
|
||||||
|
{ MFP_RESTOREMAC, "RESTORE"},
|
||||||
{ 0, NULL}
|
{ 0, NULL}
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -1233,7 +1249,44 @@ const char *mfpGetAnnotationForCode(uint8_t code) {
|
||||||
return NULL ;
|
return NULL ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIFARE Plus
|
const char *mfpGetEncryptedForCode(uint8_t code){
|
||||||
|
/*
|
||||||
|
encrypted |plain : bit 1
|
||||||
|
30 A0 0000 32 A2 0010
|
||||||
|
31 A1 0001 33 A3 0011
|
||||||
|
34 0100 36 0110
|
||||||
|
35 0101 37 0111
|
||||||
|
*/
|
||||||
|
if ((code & 0x02) == 2) {
|
||||||
|
return "PLAIN" ;
|
||||||
|
}
|
||||||
|
return "ENCRYPTED" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
response |command
|
||||||
|
NOMAC MAC UnMACed MACed
|
||||||
|
30 31 34 30,A0
|
||||||
|
32 33 35 31,A1
|
||||||
|
A0 A1 36 32,A2
|
||||||
|
A2 A3 37 33,A3
|
||||||
|
bit 0 is response: NOMAC if 0, MAC if 1
|
||||||
|
bit 2 is command: UNMACed if 1, MACed if 0
|
||||||
|
*/
|
||||||
|
const char *mfpGetResponseMacedForCode(uint8_t code) {
|
||||||
|
if (( code & 0x01) == 0x00) {
|
||||||
|
return "NoMAC" ;
|
||||||
|
}
|
||||||
|
return "MAC" ;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *mfpGetCommandMacedForCode(uint8_t code) {
|
||||||
|
if (( code & 0x04) == 0x04) {
|
||||||
|
return "UnMACed" ;
|
||||||
|
}
|
||||||
|
return "MACed" ;
|
||||||
|
}
|
||||||
|
|
||||||
void annotateMfPlus(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
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 we are in Mifare Classic Authenticated mode, all the work has already be done elsewhere
|
||||||
|
@ -1269,8 +1322,8 @@ void annotateMfPlus(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||||
if (cmdsize > (data - cmd)) {
|
if (cmdsize > (data - cmd)) {
|
||||||
data_size = cmdsize - (data - cmd);
|
data_size = cmdsize - (data - cmd);
|
||||||
}
|
}
|
||||||
|
uint8_t opcode=cmd[pos] ;
|
||||||
switch (cmd[pos]) {
|
switch (opcode) {
|
||||||
case MFP_AUTHENTICATEFIRST:
|
case MFP_AUTHENTICATEFIRST:
|
||||||
case MFP_AUTHENTICATEFIRST_VARIANT:
|
case MFP_AUTHENTICATEFIRST_VARIANT:
|
||||||
if (data_size > 1) {
|
if (data_size > 1) {
|
||||||
|
@ -1295,119 +1348,75 @@ void annotateMfPlus(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||||
case MFP_READENCRYPTEDMAC_MACED:
|
case MFP_READENCRYPTEDMAC_MACED:
|
||||||
case MFP_READENCRYPTEDNOMAC_UNMACED:
|
case MFP_READENCRYPTEDNOMAC_UNMACED:
|
||||||
case MFP_READENCRYPTEDMAC_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_READPLAINNOMAC_MACED:
|
||||||
case MFP_READPLAINMAC_MACED:
|
case MFP_READPLAINMAC_MACED:
|
||||||
case MFP_READPLAINNOMAC_UNMACED:
|
case MFP_READPLAINNOMAC_UNMACED:
|
||||||
case MFP_READPLAINMAC_UNMACED:
|
case MFP_READPLAINMAC_UNMACED: {
|
||||||
|
const char *encrypted = mfpGetEncryptedForCode(opcode) ;
|
||||||
|
const char *responseMaced = mfpGetResponseMacedForCode(opcode) ;
|
||||||
|
const char *commandMaced = mfpGetCommandMacedForCode(opcode) ;
|
||||||
|
|
||||||
if (data_size > 2) {
|
if (data_size > 2) {
|
||||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||||
uint8_t uQty = data[2] ;
|
uint8_t uQty = data[2] ;
|
||||||
if (uQty != 1) {
|
if (uQty != 1) {
|
||||||
snprintf(exp, size, "READ PLAIN(%u-%u)", uBlockNum, uBlockNum+uQty-1);
|
snprintf(exp, size, "READ %s(%u-%u) %s_%s", encrypted, uBlockNum, uBlockNum+uQty-1, responseMaced, commandMaced);
|
||||||
} else {
|
} else {
|
||||||
snprintf(exp, size, "READ PLAIN(%u)", uBlockNum);
|
snprintf(exp, size, "READ %s(%u) %s_%s", encrypted, uBlockNum, responseMaced, commandMaced);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf(exp, size, "READ PLAIN ?");
|
snprintf(exp, size, "READ %s %s_%s ?", encrypted, responseMaced, commandMaced);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFP_WRITEPLAINNOMAC :
|
case MFP_WRITEPLAINNOMAC :
|
||||||
case MFP_WRITEPLAINMAC :
|
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_WRITEENCRYPTEDNOMAC:
|
||||||
case MFP_WRITEENCRYPTEDMAC :
|
case MFP_WRITEENCRYPTEDMAC :{
|
||||||
|
const char *encrypted = mfpGetEncryptedForCode(opcode) ;
|
||||||
|
const char *responseMaced = mfpGetResponseMacedForCode(opcode) ;
|
||||||
|
|
||||||
if (data_size > 1) {
|
if (data_size > 1) {
|
||||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||||
snprintf(exp, size, "WRITE ENCRYPTED(%u)", uBlockNum);
|
snprintf(exp, size, "WRITE %s(%u) %s", encrypted, uBlockNum, responseMaced);
|
||||||
} else {
|
} else {
|
||||||
snprintf(exp, size, "WRITE ENCRYPTED ?");
|
snprintf(exp, size, "WRITE %s %s ?", encrypted, responseMaced);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MFP_INCREMENTNOMAC :
|
case MFP_INCREMENTNOMAC :
|
||||||
case MFP_INCREMENTMAC :
|
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_DECREMENTNOMAC :
|
||||||
case MFP_DECREMENTMAC :
|
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_TRANSFERNOMAC :
|
||||||
case MFP_TRANSFERMAC :
|
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_INCREMENTTRANSFERNOMAC:
|
||||||
case MFP_INCREMENTTRANSFERMAC :
|
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_DECREMENTTRANSFERNOMAC:
|
||||||
case MFP_DECREMENTTRANSFERMAC :
|
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_RESTORENOMAC :
|
||||||
case MFP_RESTOREMAC :
|
case MFP_RESTOREMAC :{
|
||||||
|
const char *responseMaced = mfpGetResponseMacedForCode(opcode) ;
|
||||||
|
const char *annotation = mfpGetAnnotationForCode(opcode) ;
|
||||||
|
if (annotation == NULL) {
|
||||||
|
//should not happen outside of default case: it means an entry is mising in mfpGetAnnotationForCode()
|
||||||
|
annotation="?? MISSING OPCODE" ;
|
||||||
|
}
|
||||||
|
|
||||||
if (data_size > 1) {
|
if (data_size > 1) {
|
||||||
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
uint16_t uBlockNum = MemLeToUint2byte(data) ;
|
||||||
snprintf(exp, size, "RESTORE(%u)", uBlockNum);
|
snprintf(exp, size, "%s(%u) %s", annotation, uBlockNum, responseMaced);
|
||||||
} else {
|
} else {
|
||||||
snprintf(exp, size, "RESTORE ?");
|
snprintf(exp, size, "%s %s ?", annotation, responseMaced);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
// Messages for commands that do not need args are treated here
|
// Messages for commands that do not need args are treated here
|
||||||
const char *annotation = mfpGetAnnotationForCode(cmd[pos]) ;
|
const char *annotation = mfpGetAnnotationForCode(opcode) ;
|
||||||
if (annotation != NULL) {
|
if (annotation != NULL) {
|
||||||
snprintf(exp, size, "%s", annotation) ;
|
snprintf(exp, size, "%s", annotation) ;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -57,6 +57,9 @@ 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 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);
|
void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
||||||
const char *mfpGetAnnotationForCode(uint8_t code);
|
const char *mfpGetAnnotationForCode(uint8_t code);
|
||||||
|
const char *mfpGetEncryptedForCode(uint8_t code);
|
||||||
|
const char *mfpGetResponseMacedForCode(uint8_t code);
|
||||||
|
const char *mfpGetCommandMacedForCode(uint8_t code);
|
||||||
void annotateMfPlus(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize);
|
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,
|
void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize,
|
||||||
const uint8_t *parity, uint8_t paritysize, bool isResponse);
|
const uint8_t *parity, uint8_t paritysize, bool isResponse);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue