mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
parse the hf ksx6924 init
response
This commit is contained in:
parent
0890884cd5
commit
878d123a78
6 changed files with 155 additions and 59 deletions
|
@ -245,9 +245,9 @@ static int CmdHFKSX6924Select(const char *Cmd) {
|
|||
|
||||
static int CmdHFKSX6924Initialize(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf ksx6924 initialize",
|
||||
"Perform transaction initialization (mpda)",
|
||||
"hf ksx6924 initialize 000003e8 -> mpda\n");
|
||||
CLIParserInit(&ctx, "hf ksx6924 init",
|
||||
"Perform transaction initialization with Mpda (Money of Purchase Transaction)",
|
||||
"hf ksx6924 init 000003e8 -> Mpda\n");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
|
@ -278,15 +278,23 @@ static int CmdHFKSX6924Initialize(const char *Cmd) {
|
|||
goto end;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Initialize Card : Mpda -> %02X %02X %02X %02X", data[0], data[1], data[2], data[3]);
|
||||
|
||||
uint8_t response[25] = {0};
|
||||
if (KSX6924InitializeCard(data[0], data[1], data[2], data[3], response)) {
|
||||
PrintAndLogEx(SUCCESS, "Response : %s", sprint_hex(response, sizeof(response)));
|
||||
} else {
|
||||
PrintAndLogEx(FAILED, "Initialize Card Error");
|
||||
uint8_t resp[APDU_RES_LEN] = {0};
|
||||
size_t resp_len = 0;
|
||||
if (KSX6924InitializeCard(data[0], data[1], data[2], data[3], resp, &resp_len) == false) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
uint8_t *r = resp;
|
||||
struct ksx6924_initialize_card_response initCardResponse;
|
||||
bool ret = KSX6924ParseInitializeCardResponse(r, resp_len, &initCardResponse);
|
||||
|
||||
if (!ret) {
|
||||
PrintAndLogEx(FAILED, "Error parsing KS X 6924 initialize card response");
|
||||
goto end;
|
||||
}
|
||||
|
||||
KSX6924PrintInitializeCardResponse(&initCardResponse);
|
||||
|
||||
end:
|
||||
if (keep == false) {
|
||||
DropField();
|
||||
|
@ -348,11 +356,11 @@ end:
|
|||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"balance", CmdHFKSX6924Balance, IfPm3Iso14443a, "Get current purse balance"},
|
||||
{"info", CmdHFKSX6924Info, IfPm3Iso14443a, "Get info about a KS X 6924 (T-Money, Snapper+) transit card"},
|
||||
{"initialize", CmdHFKSX6924Initialize, IfPm3Iso14443a, "Perform transaction initialization (Mpda)"},
|
||||
{"prec", CmdHFKSX6924PRec, IfPm3Iso14443a, "Send proprietary get record command (CLA=90, INS=4C)"},
|
||||
{"select", CmdHFKSX6924Select, IfPm3Iso14443a, "Select application, and leave field up"},
|
||||
{"info", CmdHFKSX6924Info, IfPm3Iso14443a, "Get info about a KS X 6924 (T-Money, Snapper+) transit card"},
|
||||
{"balance", CmdHFKSX6924Balance, IfPm3Iso14443a, "Get current purse balance"},
|
||||
{"init", CmdHFKSX6924Initialize, IfPm3Iso14443a, "Perform transaction initialization with Mpda"},
|
||||
{"prec", CmdHFKSX6924PRec, IfPm3Iso14443a, "Send proprietary get record command (CLA=90, INS=4C)"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -66,6 +66,16 @@ typedef struct {
|
|||
uint8_t rfu[8];
|
||||
} PACKED _ksx6924_internal_purse_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t ALGep;
|
||||
uint8_t VKep;
|
||||
uint8_t BALep[4]; // uint32_t big-endian
|
||||
uint8_t IDcenter;
|
||||
uint8_t IDep[8]; // bcd
|
||||
uint8_t NTep[4];
|
||||
uint8_t Sign1[4];
|
||||
} PACKED _ksx6924_initialize_card_response_t;
|
||||
|
||||
// Declares a structure for simple enums.
|
||||
#define MAKE_ENUM_TYPE(KEY_TYPE) \
|
||||
struct _ksx6924_enum_ ## KEY_TYPE { \
|
||||
|
@ -446,7 +456,7 @@ bool KSX6924GetBalance(uint32_t *result) {
|
|||
/**
|
||||
* Perform transaction initialization.
|
||||
*/
|
||||
bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result) {
|
||||
bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result, size_t *result_len) {
|
||||
|
||||
if (result == NULL) {
|
||||
return false;
|
||||
|
@ -472,9 +482,68 @@ bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t
|
|||
|
||||
//*result = ntohl(*(uint32_t*)(arr));
|
||||
memcpy(result, arr, rlen + 2); // skip 2 sw bytes
|
||||
memcpy(result_len, &rlen, sizeof(size_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Initialize Card response
|
||||
*/
|
||||
bool KSX6924ParseInitializeCardResponse(const uint8_t *initCardResponse, size_t resp_len, struct ksx6924_initialize_card_response *ret) {
|
||||
|
||||
memset(ret, 0, sizeof(struct ksx6924_initialize_card_response));
|
||||
|
||||
if (resp_len != sizeof(_ksx6924_initialize_card_response_t)) {
|
||||
// Invalid size!
|
||||
PrintAndLogEx(FAILED, "Expected %ld bytes, got %ld\n", sizeof(_ksx6924_initialize_card_response_t), resp_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
const _ksx6924_initialize_card_response_t *internalInitCardResponse = (const _ksx6924_initialize_card_response_t *)initCardResponse;
|
||||
|
||||
// Simple copies
|
||||
ret->ALGep = internalInitCardResponse->ALGep;
|
||||
ret->VKep = internalInitCardResponse->VKep;
|
||||
ret->IDcenter = internalInitCardResponse->IDcenter;
|
||||
|
||||
// Fields that need rewriting
|
||||
hex_to_buffer(ret->IDep, internalInitCardResponse->IDep,
|
||||
sizeof(internalInitCardResponse->IDep),
|
||||
sizeof(ret->IDep) - 1,
|
||||
0, // min_str_len
|
||||
0, // spaces_between
|
||||
false // uppercase
|
||||
);
|
||||
|
||||
ret->BALep = MemBeToUint4byte((uint8_t *)internalInitCardResponse->BALep);
|
||||
ret->NTep = MemBeToUint4byte((uint8_t *)internalInitCardResponse->NTep);
|
||||
|
||||
memcpy(&ret->Sign1, &internalInitCardResponse->Sign1, 4);
|
||||
|
||||
// TODO
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prints out a Initialize Card response
|
||||
*/
|
||||
void KSX6924PrintInitializeCardResponse(const struct ksx6924_initialize_card_response *response) {
|
||||
|
||||
if (response == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("KS X 6924 Initialize Card Response") " ---------------------------");
|
||||
PrintAndLogEx(INFO, "");
|
||||
PrintAndLogEx(INFO, " ALGep (Algorithm Identifier)........ %02x ( %s )", response->ALGep, KSX6924LookupAlg(response->ALGep, KSX6924_UNKNOWN));
|
||||
PrintAndLogEx(INFO, " VKep (Version of Key) .............. %02x", response->VKep);
|
||||
PrintAndLogEx(INFO, " BALep (Balance...................... %" PRIu32, response->BALep);
|
||||
PrintAndLogEx(INFO, " IDcenter (Issuer ID) ............... %02x ( %s )", response->IDcenter, KSX6924LookupTMoneyIDCenter(response->IDcenter, KSX6924_UNKNOWN));
|
||||
PrintAndLogEx(INFO, " IDep (Card number) ................. %s", response->IDep);
|
||||
PrintAndLogEx(INFO, " NTep (Number of Transaction + 1) ... %" PRIu32, response->NTep);
|
||||
PrintAndLogEx(INFO, " Sign1 .............................. %s", sprint_hex(response->Sign1, sizeof(response->Sign1)));
|
||||
PrintAndLogEx(INFO, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a proprietary "get record" command (CLA=90, INS=4C).
|
||||
|
|
|
@ -53,6 +53,18 @@ struct ksx6924_purse_info {
|
|||
uint8_t rfu[8];
|
||||
};
|
||||
|
||||
// Convenience structure for representing purse information. Actual on-card
|
||||
// format is in _ksx6924_initialize_card_response_t.
|
||||
struct ksx6924_initialize_card_response {
|
||||
uint8_t ALGep;
|
||||
uint8_t VKep;
|
||||
uint32_t BALep;
|
||||
uint8_t IDcenter;
|
||||
uint8_t IDep[17]; // hex digits + null terminator
|
||||
uint32_t NTep;
|
||||
uint8_t Sign1[4];
|
||||
};
|
||||
|
||||
// Get card type description
|
||||
const char *KSX6924LookupCardType(uint8_t key, const char *defaultValue);
|
||||
|
||||
|
@ -94,7 +106,13 @@ bool KSX6924TrySelect(void);
|
|||
bool KSX6924GetBalance(uint32_t *result);
|
||||
|
||||
// Perform transaction initialization.
|
||||
bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result);
|
||||
bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result, size_t *result_len);
|
||||
|
||||
// Parses Initialize Card response
|
||||
bool KSX6924ParseInitializeCardResponse(const uint8_t *initCardResponse, size_t resp_len, struct ksx6924_initialize_card_response *ret);
|
||||
|
||||
// Prints out a Initialize Card response
|
||||
void KSX6924PrintInitializeCardResponse(const struct ksx6924_initialize_card_response *response);
|
||||
|
||||
// Proprietary get record command. Function unknown.
|
||||
// result must be 10 bytes long.
|
||||
|
|
|
@ -244,11 +244,11 @@ const static vocabulory_t vocabulory[] = {
|
|||
{ 1, "hf gallagher diversifykey" },
|
||||
{ 1, "hf gallagher decode" },
|
||||
{ 1, "hf ksx6924 help" },
|
||||
{ 0, "hf ksx6924 balance" },
|
||||
{ 0, "hf ksx6924 info" },
|
||||
{ 0, "hf ksx6924 initialize" },
|
||||
{ 0, "hf ksx6924 prec" },
|
||||
{ 0, "hf ksx6924 select" },
|
||||
{ 0, "hf ksx6924 info" },
|
||||
{ 0, "hf ksx6924 balance" },
|
||||
{ 0, "hf ksx6924 init" },
|
||||
{ 0, "hf ksx6924 prec" },
|
||||
{ 1, "hf jooki help" },
|
||||
{ 0, "hf jooki clone" },
|
||||
{ 1, "hf jooki decode" },
|
||||
|
|
|
@ -3390,20 +3390,6 @@
|
|||
],
|
||||
"usage": "hf jooki sim [-h] [-b <base64>]"
|
||||
},
|
||||
"hf ksx6924 balance": {
|
||||
"command": "hf ksx6924 balance",
|
||||
"description": "Gets the current purse balance",
|
||||
"notes": [
|
||||
"hf ksx6924 balance"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-k, --keep keep field ON for next command",
|
||||
"-a, --apdu show APDU reqests and responses"
|
||||
],
|
||||
"usage": "hf ksx6924 balance [-hka]"
|
||||
},
|
||||
"hf ksx6924 help": {
|
||||
"command": "hf ksx6924 help",
|
||||
"description": "help This help",
|
||||
|
@ -3412,6 +3398,19 @@
|
|||
"options": [],
|
||||
"usage": ""
|
||||
},
|
||||
"hf ksx6924 select": {
|
||||
"command": "hf ksx6924 select",
|
||||
"description": "Selects KS X 6924 application, and leaves field up",
|
||||
"notes": [
|
||||
"hf ksx6924 select"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-a, --apdu Show APDU requests and responses"
|
||||
],
|
||||
"usage": "hf ksx6924 select [-ha]"
|
||||
},
|
||||
"hf ksx6924 info": {
|
||||
"command": "hf ksx6924 info",
|
||||
"description": "Get info about a KS X 6924 transit card. This application is used by T-Money (South Korea) and Snapper+ (Wellington, New Zealand).",
|
||||
|
@ -3422,23 +3421,37 @@
|
|||
"options": [
|
||||
"-h, --help This help",
|
||||
"-k, --keep keep field ON for next command",
|
||||
"-a, --apdu show APDU reqests and responses"
|
||||
"-a, --apdu Show APDU requests and responses"
|
||||
],
|
||||
"usage": "hf ksx6924 info [-hka]"
|
||||
},
|
||||
"hf ksx6924 initialize": {
|
||||
"command": "hf ksx6924 initialize",
|
||||
"description": "Perform transaction initialization (mpda)",
|
||||
"hf ksx6924 balance": {
|
||||
"command": "hf ksx6924 balance",
|
||||
"description": "Gets the current purse balance",
|
||||
"notes": [
|
||||
"hf ksx6924 initialize 000003e8 -> mpda"
|
||||
"hf ksx6924 balance"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-k, --keep keep field ON for next command",
|
||||
"-a, --apdu show APDU reqests and responses"
|
||||
"-a, --apdu Show APDU requests and responses"
|
||||
],
|
||||
"usage": "hf ksx6924 initialize [-hka] <mpda 4byte hex>"
|
||||
"usage": "hf ksx6924 balance [-hka]"
|
||||
},
|
||||
"hf ksx6924 init": {
|
||||
"command": "hf ksx6924 init",
|
||||
"description": "Perform transaction initialization (mpda)",
|
||||
"notes": [
|
||||
"hf ksx6924 init 000003e8 -> Mpda"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-k, --keep keep field ON for next command",
|
||||
"-a, --apdu Show APDU requests and responses"
|
||||
],
|
||||
"usage": "hf ksx6924 init [-hka] <Mpda 4 bytes hex>"
|
||||
},
|
||||
"hf ksx6924 prec": {
|
||||
"command": "hf ksx6924 prec",
|
||||
|
@ -3450,23 +3463,11 @@
|
|||
"options": [
|
||||
"-h, --help This help",
|
||||
"-k, --keep keep field ON for next command",
|
||||
"-a, --apdu show APDU reqests and responses"
|
||||
"-a, --apdu Show APDU requests and responses"
|
||||
],
|
||||
"usage": "hf ksx6924 prec [-hka] <record 1byte HEX>"
|
||||
},
|
||||
"hf ksx6924 select": {
|
||||
"command": "hf ksx6924 select",
|
||||
"description": "Selects KS X 6924 application, and leaves field up",
|
||||
"notes": [
|
||||
"hf ksx6924 select"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-a, --apdu show APDU reqests and responses"
|
||||
],
|
||||
"usage": "hf ksx6924 select [-ha]"
|
||||
},
|
||||
|
||||
"hf legic crc": {
|
||||
"command": "hf legic crc",
|
||||
"description": "Calculates the legic crc8/crc16 on the given data",
|
||||
|
|
|
@ -367,11 +367,11 @@ Check column "offline" for their availability.
|
|||
|command |offline |description
|
||||
|------- |------- |-----------
|
||||
|`hf ksx6924 help `|Y |`This help`
|
||||
|`hf ksx6924 balance `|N |`Get current purse balance`
|
||||
|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card`
|
||||
|`hf ksx6924 initialize `|N |`Perform transaction initialization (Mpda)`
|
||||
|`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)`
|
||||
|`hf ksx6924 select `|N |`Select application, and leave field up`
|
||||
|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card`
|
||||
|`hf ksx6924 balance `|N |`Get current purse balance`
|
||||
|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda (Money of Purchase Transaction)`
|
||||
|`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)`
|
||||
|
||||
|
||||
### hf jooki
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue