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:
Iceman 2023-07-21 18:14:35 +02:00 committed by GitHub
commit 498bfa56e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 91 additions and 79 deletions

View file

@ -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 {

View file

@ -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);