From b19117b6ab9f6c31c63634e5f9a76259340d860f Mon Sep 17 00:00:00 2001 From: Geonyeob Kim Date: Mon, 27 Dec 2021 00:40:01 +0900 Subject: [PATCH] KS X 6924 - Implement the initialize card function --- client/src/cmdhfksx6924.c | 49 ++++++++++++++++++++++++++++++++ client/src/ksx6924/ksx6924core.c | 35 +++++++++++++++++++++++ client/src/ksx6924/ksx6924core.h | 3 ++ 3 files changed, 87 insertions(+) diff --git a/client/src/cmdhfksx6924.c b/client/src/cmdhfksx6924.c index 69f1c36a8..10ec08e47 100644 --- a/client/src/cmdhfksx6924.c +++ b/client/src/cmdhfksx6924.c @@ -237,6 +237,55 @@ static int CmdHFKSX6924Select(const char *Cmd) { return 0; } +static int CmdHFKSX6924InitializeCard(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf ksx6924 initializecard", + "Perform transaction initialization. (Mpda)\n", + "Usage:\n\thf ksx6924 initializecard 000003e8 -> Mpda\n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("kK", "keep", "keep field ON for next command"), + arg_lit0("aA", "apdu", "show APDU reqests and responses"), + arg_strx1(NULL, NULL, "", NULL), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool leaveSignalON = arg_get_lit(ctx, 1); + bool APDULogging = arg_get_lit(ctx, 2); + uint8_t data[APDU_RES_LEN] = {0}; + int datalen = 0; + CLIGetHexWithReturn(ctx, 3, data, &datalen); + CLIParserFree(ctx); + SetAPDULogging(APDULogging); + + if (datalen != 4) { + PrintAndLogEx(WARNING, "Mpda parameter must be 4 byte long (eg: 000003e8)"); + goto end; + } + + bool ret = KSX6924TrySelect(); + if (!ret) { + goto end; + } + + PrintAndLogEx(NORMAL, "Initialize Card : Mpda -> %02X %02X %02X %02X", data[0], data[1], data[2], data[3]); + uint8_t response[25]; + if (!KSX6924InitializeCard(data[0], data[1], data[2], data[3], response)) { + PrintAndLogEx(FAILED, "Initialize Card Error"); + goto end; + } + + PrintAndLogEx(NORMAL, "Response : %s", sprint_hex(response, sizeof(response))); + +end: + if (!leaveSignalON) { + DropField(); + } + return 0; +} + static int CmdHFKSX6924PRec(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf ksx6924 prec", diff --git a/client/src/ksx6924/ksx6924core.c b/client/src/ksx6924/ksx6924core.c index e0795a8df..1bddf9769 100644 --- a/client/src/ksx6924/ksx6924core.c +++ b/client/src/ksx6924/ksx6924core.c @@ -445,6 +445,41 @@ fail: } +/** + * Perform transaction initialization. + */ +bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result) { + if (result == NULL) { + return false; + } + + uint16_t sw; + size_t result_len; + uint8_t rawResult[1 /* ALGep */ + 1 /* VKep */ + 4 /* BALep */ + 1 /* IDcenter */ + 8 /* IDep */ + 4 /* NTep */ + 4 /* Sign1 */ + 2 /* sw */]; + memset(rawResult, 0, sizeof(rawResult)); + uint8_t data[] = {mpda1, mpda2, mpda3, mpda4}; + int res = FIDOExchange((sAPDU_t) {0x90, 0x02, 0x00, 0x00, 0x04, data}, rawResult, sizeof(rawResult), + &result_len, &sw); + if (res) { + // error communicating + goto fail; + } + + if (sw != 0x9000) { + // card returned error + goto fail; + } + + //*result = ntohl(*(uint32_t*)(rawResult)); + memcpy(result, rawResult, result_len + 2 /* sw */); + return true; + +fail: + *result = 0; + return false; +} + + /** * Issues a proprietary "get record" command (CLA=90, INS=4C). * diff --git a/client/src/ksx6924/ksx6924core.h b/client/src/ksx6924/ksx6924core.h index cd6f5bc0c..700fa90e6 100644 --- a/client/src/ksx6924/ksx6924core.h +++ b/client/src/ksx6924/ksx6924core.h @@ -86,6 +86,9 @@ bool KSX6924TrySelect(void); // selected. 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); + // Proprietary get record command. Function unknown. // result must be 10 bytes long. bool KSX6924ProprietaryGetRecord(