Add felica request service all nodes command.

Make style.
This commit is contained in:
Thomas Sutter 2019-10-22 17:03:54 +02:00
commit 3f56116615
5 changed files with 71 additions and 45 deletions

View file

@ -97,7 +97,10 @@ static int usage_hf_felica_request_service(void) {
PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>"); PrintAndLogEx(NORMAL, "\nUsage: hf felica rqservice [-h] [-i] <01 Number of Node hex> <0A 0B Node Code List hex (Little Endian)>");
PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -h this help");
PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set custom IDm to use"); PrintAndLogEx(NORMAL, " -i <0A 0B 0C ... hex> set custom IDm to use");
PrintAndLogEx(NORMAL, "\nExample: hf felica rqservice 01 FFFF \n\n"); PrintAndLogEx(NORMAL, "\nExamples: hf felica rqservice 01 FF FF");
PrintAndLogEx(NORMAL, " hf felica rqservice 01 FF FF");
PrintAndLogEx(NORMAL, " hf felica rqs -a FF FF");
PrintAndLogEx(NORMAL, " hf felica rqs -i 01 10 09 10 c1 1b c4 07 01 FF FF \n\n");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -150,7 +153,7 @@ static bool is_hex_input(const char *Cmd, int i) {
} }
/** /**
* Add crc bytes to the end of the given data. * Add crc bytes to the end of the given data and increments datalen.
* @param datalen length of the data frame. * @param datalen length of the data frame.
* @param data frame on which the crc is calculated. * @param data frame on which the crc is calculated.
* @param size of the data. * @param size of the data.
@ -242,6 +245,32 @@ static int CmdHFFelicaDump(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
}*/ }*/
/**
* Sends a request service frame to the pm3.
*/
void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data) {
uint16_t numbits = 0;
clearCommandBuffer();
PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen));
SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen);
PacketResponseNG resp;
if (datalen > 0) {
if (!waitCmdFelica(0, &resp)) {
PrintAndLogEx(ERR, "\nGot no Response from card");
return;
}
felica_request_service_response_t rqs_response;
memcpy(&rqs_response, (felica_request_service_response_t *)resp.data.asBytes, sizeof(felica_request_service_response_t));
if (rqs_response.IDm[0] != 0) {
PrintAndLogEx(SUCCESS, "\nGot Service Response:");
PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.IDm, sizeof(rqs_response.IDm)));
PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number)));
PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions)));
}
}
}
/** /**
* Command parser for rqservice. * Command parser for rqservice.
* @param Cmd input data of the user. * @param Cmd input data of the user.
@ -252,9 +281,10 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
int i = 0; int i = 0;
uint8_t data[PM3_CMD_DATA_SIZE]; uint8_t data[PM3_CMD_DATA_SIZE];
bool custom_IDm = false; bool custom_IDm = false;
bool all_nodes = false;
uint16_t datalen = 0; uint16_t datalen = 0;
uint8_t flags = 0; uint8_t flags = 0;
uint16_t numbits = 0;
char buf[5] = ""; char buf[5] = "";
datalen += 10; // length (1) + CMD (1) + IDm(8) datalen += 10; // length (1) + CMD (1) + IDm(8)
strip_cmds(Cmd); strip_cmds(Cmd);
@ -263,12 +293,17 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
switch (Cmd[i + 1]) { switch (Cmd[i + 1]) {
case 'H': case 'H':
case 'h': case 'h':
return usage_hf_felica_raw(); return usage_hf_felica_request_service();
case 'i': case 'i':
custom_IDm = true; custom_IDm = true;
datalen -= 8;
break;
case 'a':
all_nodes = true;
datalen += 1;
break; break;
default: default:
return usage_hf_felica_raw(); return usage_hf_felica_request_service();
} }
i += 2; i += 2;
} }
@ -300,28 +335,18 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
} }
data[0] = int_to_hex(&datalen); data[0] = int_to_hex(&datalen);
data[1] = 0x02; // Request Command ID data[1] = 0x02; // Request Command ID
if (all_nodes) {
for (uint16_t y = 1; y < 32; y++) {
data[10] = int_to_hex(&y);
add_crc_bytes(&datalen, data, sizeof(data)); add_crc_bytes(&datalen, data, sizeof(data));
PrintAndLogEx(NORMAL, "Send Service Request Frame: %s", sprint_hex(data, datalen)); send_request_service(flags, datalen, data);
clearCommandBuffer(); datalen -= 2; // Remove CRC bytes before adding new ones
SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen);
PacketResponseNG resp;
if (custom_IDm) {
waitCmdFelica(1, &resp);
} }
if (datalen > 0) {
if(!waitCmdFelica(0, &resp)){
return PM3_ESOFT;
}
felica_request_service_response_t rqs_response;
memcpy(&rqs_response, (felica_request_service_response_t *)resp.data.asBytes, sizeof(felica_request_service_response_t));
PrintAndLogEx(SUCCESS, "\nGot Service Response:");
PrintAndLogEx(NORMAL, "IDm: %s", sprint_hex(rqs_response.IDm, sizeof(rqs_response.IDm)));
PrintAndLogEx(NORMAL, " -Node Number: %s", sprint_hex(rqs_response.node_number, sizeof(rqs_response.node_number)));
PrintAndLogEx(NORMAL, " -Node Key Version List: %s\n", sprint_hex(rqs_response.node_key_versions, sizeof(rqs_response.node_key_versions)));
} else { } else {
return PM3_ESOFT; add_crc_bytes(&datalen, data, sizeof(data));
send_request_service(flags, datalen, data);
} }
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -15,4 +15,5 @@
int CmdHFFelica(const char *Cmd); int CmdHFFelica(const char *Cmd);
int readFelicaUid(bool verbose); int readFelicaUid(bool verbose);
void send_request_service(uint8_t flags, uint16_t datalen, uint8_t *data);
#endif #endif

View file

@ -170,7 +170,7 @@ typedef struct {
} PACKED felica_card_select_t; } PACKED felica_card_select_t;
typedef struct { typedef struct {
uint8_t sync[4]; uint8_t sync[2];
uint8_t length[1]; uint8_t length[1];
uint8_t cmd_code[1]; uint8_t cmd_code[1];
uint8_t IDm[8]; uint8_t IDm[8];