mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge pull request #1549 from toucan12/ksx6924
For testing KS X 6924 (South Korea's T-money card)
This commit is contained in:
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added support for KS X 6924 (South Korea's T-money card) (@toucan12)
|
||||
- Fixed `hf 15 dump` - now correctly dumps 256 blocks w/o crashing the client (@iceman1001)
|
||||
- Changed `hf 14a sim -t 3` - anticollision for DESFire simulation now uses different RATS (@mosci)
|
||||
- Fixed `hf mfdes` - works with dynamic apdu and encode/decode buffers (@merlokk)
|
||||
|
||||
@@ -213,6 +213,7 @@ set (TARGET_SOURCES
|
||||
${PM3_ROOT}/client/src/fido/fidocore.c
|
||||
${PM3_ROOT}/client/src/iso7816/apduinfo.c
|
||||
${PM3_ROOT}/client/src/iso7816/iso7816core.c
|
||||
${PM3_ROOT}/client/src/ksx6924/ksx6924core.c
|
||||
${PM3_ROOT}/client/src/cipurse/cipursecrypto.c
|
||||
${PM3_ROOT}/client/src/cipurse/cipursecore.c
|
||||
${PM3_ROOT}/client/src/cipurse/cipursetest.c
|
||||
@@ -256,6 +257,7 @@ set (TARGET_SOURCES
|
||||
${PM3_ROOT}/client/src/cmdhfcipurse.c
|
||||
${PM3_ROOT}/client/src/cmdhficlass.c
|
||||
${PM3_ROOT}/client/src/cmdhfjooki.c
|
||||
${PM3_ROOT}/client/src/cmdhfksx6924.c
|
||||
${PM3_ROOT}/client/src/cmdhflegic.c
|
||||
${PM3_ROOT}/client/src/cmdhflist.c
|
||||
${PM3_ROOT}/client/src/cmdhflto.c
|
||||
|
||||
@@ -76,6 +76,7 @@ LUALIBLD =
|
||||
LUAPLATFORM = generic
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
LUAPLATFORM = mingw
|
||||
LDLIBS += -lws2_32
|
||||
else
|
||||
ifeq ($(platform),Darwin)
|
||||
LUAPLATFORM = macosx
|
||||
@@ -505,6 +506,7 @@ SRCS = mifare/aiddesfire.c \
|
||||
cmdhfemrtd.c \
|
||||
cmdhffelica.c \
|
||||
cmdhffido.c \
|
||||
cmdhfksx6924.c \
|
||||
cmdhfcipurse.c \
|
||||
cmdhficlass.c \
|
||||
cmdhflegic.c \
|
||||
@@ -590,6 +592,7 @@ SRCS = mifare/aiddesfire.c \
|
||||
fido/cose.c \
|
||||
fido/cbortools.c \
|
||||
fido/fidocore.c \
|
||||
ksx6924/ksx6924core.c \
|
||||
cipurse/cipursecore.c \
|
||||
cipurse/cipursecrypto.c \
|
||||
cipurse/cipursetest.c \
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "cmdhftopaz.h" // TOPAZ
|
||||
#include "cmdhffelica.h" // ISO18092 / FeliCa
|
||||
#include "cmdhffido.h" // FIDO authenticators
|
||||
#include "cmdhfksx6924.h" // KS X 6924
|
||||
#include "cmdhfcipurse.h" // CIPURSE transport cards
|
||||
#include "cmdhfthinfilm.h" // Thinfilm
|
||||
#include "cmdhflto.h" // LTO-CM
|
||||
@@ -413,6 +414,7 @@ static command_t CommandTable[] = {
|
||||
{"emrtd", CmdHFeMRTD, AlwaysAvailable, "{ Machine Readable Travel Document... }"},
|
||||
{"felica", CmdHFFelica, AlwaysAvailable, "{ ISO18092 / FeliCa RFIDs... }"},
|
||||
{"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"},
|
||||
{"ksx6924", CmdHFKSX6924, AlwaysAvailable, "{ KS X 6924 (T-Money, Snapper+) RFIDs }"},
|
||||
{"jooki", CmdHF_Jooki, AlwaysAvailable, "{ Jooki RFIDs... }"},
|
||||
{"iclass", CmdHFiClass, AlwaysAvailable, "{ ICLASS RFIDs... }"},
|
||||
{"legic", CmdHFLegic, AlwaysAvailable, "{ LEGIC RFIDs... }"},
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
// -*- mode: c; indent-tabs-mode: nil; tab-width: 3 -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2019 micolous+git@gmail.com
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Commands for KS X 6924 transit cards (T-Money, Snapper+)
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is used in T-Money (South Korea) and Snapper plus (Wellington, New
|
||||
// Zealand).
|
||||
//
|
||||
// References:
|
||||
// - https://github.com/micolous/metrodroid/wiki/T-Money (in English)
|
||||
// - https://github.com/micolous/metrodroid/wiki/Snapper (in English)
|
||||
// - https://kssn.net/StdKS/ks_detail.asp?k1=X&k2=6924-1&k3=4
|
||||
// (KS X 6924, only available in Korean)
|
||||
// - http://www.tta.or.kr/include/Download.jsp?filename=stnfile/TTAK.KO-12.0240_%5B2%5D.pdf
|
||||
// (TTAK.KO 12.0240, only available in Korean)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "cmdhfksx6924.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include "comms.h"
|
||||
#include "cmdmain.h"
|
||||
#include "util.h"
|
||||
#include "ui.h"
|
||||
#include "proxmark3.h"
|
||||
#include "cliparser.h"
|
||||
#include "ksx6924/ksx6924core.h"
|
||||
#include "emv/tlv.h"
|
||||
#include "iso7816/apduinfo.h"
|
||||
#include "cmdhf14a.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static void getAndPrintBalance(void) {
|
||||
uint32_t balance;
|
||||
bool ret = KSX6924GetBalance(&balance);
|
||||
if (!ret) {
|
||||
PrintAndLogEx(ERR, "Error getting balance");
|
||||
return;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Current balance: %ld won/cents", balance);
|
||||
}
|
||||
|
||||
static int CmdHFKSX6924Balance(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf ksx6924 balance",
|
||||
"Gets the current purse balance.\n",
|
||||
"Usage:\n\thf ksx6924 balance\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_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(ctx, 1);
|
||||
bool APDULogging = arg_get_lit(ctx, 2);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
bool ret = KSX6924TrySelect();
|
||||
if (!ret) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
getAndPrintBalance();
|
||||
|
||||
end:
|
||||
if (!leaveSignalON) {
|
||||
DropField();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdHFKSX6924Info(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf ksx6924 info",
|
||||
"Get info about a KS X 6924 transit card.\nThis application is used by T-Money (South Korea) and Snapper+ (Wellington, New Zealand).\n",
|
||||
"Usage:\n\thf ksx6924 info\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_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool leaveSignalON = arg_get_lit(ctx, 1);
|
||||
bool APDULogging = arg_get_lit(ctx, 2);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
// KSX6924 info
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
uint16_t sw = 0;
|
||||
int res = KSX6924Select(true, true, buf, sizeof(buf), &len, &sw);
|
||||
|
||||
if (res) {
|
||||
if (!leaveSignalON) {
|
||||
DropField();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
if (sw != 0x9000) {
|
||||
if (sw) {
|
||||
PrintAndLogEx(INFO, "Not a KS X 6924 card! APDU response: %04x - %s",
|
||||
sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "APDU exchange error. Card returns 0x0000.");
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
// PrintAndLogEx(DEBUG, "APDU response: %s", sprint_hex(buf, len));
|
||||
|
||||
// FCI Response is a BER-TLV, we are interested in tag 6F,B0 only.
|
||||
const uint8_t *p = buf;
|
||||
struct tlv fci_tag;
|
||||
|
||||
while (len > 0) {
|
||||
memset(&fci_tag, 0, sizeof(fci_tag));
|
||||
bool ret = tlv_parse_tl(&p, &len, &fci_tag);
|
||||
|
||||
if (!ret) {
|
||||
PrintAndLogEx(FAILED, "Error parsing FCI!");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// PrintAndLog("tag %02x, len %d, value %s",
|
||||
// fci_tag.tag, fci_tag.len,
|
||||
// sprint_hex(p, fci_tag.len));
|
||||
|
||||
if (fci_tag.tag == 0x6f) { /* FCI template */
|
||||
break;
|
||||
} else {
|
||||
p += fci_tag.len;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (fci_tag.tag != 0x6f) {
|
||||
PrintAndLogEx(ERR, "Couldn't find tag 6F (FCI) in SELECT response");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// We now are at Tag 6F (FCI template), get Tag B0 inside of it
|
||||
while (len > 0) {
|
||||
memset(&fci_tag, 0, sizeof(fci_tag));
|
||||
bool ret = tlv_parse_tl(&p, &len, &fci_tag);
|
||||
|
||||
if (!ret) {
|
||||
PrintAndLogEx(ERR, "Error parsing FCI!");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// PrintAndLog("tag %02x, len %d, value %s",
|
||||
// fci_tag.tag, fci_tag.len,
|
||||
// sprint_hex(p, fci_tag.len));
|
||||
|
||||
if (fci_tag.tag == 0xb0) { /* KS X 6924 purse info */
|
||||
break;
|
||||
} else {
|
||||
p += fci_tag.len;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (fci_tag.tag != 0xb0) {
|
||||
PrintAndLogEx(FAILED, "Couldn't find tag B0 (KS X 6924 purse info) in FCI");
|
||||
goto end;
|
||||
}
|
||||
|
||||
struct ksx6924_purse_info purseInfo;
|
||||
bool ret = KSX6924ParsePurseInfo(p, fci_tag.len, &purseInfo);
|
||||
|
||||
if (!ret) {
|
||||
PrintAndLogEx(FAILED, "Error parsing KS X 6924 purse info");
|
||||
goto end;
|
||||
}
|
||||
|
||||
KSX6924PrintPurseInfo(&purseInfo);
|
||||
|
||||
getAndPrintBalance();
|
||||
|
||||
end:
|
||||
if (!leaveSignalON) {
|
||||
DropField();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdHFKSX6924Select(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf ksx6924 select",
|
||||
"Selects KS X 6924 application, and leaves field up.\n",
|
||||
"Usage:\n\thf ksx6924 select\n");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
bool APDULogging = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
SetAPDULogging(APDULogging);
|
||||
|
||||
bool ret = KSX6924TrySelect();
|
||||
if (ret) {
|
||||
PrintAndLogEx(SUCCESS, "OK");
|
||||
} else {
|
||||
// Wrong app, drop field.
|
||||
DropField();
|
||||
}
|
||||
|
||||
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, "<Mpda 4byte hex>", 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",
|
||||
"Executes proprietary read record command.\nData format is unknown. Other records are available with 'emv getrec'.\n",
|
||||
"Usage:\n\thf ksx6924 prec 0b -> read proprietary record 0x0b\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, "<record 1byte HEX>", 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 != 1) {
|
||||
PrintAndLogEx(WARNING, "Record parameter must be 1 byte long (eg: 0f)");
|
||||
goto end;
|
||||
}
|
||||
|
||||
bool ret = KSX6924TrySelect();
|
||||
if (!ret) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "Getting record %02x...", data[0]);
|
||||
uint8_t recordData[0x10];
|
||||
if (!KSX6924ProprietaryGetRecord(data[0], recordData, sizeof(recordData))) {
|
||||
PrintAndLogEx(FAILED, "Error getting record");
|
||||
goto end;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " %s", sprint_hex(recordData, sizeof(recordData)));
|
||||
|
||||
end:
|
||||
if (!leaveSignalON) {
|
||||
DropField();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help."},
|
||||
{"info", CmdHFKSX6924Info, AlwaysAvailable, "Get info about a KS X 6924 (T-Money, Snapper+) transit card"},
|
||||
{"select", CmdHFKSX6924Select, AlwaysAvailable, "Select application, and leave field up"},
|
||||
{"balance", CmdHFKSX6924Balance, AlwaysAvailable, "Get current purse balance"},
|
||||
{"initializecard", CmdHFKSX6924InitializeCard, AlwaysAvailable, "Perform transaction initialization (Mpda)"},
|
||||
{"prec", CmdHFKSX6924PRec, AlwaysAvailable, "Send proprietary get record command (CLA=90, INS=4C)"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
int CmdHFKSX6924(const char *Cmd) {
|
||||
(void)WaitForResponseTimeout(CMD_ACK, NULL, 100);
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// -*- mode: c; indent-tabs-mode: nil; tab-width: 3 -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2019 micolous+git@gmail.com
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Commands for KS X 6924 transit cards (T-Money, Snapper+)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef CMDHFKSX6924_H__
|
||||
#define CMDHFKSX6924_H__
|
||||
|
||||
int CmdHFKSX6924(const char *Cmd);
|
||||
|
||||
#endif /* CMDHFKSX6924_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,98 @@
|
||||
// -*- mode: c; indent-tabs-mode: nil; tab-width: 3 -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2019 micolous+git@gmail.com
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// KS X 6924 (T-Money, Snapper+) protocol implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __KSX6924CORE_H__
|
||||
#define __KSX6924CORE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "cmdhf14a.h"
|
||||
#include "emv/emvcore.h"
|
||||
|
||||
// Convenience structure for representing a date. Actual on-card format is in
|
||||
// _ksx6924_internal_date_t.
|
||||
struct ksx6924_date {
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
};
|
||||
|
||||
// Convenience structure for representing purse information. Actual on-card
|
||||
// format is in _ksx6924_internal_purse_info_t.
|
||||
struct ksx6924_purse_info {
|
||||
uint8_t cardType;
|
||||
uint8_t alg;
|
||||
uint8_t vk;
|
||||
uint8_t idCenter;
|
||||
uint8_t csn[17]; // hex digits + null terminator
|
||||
uint64_t idtr;
|
||||
struct ksx6924_date issueDate;
|
||||
struct ksx6924_date expiryDate;
|
||||
uint8_t userCode;
|
||||
uint8_t disRate;
|
||||
uint32_t balMax;
|
||||
uint16_t bra;
|
||||
uint32_t mmax;
|
||||
uint8_t tcode;
|
||||
uint8_t ccode;
|
||||
uint8_t rfu[8];
|
||||
};
|
||||
|
||||
// Get card type description
|
||||
const char *KSX6924LookupCardType(uint8_t key, const char *defaultValue);
|
||||
|
||||
// Get encryption algorithm description
|
||||
const char *KSX6924LookupAlg(uint8_t key, const char *defaultValue);
|
||||
|
||||
// Get IDCenter (issuer ID) description
|
||||
const char *KSX6924LookupTMoneyIDCenter(uint8_t key, const char *defaultValue);
|
||||
|
||||
// Get UserCode (ticket type) description
|
||||
const char *KSX6924LookupTMoneyUserCode(uint8_t key, const char *defaultValue);
|
||||
|
||||
// Get DisRate (discount type) description
|
||||
const char *KSX6924LookupTMoneyDisRate(uint8_t key, const char *defaultValue);
|
||||
|
||||
// Get TCode (telecom carrier ID) description
|
||||
const char *KSX6924LookupTMoneyTCode(uint8_t key, const char *defaultValue);
|
||||
|
||||
// Get CCode (credit card company ID) description
|
||||
const char *KSX6924LookupTMoneyCCode(uint8_t key, const char *defaultValue);
|
||||
|
||||
// Parses purse info in FCI tag b0
|
||||
bool KSX6924ParsePurseInfo(
|
||||
const uint8_t *purseInfo, size_t purseLen, struct ksx6924_purse_info *ret);
|
||||
|
||||
// Prints out a ksx6924_purse_info
|
||||
void KSX6924PrintPurseInfo(const struct ksx6924_purse_info *purseInfo);
|
||||
|
||||
// Selects the KS X 6924 application, returns all information
|
||||
int KSX6924Select(
|
||||
bool ActivateField, bool LeaveFieldON,
|
||||
uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
|
||||
|
||||
// Selects the KS X 6924 application, returns true on success
|
||||
bool KSX6924TrySelect(void);
|
||||
|
||||
// Gets the balance from a KS X 6924 card. Application must be already
|
||||
// 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(
|
||||
uint8_t id, uint8_t *result, size_t resultLen);
|
||||
|
||||
#endif /* __KSX6924CORE_H__ */
|
||||
|
||||
Reference in New Issue
Block a user