mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-10-23 06:32:37 +00:00
Merge branch 'RfidResearchGroup:master' into fix_lf_bps
This commit is contained in:
13 files changed
+374
-121
No files matched your search
+102
-68
@@ -99,6 +99,7 @@ static const productName_t uidmapping[] = {
|
||||
//I-Code SLIX-L [IC id = 03 + bit36 set to 1]
|
||||
{ 0xE004000000000000LL, 16, "NXP Semiconductors Germany (Philips)" },
|
||||
{ 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX) ICS2602(SLIX2)" },
|
||||
{ 0xE004011800000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC NTP53x2/NTP5210/NTA5332(NTAG 5)" },
|
||||
{ 0xE004010000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS20/ICS21(SLI)" },
|
||||
{ 0xE004011000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2002/ICS2102(SLIX)" },
|
||||
{ 0xE004010800000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2602(SLIX2)" },
|
||||
@@ -651,6 +652,95 @@ static int CmdHF15Samples(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int NxpTestEAS(uint8_t *uid)
|
||||
{
|
||||
uint8_t fast = 1;
|
||||
uint8_t reply = 1;
|
||||
PacketResponseNG resp;
|
||||
uint16_t reqlen = 0;
|
||||
uint8_t req[PM3_CMD_DATA_SIZE] = {0};
|
||||
|
||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||
req[reqlen++] = ISO15693_EAS_ALARM;
|
||||
req[reqlen++] = 0x04; // IC manufacturer code
|
||||
memcpy(req + 3, uid, 8); // add UID
|
||||
reqlen += 8;
|
||||
|
||||
AddCrc15(req, reqlen);
|
||||
reqlen += 2;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
|
||||
PrintAndLogEx(WARNING, "iso15693 timeout");
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
|
||||
if (resp.length < 2) {
|
||||
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active");
|
||||
} else {
|
||||
uint8_t * recv = resp.data.asBytes;
|
||||
|
||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active.");
|
||||
PrintAndLogEx(INFO, " EAS sequence: %s", sprint_hex(recv + 1, 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int NxpCheckSig(uint8_t *uid) {
|
||||
uint8_t fast = 1;
|
||||
uint8_t reply = 1;
|
||||
PacketResponseNG resp;
|
||||
uint16_t reqlen = 0;
|
||||
uint8_t req[PM3_CMD_DATA_SIZE] = {0};
|
||||
|
||||
// Check if we can also read the signature
|
||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||
req[reqlen++] = ISO15693_READ_SIGNATURE;
|
||||
req[reqlen++] = 0x04; // IC manufacturer code
|
||||
memcpy(req + 3, uid, 8); // add UID
|
||||
reqlen += 8;
|
||||
|
||||
AddCrc15(req, reqlen);
|
||||
reqlen += 2;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
|
||||
PrintAndLogEx(WARNING, "iso15693 timeout");
|
||||
DropField();
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
DropField();
|
||||
|
||||
if (resp.length < 2) {
|
||||
PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command");
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
uint8_t *recv = resp.data.asBytes;
|
||||
|
||||
if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) {
|
||||
PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
uint8_t signature[32] = {0x00};
|
||||
memcpy(signature, recv + 1, 32);
|
||||
|
||||
nxp_15693_print_signature(uid, signature);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Get NXP system information from SLIX2 tag/VICC
|
||||
static int NxpSysInfo(uint8_t *uid) {
|
||||
|
||||
@@ -732,77 +822,11 @@ static int NxpSysInfo(uint8_t *uid) {
|
||||
PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[5] & 0x80) ? "" : " not"));
|
||||
|
||||
if (support_easmode) {
|
||||
reqlen = 0;
|
||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||
req[reqlen++] = ISO15693_EAS_ALARM;
|
||||
req[reqlen++] = 0x04; // IC manufacturer code
|
||||
memcpy(req + 3, uid, 8); // add UID
|
||||
reqlen += 8;
|
||||
|
||||
AddCrc15(req, reqlen);
|
||||
reqlen += 2;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
|
||||
PrintAndLogEx(WARNING, "iso15693 timeout");
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
|
||||
if (resp.length < 2) {
|
||||
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active");
|
||||
} else {
|
||||
recv = resp.data.asBytes;
|
||||
|
||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||
PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active.");
|
||||
PrintAndLogEx(INFO, " EAS sequence: %s", sprint_hex(recv + 1, 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
NxpTestEAS(uid);
|
||||
}
|
||||
|
||||
if (support_signature) {
|
||||
// Check if we can also read the signature
|
||||
reqlen = 0;
|
||||
req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS;
|
||||
req[reqlen++] = ISO15693_READ_SIGNATURE;
|
||||
req[reqlen++] = 0x04; // IC manufacturer code
|
||||
memcpy(req + 3, uid, 8); // add UID
|
||||
reqlen += 8;
|
||||
|
||||
AddCrc15(req, reqlen);
|
||||
reqlen += 2;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
|
||||
PrintAndLogEx(WARNING, "iso15693 timeout");
|
||||
DropField();
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
DropField();
|
||||
|
||||
if (resp.length < 2) {
|
||||
PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command");
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
recv = resp.data.asBytes;
|
||||
|
||||
if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) {
|
||||
PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0]));
|
||||
return PM3_EWRONGANSWER;
|
||||
}
|
||||
|
||||
uint8_t signature[32] = {0x00};
|
||||
memcpy(signature, recv + 1, 32);
|
||||
|
||||
nxp_15693_print_signature(uid, signature);
|
||||
NxpCheckSig(uid);
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
@@ -945,6 +969,16 @@ static int CmdHF15Info(const char *Cmd) {
|
||||
PrintAndLogEx(DEBUG, "SLIX2 Detected, getting NXP System Info");
|
||||
return NxpSysInfo(uid);
|
||||
}
|
||||
else if(data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) //If it is an NTAG 5
|
||||
{
|
||||
PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info");
|
||||
return NxpSysInfo(uid);
|
||||
}
|
||||
else if(data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status
|
||||
{
|
||||
PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status");
|
||||
return NxpTestEAS(uid);
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
|
||||
@@ -971,6 +971,11 @@ static int CmdHF14AMfDump(const char *Cmd) {
|
||||
for (blockNo = 0; blockNo < mfNumBlocksPerSector(sectorNo); blockNo++) {
|
||||
bool received = false;
|
||||
current_key = MF_KEY_A;
|
||||
uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5;
|
||||
if (rights[sectorNo][data_area] == 0x07) { // no key would work
|
||||
PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d, skipping", sectorNo, blockNo);
|
||||
continue;
|
||||
}
|
||||
for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) {
|
||||
if (blockNo == mfNumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A.
|
||||
|
||||
@@ -982,7 +987,6 @@ static int CmdHF14AMfDump(const char *Cmd) {
|
||||
SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t));
|
||||
received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500);
|
||||
} else { // data block. Check if it can be read with key A or key B
|
||||
uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5;
|
||||
if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work
|
||||
|
||||
payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo;
|
||||
@@ -992,10 +996,6 @@ static int CmdHF14AMfDump(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t));
|
||||
received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500);
|
||||
} else if (rights[sectorNo][data_area] == 0x07) { // no key would work
|
||||
PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo);
|
||||
// where do you want to go?? Next sector or block?
|
||||
break;
|
||||
} else { // key A would work
|
||||
|
||||
payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo;
|
||||
@@ -1044,11 +1044,9 @@ static int CmdHF14AMfDump(const char *Cmd) {
|
||||
PrintAndLogEx(SUCCESS, "successfully read block %2d of sector %2d.", blockNo, sectorNo);
|
||||
} else {
|
||||
PrintAndLogEx(FAILED, "could not read block %2d of sector %2d", blockNo, sectorNo);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d of sector %2d.", blockNo, sectorNo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+43
-26
@@ -64,26 +64,36 @@ static int info_hf_tesla(void) {
|
||||
param_gethex_to_eol("00a404000a7465736c614c6f676963", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
|
||||
int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
if (res != PM3_SUCCESS) {
|
||||
DropField();
|
||||
return res;
|
||||
}
|
||||
|
||||
if (resplen < 2) {
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint16_t sw = get_sw(response, resplen);
|
||||
if (sw != ISO7816_OK) {
|
||||
PrintAndLogEx(ERR, "Selecting TESLA aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
activate_field = false;
|
||||
uint16_t sw = get_sw(response, resplen);
|
||||
|
||||
if ((resplen < 2) || (sw != ISO7816_OK)) {
|
||||
|
||||
param_gethex_to_eol("00a404000af465736c614c6f676963", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n);
|
||||
res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
|
||||
if (res != PM3_SUCCESS) {
|
||||
DropField();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if ((resplen < 2) || (sw != ISO7816_OK)) {
|
||||
PrintAndLogEx(ERR, "Selecting TESLA aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
|
||||
// DropField();
|
||||
// return PM3_ESOFT;
|
||||
}
|
||||
|
||||
|
||||
keep_field_on = true;
|
||||
|
||||
|
||||
// --------------- ECDH public key file reading ----------------
|
||||
uint8_t pk[3][65] = {{0}};
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
|
||||
uint8_t aSELECT_PK[5] = {0x80, 0x04, i, 0x00, 0x00};
|
||||
@@ -94,12 +104,7 @@ static int info_hf_tesla(void) {
|
||||
|
||||
sw = get_sw(response, resplen);
|
||||
if (sw == ISO7816_OK) {
|
||||
// save PK for later
|
||||
uint8_t pk[65] = {0};
|
||||
memcpy(pk, response, resplen - 2);
|
||||
|
||||
PrintAndLogEx(INFO, "PUBLIC KEY # %i", i);
|
||||
PrintAndLogEx(INFO, "%s", sprint_hex_inrow(pk, sizeof(pk)));
|
||||
memcpy(pk[i], response, resplen - 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,21 +191,33 @@ static int info_hf_tesla(void) {
|
||||
memcpy(auth, response, sizeof(auth));
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "CHALL... %s", sprint_hex_inrow(auth, sizeof(auth)));
|
||||
|
||||
keep_field_on = false;
|
||||
DropField();
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
// PrintAndLogEx(INFO, "PUBLIC KEY");
|
||||
// PrintAndLogEx(INFO, "%zu - %s", sizeof(pk), sprint_hex_inrow(pk, sizeof(pk)));
|
||||
PrintAndLogEx(INFO, "Form factor");
|
||||
PrintAndLogEx(INFO, "%zu - %s", sizeof(form_factor), sprint_hex_inrow(form_factor, sizeof(form_factor)));
|
||||
PrintAndLogEx(INFO, "VERSION");
|
||||
PrintAndLogEx(INFO, "%zu - %s", sizeof(version), sprint_hex_inrow(version, sizeof(version)));
|
||||
PrintAndLogEx(INFO, "PUBLIC KEY");
|
||||
for (int i=0; i < 3; i++) {
|
||||
PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65));
|
||||
}
|
||||
if (form_factor[1] == 1) {
|
||||
PrintAndLogEx(INFO, "Form factor... %s (card)", sprint_hex_inrow(form_factor, sizeof(form_factor)));
|
||||
} else if (form_factor[1] == 2){
|
||||
PrintAndLogEx(INFO, "Form factor... %s (phone app)", sprint_hex_inrow(form_factor, sizeof(form_factor)));
|
||||
}
|
||||
|
||||
if (sizeof(version) > 0) {
|
||||
PrintAndLogEx(INFO, "Version....... %s", sprint_hex_inrow(version, sizeof(version)));
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "CHALL......... %s", sprint_hex_inrow(auth, sizeof(auth)));
|
||||
|
||||
PrintAndLogEx(INFO, "Fingerprint");
|
||||
if ((memcmp(pk[0], pk[1], 65) == 0)) {
|
||||
PrintAndLogEx(INFO, " GaussKey detected");
|
||||
}
|
||||
//
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+18
-9
@@ -147,7 +147,7 @@ static int split(char *str, char **arr) {
|
||||
return word_cnt;
|
||||
}
|
||||
|
||||
static void set_python_path(char *path) {
|
||||
static void set_python_path(const char *path) {
|
||||
PyObject *syspath = PySys_GetObject("path");
|
||||
if (syspath == 0) {
|
||||
PrintAndLogEx(WARNING, "Python failed to getobject");
|
||||
@@ -172,7 +172,7 @@ static void set_python_paths(void) {
|
||||
char scripts_path[strlen(exec_path) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1];
|
||||
strcpy(scripts_path, exec_path);
|
||||
strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR);
|
||||
// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD);
|
||||
// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD);
|
||||
set_python_path(scripts_path);
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ static void set_python_paths(void) {
|
||||
strcpy(scripts_path, user_path);
|
||||
strcat(scripts_path, PM3_USER_DIRECTORY);
|
||||
strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR);
|
||||
// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD);
|
||||
// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD);
|
||||
set_python_path(scripts_path);
|
||||
|
||||
}
|
||||
@@ -194,7 +194,7 @@ static void set_python_paths(void) {
|
||||
strcpy(scripts_path, exec_path);
|
||||
strcat(scripts_path, PM3_SHARE_RELPATH);
|
||||
strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR);
|
||||
// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD);
|
||||
// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD);
|
||||
set_python_path(scripts_path);
|
||||
}
|
||||
}
|
||||
@@ -407,12 +407,16 @@ static int CmdScriptRun(const char *Cmd) {
|
||||
Py_Initialize();
|
||||
#else
|
||||
PyConfig py_conf;
|
||||
PyConfig_InitIsolatedConfig(&py_conf);
|
||||
// Despite being isolated we probably want to allow users to use
|
||||
// the Python packages they installed on their user directory as well
|
||||
// as system ones. But it seems isolated mode still enforces them off.
|
||||
py_conf.use_environment = 1;
|
||||
// We need to use Python mode instead of isolated to avoid breaking stuff.
|
||||
PyConfig_InitPythonConfig(&py_conf);
|
||||
// Let's still make things bit safer by being as close as possible to isolated mode.
|
||||
py_conf.configure_c_stdio = -1;
|
||||
py_conf.faulthandler = 0;
|
||||
py_conf.use_hash_seed = 0;
|
||||
py_conf.install_signal_handlers = 0;
|
||||
py_conf.parse_argv = 0;
|
||||
py_conf.user_site_directory = 1;
|
||||
py_conf.use_environment = 0;
|
||||
#endif
|
||||
|
||||
//int argc, char ** argv
|
||||
@@ -429,8 +433,13 @@ static int CmdScriptRun(const char *Cmd) {
|
||||
#else
|
||||
// The following line will implicitly pre-initialize Python
|
||||
PyConfig_SetBytesArgv(&py_conf, argc + 1, argv);
|
||||
|
||||
// We disallowed in py_conf environment variables interfering with python interpreter's behavior.
|
||||
// Let's manually enable the ones we truly need.
|
||||
// This is required by Proxspace to work with an isolated Python configuration
|
||||
PyConfig_SetBytesString(&py_conf, &py_conf.home, getenv("PYTHONHOME"));
|
||||
// This is required for allowing `import pm3` in python scripts
|
||||
PyConfig_SetBytesString(&py_conf, &py_conf.pythonpath_env, getenv("PYTHONPATH"));
|
||||
|
||||
Py_InitializeFromConfig(&py_conf);
|
||||
|
||||
|
||||
@@ -719,7 +719,7 @@ static int CmdSmartInfo(const char *Cmd) {
|
||||
|
||||
// print header
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Smartcard Information") " ---------");
|
||||
PrintAndLogEx(INFO, "ISO7618-3 ATR... %s", sprint_hex(card.atr, card.atr_len));
|
||||
PrintAndLogEx(INFO, "ISO7816-3 ATR... %s", sprint_hex(card.atr, card.atr_len));
|
||||
// convert bytes to str.
|
||||
char *hexstr = calloc((card.atr_len << 1) + 1, sizeof(uint8_t));
|
||||
if (hexstr == NULL) {
|
||||
|
||||
@@ -42,14 +42,14 @@
|
||||
|
||||
typedef struct {
|
||||
uint8_t *buffer;
|
||||
uint8_t numbits;
|
||||
uint8_t position;
|
||||
uint32_t numbits;
|
||||
uint32_t position;
|
||||
} BitstreamIn_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *buffer;
|
||||
uint8_t numbits;
|
||||
uint8_t position;
|
||||
uint32_t numbits;
|
||||
uint32_t position;
|
||||
} BitstreamOut_t;
|
||||
|
||||
bool headBit(BitstreamIn_t *stream);
|
||||
|
||||
Reference in new issue
Block a user