mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
appears to work - using normal mifare sim init
working demo works seems to work so far more cleanup and works working copy working, clean one more pass cleanup continues back in buisness babyyy final cleanup before PR I hope
This commit is contained in:
+317
-420
File diff suppressed because it is too large
Load Diff
@@ -25,5 +25,6 @@
|
||||
#define AUTHKEYNONE 0xff
|
||||
|
||||
void EMVsim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint16_t atqa, uint8_t sak);
|
||||
void annotate(uint8_t *cmd, uint8_t cmdsize);
|
||||
|
||||
#endif
|
||||
|
||||
+6
-172
@@ -36,11 +36,6 @@
|
||||
#include "i2c.h"
|
||||
#include "i2c_direct.h"
|
||||
|
||||
static uint8_t fci_template[] = {0x02, 0x6f, 0x5e, 0x84, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0xa5, 0x53, 0x50, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x9f, 0x38, 0x18, 0x9f, 0x66, 0x04, 0x9f, 0x02, 0x06, 0x9f, 0x03, 0x06, 0x9f, 0x1a, 0x02, 0x95, 0x05, 0x5f, 0x2a, 0x02, 0x9a, 0x03, 0x9c, 0x01, 0x9f, 0x37, 0x04, 0x5f, 0x2d, 0x02, 0x65, 0x6e, 0x9f, 0x11, 0x01, 0x01, 0x9f, 0x12, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0xbf, 0x0c, 0x13, 0x9f, 0x5a, 0x05, 0x31, 0x08, 0x26, 0x08, 0x26, 0x9f, 0x0a, 0x08, 0x00, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0xd8, 0x15};
|
||||
|
||||
static uint8_t pay1_response[] = { 0x6F, 0x1E, 0x84, 0x0E, 0x31, 0x50, 0x41, 0x59 };
|
||||
static uint8_t pay2_response[] = { 0x03, 0x6f, 0x3e, 0x84, 0x0e, 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, 0xa5, 0x2c, 0xbf, 0x0c, 0x29, 0x61, 0x27, 0x4f, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0x50, 0x0a, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x9f, 0x0a, 0x08, 0x00, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x63, 0x04, 0xdf, 0x20, 0x01, 0x80, 0x90, 0x00, 0x07, 0x9d};
|
||||
|
||||
static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint8_t *output, uint16_t *olen) {
|
||||
LED_D_ON();
|
||||
|
||||
@@ -50,9 +45,6 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
// check if alloacted...
|
||||
smartcard_command_t flags = p->flags;
|
||||
|
||||
//if ((flags & SC_CLEARLOG) == SC_CLEARLOG)
|
||||
//clear_trace();
|
||||
|
||||
if ((flags & SC_LOG) == SC_LOG)
|
||||
set_tracing(true);
|
||||
else
|
||||
@@ -65,10 +57,9 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
if ((flags & SC_SELECT) == SC_SELECT) {
|
||||
smart_card_atr_t card;
|
||||
bool gotATR = GetATR(&card, true);
|
||||
//reply_old(CMD_ACK, gotATR, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
|
||||
|
||||
if (gotATR == false) {
|
||||
Dbprintf("No ATR received...\n");
|
||||
//reply_ng(CMD_SMART_RAW, PM3_ESOFT, NULL, 0);
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
@@ -92,8 +83,6 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
);
|
||||
|
||||
if (res == false && g_dbglevel > 3) {
|
||||
//DbpString(I2C_ERROR);
|
||||
//reply_ng(CMD_SMART_RAW, PM3_ESOFT, NULL, 0);
|
||||
Dbprintf("SmartCardDirectSend: I2C_BufferWrite failed\n");
|
||||
goto OUT;
|
||||
}
|
||||
@@ -109,11 +98,8 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
}
|
||||
|
||||
if (len == 2 && resp[1] == 0x61) {
|
||||
//Dbprintf("Data to be read: len = %d\n", len);
|
||||
//Dbprintf("\n");
|
||||
|
||||
uint8_t cmd_getresp[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, resp[2]};
|
||||
//smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
|
||||
|
||||
smart_card_raw_t *payload = (smart_card_raw_t *)BigBuf_calloc(sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
|
||||
payload->flags = SC_RAW | SC_LOG;
|
||||
payload->len = sizeof(cmd_getresp);
|
||||
@@ -129,8 +115,6 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
resp[2] = 0x82;
|
||||
AddCrc14A(resp, 3);
|
||||
|
||||
//Dbhexdump(5, &resp[0], false); // special print
|
||||
//EmSendCmd(&resp[0], 5);
|
||||
memcpy(output, resp, 5);
|
||||
*olen = 5;
|
||||
}
|
||||
@@ -142,9 +126,6 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
resp[2] = 0x82;
|
||||
AddCrc14A(resp, 3);
|
||||
|
||||
//Dbhexdump(5, &resp[0], false); // special print
|
||||
//EmSendCmd14443aRaw(&resp[0], 5);
|
||||
//EmSendCmd(&resp[0], 5);
|
||||
memcpy(output, resp, 5);
|
||||
*olen = 5;
|
||||
FpgaDisableTracing();
|
||||
@@ -154,108 +135,23 @@ static void SmartCardDirectSend(uint8_t prepend, const smart_card_raw_t *p, uint
|
||||
Dbprintf("***** sending it over the wire... len: %d =>\n", len);
|
||||
resp[1] = prepend;
|
||||
|
||||
// if we have a generate AC request, lets extract the data and populate the template
|
||||
if (resp[1] != 0xff && resp[2] == 0x77) {
|
||||
Dbprintf("we have detected a generate ac response, lets repackage it!");
|
||||
Dbhexdump(len, &resp[1], false); // special print
|
||||
// 11 and 12 are trans counter.
|
||||
// 16 to 24 are the cryptogram
|
||||
// 27 to 34 is issuer application data
|
||||
Dbprintf("atc: %d %d, cryptogram: %d ", resp[11], resp[12], resp[13]);
|
||||
|
||||
// then, on the template:
|
||||
// 61 and 62 for counter
|
||||
// 46 to 54 for cryptogram
|
||||
// 36 to 43 for issuer application data
|
||||
|
||||
uint8_t template[] = { 0x00, 0x00, 0x77, 0x47, 0x82, 0x02, 0x39, 0x00, 0x57, 0x13, 0x47, 0x62, 0x28, 0x00, 0x05, 0x93, 0x38, 0x64, 0xd2, 0x70, 0x92, 0x01, 0x00, 0x00, 0x01, 0x42, 0x00, 0x00, 0x0f, 0x5f, 0x34, 0x01, 0x00, 0x9f, 0x10, 0x07, 0x06, 0x01, 0x12, 0x03, 0xa0, 0x20, 0x00, 0x9f, 0x26, 0x08, 0x56, 0xcb, 0x4e, 0xe1, 0xa4, 0xef, 0xac, 0x74, 0x9f, 0x27, 0x01, 0x80, 0x9f, 0x36, 0x02, 0x00, 0x07, 0x9f, 0x6c, 0x02, 0x3e, 0x00, 0x9f, 0x6e, 0x04, 0x20, 0x70, 0x00, 0x00, 0x90, 0x00, 0xff, 0xff};
|
||||
|
||||
// do the replacement
|
||||
template[1] = resp[1]; // class bit
|
||||
|
||||
template[61] = resp[11];
|
||||
template[62] = resp[12];
|
||||
|
||||
template[46] = resp[16];
|
||||
template[47] = resp[17];
|
||||
template[48] = resp[18];
|
||||
template[49] = resp[19];
|
||||
template[50] = resp[20];
|
||||
template[51] = resp[21];
|
||||
template[52] = resp[22];
|
||||
template[53] = resp[23];
|
||||
template[54] = resp[24];
|
||||
|
||||
template[36] = resp[27];
|
||||
template[37] = resp[28];
|
||||
template[38] = resp[29];
|
||||
template[39] = resp[30];
|
||||
template[40] = resp[31];
|
||||
template[41] = resp[32];
|
||||
template[42] = resp[33];
|
||||
|
||||
Dbprintf("\nrearranged is: ");
|
||||
len = sizeof(template);
|
||||
Dbhexdump(len, &template[0], false); // special print
|
||||
|
||||
AddCrc14A(&template[1], len - 3);
|
||||
Dbprintf("\nafter crc rearranged is: ");
|
||||
Dbhexdump(len, &template[0], false); // special print
|
||||
Dbprintf("\n");
|
||||
|
||||
//EmSendCmd(&template[1], len-1);
|
||||
memcpy(output, &template[1], len - 1);
|
||||
*olen = len - 1;
|
||||
|
||||
BigBuf_free();
|
||||
return;
|
||||
}
|
||||
|
||||
//Dbhexdump(len, &resp[1], false); // special print
|
||||
AddCrc14A(&resp[1], len);
|
||||
Dbhexdump(len + 2, &resp[1], false); // special print
|
||||
|
||||
// Check we don't want to modify the response (application profile response)
|
||||
//uint8_t modifyme[] = {0x03, 0x77, 0x0e, 0x82, 0x02};
|
||||
Dbhexdump(len + 2, &resp[1], false);
|
||||
|
||||
BigBuf_free();
|
||||
|
||||
if (prepend == 0xff) {
|
||||
Dbprintf("pdol request, we can can the response...");
|
||||
Dbprintf("pdol request, we can ignore the response...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(&resp[2], &pay1_response[0], sizeof(pay1_response)) == 0 && true) {
|
||||
Dbprintf("Switching out the pay1 response for a pay2 response...");
|
||||
//EmSendCmd(&pay2_response[0], sizeof(pay2_response));
|
||||
memcpy(output, &pay2_response[0], sizeof(pay2_response));
|
||||
*olen = sizeof(pay2_response);
|
||||
} else if (memcmp(&resp[1], &fci_template[0], 2) == 0 && true) {
|
||||
Dbprintf("***** modifying response to have full fci template...!");
|
||||
//EmSendCmd(&fci_template[0], sizeof(fci_template));
|
||||
memcpy(output, &fci_template[0], sizeof(fci_template));
|
||||
*olen = sizeof(fci_template);
|
||||
} else {
|
||||
//Dbprintf("***** not modifying response...");
|
||||
//EmSendCmd(&resp[1], len + 2);
|
||||
memcpy(output, &resp[1], len + 2);
|
||||
*olen = len + 2;
|
||||
}
|
||||
memcpy(output, &resp[1], len + 2);
|
||||
*olen = len + 2;
|
||||
|
||||
BigBuf_free();
|
||||
|
||||
//memcpy(saved_command, &resp[1], len+2);
|
||||
//saved_command_len = len+2;
|
||||
//EmSendCmd14443aRaw(&resp[1], len+2);
|
||||
//FpgaDisableTracing();
|
||||
//EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
||||
}
|
||||
|
||||
//reply_ng(CMD_SMART_RAW, PM3_SUCCESS, resp, len);
|
||||
|
||||
OUT:
|
||||
//BigBuf_free();
|
||||
//set_tracing(false);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
@@ -269,7 +165,6 @@ int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *o
|
||||
dlen = data[4] + 5;
|
||||
}
|
||||
|
||||
//smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + dlen);
|
||||
smart_card_raw_t *payload = (smart_card_raw_t *)BigBuf_calloc(sizeof(smart_card_raw_t) + dlen);
|
||||
if (payload == NULL) {
|
||||
Dbprintf("failed to allocate memory");
|
||||
@@ -285,7 +180,6 @@ int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *o
|
||||
bool use_t0 = true;
|
||||
|
||||
if (active || active_select) {
|
||||
|
||||
payload->flags |= (SC_CONNECT | SC_CLEARLOG);
|
||||
if (active_select)
|
||||
payload->flags |= SC_SELECT;
|
||||
@@ -296,7 +190,6 @@ int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *o
|
||||
payload->flags |= SC_WAIT;
|
||||
payload->wait_delay = timeout;
|
||||
}
|
||||
//Dbprintf("SIM Card timeout... %u ms", payload->wait_delay);
|
||||
|
||||
if (dlen > 0) {
|
||||
if (use_t0)
|
||||
@@ -305,66 +198,7 @@ int CmdSmartRaw(const uint8_t prepend, const uint8_t *data, int dlen, uint8_t *o
|
||||
payload->flags |= SC_RAW;
|
||||
}
|
||||
|
||||
////uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||
//uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||
//if (buf == NULL) {
|
||||
// Dbprintf("failed to allocate memory");
|
||||
// free(payload);
|
||||
// return PM3_EMALLOC;
|
||||
//}
|
||||
|
||||
|
||||
//clearCommandBuffer();
|
||||
//SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + dlen);
|
||||
|
||||
//for (int i = 0; i < dlen; i++) {
|
||||
// Dbprintf("%02x ", data[i]);
|
||||
//}
|
||||
|
||||
SmartCardDirectSend(prepend, payload, output, olen);
|
||||
|
||||
//if (reply == false) {
|
||||
// Dbprintf("failed to talk to smart card!!!");
|
||||
// goto out;
|
||||
//}
|
||||
|
||||
//// reading response from smart card
|
||||
//int len = smart_response(buf, PM3_CMD_DATA_SIZE);
|
||||
//if (len < 0) {
|
||||
// free(payload);
|
||||
// free(buf);
|
||||
// return PM3_ESOFT;
|
||||
//}
|
||||
|
||||
//if (buf[0] == 0x6C) {
|
||||
|
||||
// // request more bytes to download
|
||||
// data[4] = buf[1];
|
||||
// memcpy(payload->data, data, dlen);
|
||||
// clearCommandBuffer();
|
||||
// SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + dlen);
|
||||
|
||||
// len = smart_response(buf, PM3_CMD_DATA_SIZE);
|
||||
|
||||
// data[4] = 0;
|
||||
//}
|
||||
|
||||
//if (decode_tlv && len > 4) {
|
||||
// TLVPrintFromBuffer(buf, len - 2);
|
||||
//} else {
|
||||
// if (len > 2) {
|
||||
// Dbprintf("Response data:");
|
||||
// Dbprintf(" # | bytes | ascii");
|
||||
// Dbprintf("---+-------------------------------------------------+-----------------");
|
||||
// print_hex_break(buf, len, 16);
|
||||
// }
|
||||
//}
|
||||
|
||||
//memcpy(buffer, buf, len);
|
||||
|
||||
//out:
|
||||
//free(payload);
|
||||
//free(buf);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -198,7 +198,8 @@ static uint8_t MifareMaxSector(uint16_t flags) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
|
||||
bool MifareSimInit (uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
|
||||
//static bool MifareSimInitX(uint16_t flags, uint8_t *datain, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len) {
|
||||
|
||||
uint8_t uid_tmp[10] = {0};
|
||||
// SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf
|
||||
@@ -293,6 +294,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t s
|
||||
rSAK[0] = rSAK_1k;
|
||||
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 1K ATQA/SAK");
|
||||
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_2K_MAX_BYTES)) {
|
||||
Dbprintf("We got this to happen!!!\n");
|
||||
memcpy(rATQA, rATQA_2k, sizeof(rATQA));
|
||||
rSAK[0] = rSAK_2k;
|
||||
*rats = rRATS;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define __MIFARESIM_H
|
||||
|
||||
#include "common.h"
|
||||
#include "mifare.h"
|
||||
|
||||
#ifndef CheckCrc14A
|
||||
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
|
||||
@@ -42,5 +43,6 @@
|
||||
#define AUTHKEYNONE 0xff
|
||||
|
||||
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t atqa, uint8_t sak);
|
||||
bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len, uint8_t **rats, uint8_t *rats_len);
|
||||
|
||||
#endif
|
||||
|
||||
+29
-10
@@ -643,21 +643,21 @@ static int CmdEMVSmartToNFC(const char *Cmd) {
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
int uid_len = 0;
|
||||
int uidlen = 0;
|
||||
uint8_t uid[7] = {0};
|
||||
CLIGetHexWithReturn(ctx, 2, uid, &uid_len);
|
||||
CLIGetHexWithReturn(ctx, 2, uid, &uidlen);
|
||||
|
||||
if (uid_len == 0) {
|
||||
if (uidlen == 0) {
|
||||
PrintAndLogEx(SUCCESS, "No UID provided, using default.");
|
||||
uint8_t default_uid[7] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
memcpy(uid, default_uid, sizeof(default_uid));
|
||||
uid_len = sizeof(default_uid);
|
||||
} else if (uid_len != 7) {
|
||||
uidlen = sizeof(default_uid);
|
||||
} else if (uidlen != 7) {
|
||||
PrintAndLogEx(FAILED, "UID must be 7 bytes long.");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "UID length is %d", uid_len);
|
||||
PrintAndLogEx(SUCCESS, "UID length is %d", uidlen);
|
||||
|
||||
bool testMode = arg_get_lit(ctx, 1);
|
||||
bool show_apdu = true;
|
||||
@@ -670,7 +670,7 @@ static int CmdEMVSmartToNFC(const char *Cmd) {
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// todo: check this is relevant for us.
|
||||
// todo for PR: check this is relevant for us.
|
||||
SetAPDULogging(show_apdu);
|
||||
|
||||
struct {
|
||||
@@ -681,14 +681,33 @@ static int CmdEMVSmartToNFC(const char *Cmd) {
|
||||
uint8_t sak;
|
||||
} PACKED payload;
|
||||
|
||||
memcpy(payload.uid, uid, uid_len);
|
||||
payload.flags = 0x1204;
|
||||
memcpy(payload.uid, uid, uidlen);
|
||||
|
||||
// Set up the flags for 2K mifare sim with RATS
|
||||
uint16_t flags = 0;
|
||||
|
||||
FLAG_SET_UID_IN_DATA(flags, uidlen);
|
||||
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
PrintAndLogEx(WARNING, "Invalid parameter for UID");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
FLAG_SET_MF_SIZE(flags, MIFARE_2K_MAX_BYTES);
|
||||
//snprintf(csize, sizeof(csize), "2K with RATS");
|
||||
//k_sectors_cnt = MIFARE_2K_MAXSECTOR; // todo: delete
|
||||
|
||||
flags |= FLAG_ATQA_IN_DATA;
|
||||
flags |= FLAG_SAK_IN_DATA;
|
||||
|
||||
payload.flags = flags;
|
||||
//payload.flags = 0x1204;
|
||||
payload.exitAfter = 0x1;
|
||||
payload.atqa = 0x0;
|
||||
payload.sak = 0x20;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(0x0386, (uint8_t *)&payload, sizeof(payload));
|
||||
SendCommandNG(CMD_HF_ISO14443A_EMV_SIMULATE, (uint8_t *)&payload, sizeof(payload));
|
||||
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("pm3 button") " to abort simulation");
|
||||
|
||||
|
||||
@@ -490,6 +490,15 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||
#define ISO7816_GET_CHALLENGE 0x84
|
||||
#define ISO7816_MANAGE_CHANNEL 0x70
|
||||
|
||||
#define ISO7816_APPLICATION_BLOCK 0x1E
|
||||
#define ISO7816_APPLICATION_UNBLOCK 0x18
|
||||
#define ISO7816_CARD_BLOCK 0x16
|
||||
#define ISO7816_GENERATE_APPLICATION_CRYPTOGRAM 0xAE
|
||||
#define ISO7816_GET_PROCESSING_OPTIONS 0xA8
|
||||
#define ISO7816_PIN_CHANGE 0x24
|
||||
#define ISO7816_PIN_CHANGE 0x24
|
||||
|
||||
|
||||
#define ISO7816_GET_RESPONSE 0xC0
|
||||
|
||||
// ISO7816-4 For response APDU's
|
||||
|
||||
Reference in New Issue
Block a user