This commit is contained in:
iceman1001 2022-10-25 07:56:57 +02:00
parent a1633f9323
commit 5b90ea8117
5 changed files with 116 additions and 6 deletions

View file

@ -1464,6 +1464,7 @@ static void PacketReceived(PacketCommandNG *packet) {
iso14443a_antifuzz(payload->flag);
break;
}
// EPA related
case CMD_HF_EPA_COLLECT_NONCE: {
EPA_PACE_Collect_Nonce(packet);
break;
@ -1472,6 +1473,11 @@ static void PacketReceived(PacketCommandNG *packet) {
EPA_PACE_Replay(packet);
break;
}
case CMD_HF_EPA_PACE_SIMULATE: {
EPA_PACE_Simulate(packet);
break;
}
case CMD_HF_MIFARE_READER: {
struct p {
uint8_t first_run;

View file

@ -592,3 +592,44 @@ int EPA_Setup(void) {
Dbprintf("No card found");
return 1;
}
void EPA_PACE_Simulate(PacketCommandNG *c) {
//---------Initializing---------
// Get password from arguments
unsigned char pwd[6];
memcpy(pwd, c->data.asBytes, 6);
// Set up communication with the card
int res = EPA_Setup();
if (res != 0){
EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 1, res);
return;
}
// Read EF.CardAccess
uint8_t card_access[210] = {0};
int card_access_length = EPA_Read_CardAccess(card_access, 210);
// The response has to be at least this big to hold the OID
if (card_access_length < 18) {
EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 2, card_access_length);
return;
}
// PACEInfo of the card
pace_version_info_t pace_version_info;
// Search for the PACE OID
res = EPA_Parse_CardAccess(card_access, card_access_length, &pace_version_info);
if (res != 0 || pace_version_info.version == 0) {
EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 3, res);
return;
}
Dbprintf("Standardized Domain Parameter: %i", pace_version_info.parameter_id);
DbpString("");
DbpString("finished");
}

View file

@ -32,9 +32,7 @@ typedef struct {
// general functions
void EPA_Finish(void);
size_t EPA_Parse_CardAccess(uint8_t *data,
size_t length,
pace_version_info_t *pace_info);
size_t EPA_Parse_CardAccess(uint8_t *data, size_t length, pace_version_info_t *pace_info);
int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length);
int EPA_Setup(void);
@ -44,5 +42,6 @@ int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce);
void EPA_PACE_Collect_Nonce(PacketCommandNG *c);
void EPA_PACE_Replay(PacketCommandNG *c);
void EPA_PACE_Simulate(PacketCommandNG *c);
#endif /* __EPA_H */

View file

@ -103,9 +103,10 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) {
// perform the PACE protocol by replaying APDUs
static int CmdHFEPAPACEReplay(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf epa preplay",
CLIParserInit(&ctx, "hf epa replay",
"Perform PACE protocol by replaying given APDUs",
"hf epa preplay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D");
"hf epa replay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D"
);
void *argtable[] = {
arg_param_begin,
@ -207,10 +208,72 @@ static int CmdHFEPAPACEReplay(const char *Cmd) {
return PM3_SUCCESS;
}
// perform the PACE protocol by replaying APDUs
static int CmdHFEPAPACESimulate(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf epa sim",
"Simulate PACE protocol with given password pwd of type pty.\n"
"The crypto is performed on pc or proxmark",
"hf epa sim --pwd 112233445566\n"
"hf epa sim --pc --pty 1 --pwd 112233445566"
);
void *argtable[] = {
arg_param_begin,
arg_lit1(NULL, "pc", "perform crypto on PC"),
arg_str1(NULL, "pty", "<hex>", "type of password"),
arg_str1("p", "pwd", "<hex>", "password"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
// bool use_pc = arg_get_lit(ctx, 1);
// uint8_t pwd_type = 0;
int plen = 0;
uint8_t pwd[6] = {0};
CLIGetHexWithReturn(ctx, 3, pwd, &plen);
CLIParserFree(ctx);
PrintAndLogEx(INFO, "Starting PACE simulation...");
clearCommandBuffer();
SendCommandMIX(CMD_HF_EPA_PACE_SIMULATE, 0, 0, 0, pwd, plen);
PacketResponseNG resp;
WaitForResponse(CMD_ACK, &resp);
uint32_t *data = resp.data.asDwords;
if (resp.oldarg[0] != 0) {
PrintAndLogEx(INFO, "\nPACE failed in step %u!", (uint32_t)resp.oldarg[0]);
PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]);
PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]);
PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]);
PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]);
PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]);
PrintAndLogEx(INFO, "----------------");
} else {
PrintAndLogEx(INFO, "PACE successful!");
PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]);
PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]);
PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]);
PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]);
PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]);
PrintAndLogEx(INFO, "----------------");
}
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"},
{"preplay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"},
{"replay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"},
{"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"},
{NULL, NULL, NULL, NULL}
};

View file

@ -556,6 +556,7 @@ typedef struct {
#define CMD_HF_EPA_COLLECT_NONCE 0x038A
#define CMD_HF_EPA_REPLAY 0x038B
#define CMD_HF_EPA_PACE_SIMULATE 0x039C
#define CMD_HF_LEGIC_INFO 0x03BC
#define CMD_HF_LEGIC_ESET 0x03BD