mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Merge pull request #1869 from RfidResearchGroup/nitride
Nitride release preparation in progress
This commit is contained in:
commit
2d1c856437
59 changed files with 703 additions and 692 deletions
|
@ -18,7 +18,6 @@ assignees: doegox, iceman1001
|
|||
- [ ] `tools/build_all_firmwares.sh` check that the script contains all standalone modes then compile all standalone modes (linux only)
|
||||
- [ ] `experimental_lib` compilation & tests
|
||||
- [ ] `experimental_client_with_swig` compilation & tests
|
||||
- [ ] Check Android `CMakeLists.txt` list of source file
|
||||
- [ ] GitHub Actions - green across the board ( MacOS, Ubuntu, Windows)
|
||||
|
||||
# OS compilation and tests
|
||||
|
|
|
@ -125,7 +125,7 @@ STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4
|
|||
STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI
|
||||
STANDALONE_MODES_REQ_BT := HF_REBLAY
|
||||
STANDALONE_MODES_REQ_SMARTCARD :=
|
||||
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_MFCSIM HF_LEGICSIM
|
||||
STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
|
||||
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// then from shell:
|
||||
// hexdump lf.bin -e '5/1 "%02X" /0 "\n"'
|
||||
//
|
||||
// To recall only LAST stored ID from flash use lf-last instead of lf file.
|
||||
// To recall only LAST stored ID from flash use lf-last instead of lf file.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// Modes of operation:
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
#include "BigBuf.h"
|
||||
#include "crc16.h"
|
||||
|
||||
#define MODULE_LONG_NAME "LF Nedap simple simulator"
|
||||
#define MODULE_LONG_NAME "LF Nedap simple simulator"
|
||||
|
||||
typedef struct _NEDAP_TAG {
|
||||
uint8_t subType;
|
||||
uint16_t customerCode;
|
||||
uint32_t id;
|
||||
uint8_t subType;
|
||||
uint16_t customerCode;
|
||||
uint32_t id;
|
||||
|
||||
uint8_t bIsLong;
|
||||
uint8_t bIsLong;
|
||||
} NEDAP_TAG, *PNEDAP_TAG;
|
||||
|
||||
const NEDAP_TAG Tag = {.subType = 0x5, .customerCode = 0x123, .id = 42424, .bIsLong = 1};
|
||||
|
@ -46,30 +46,27 @@ static uint8_t isEven_64_63(const uint8_t *data);
|
|||
static inline uint32_t bitcount32(uint32_t a);
|
||||
static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest);
|
||||
|
||||
void ModInfo(void)
|
||||
{
|
||||
void ModInfo(void) {
|
||||
DbpString(" " MODULE_LONG_NAME);
|
||||
}
|
||||
|
||||
void RunMod(void)
|
||||
{
|
||||
int n;
|
||||
void RunMod(void) {
|
||||
int n;
|
||||
|
||||
StandAloneMode();
|
||||
StandAloneMode();
|
||||
|
||||
Dbprintf("[=] " MODULE_LONG_NAME " -- started");
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
Dbprintf("[=] NEDAP (%s) - ID: " _GREEN_("%05u") " subtype: " _GREEN_("%1u") " customer code: " _GREEN_("%u / 0x%03X"), Tag.bIsLong ? "128b" : "64b", Tag.id, Tag.subType, Tag.customerCode, Tag.customerCode);
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
Dbprintf("[=] NEDAP (%s) - ID: " _GREEN_("%05u") " subtype: " _GREEN_("%1u") " customer code: " _GREEN_("%u / 0x%03X"), Tag.bIsLong ? "128b" : "64b", Tag.id, Tag.subType, Tag.customerCode, Tag.customerCode);
|
||||
|
||||
n = NedapPrepareBigBuffer(&Tag);
|
||||
do
|
||||
{
|
||||
n = NedapPrepareBigBuffer(&Tag);
|
||||
do {
|
||||
WDT_HIT();
|
||||
|
||||
if (data_available())
|
||||
break;
|
||||
break;
|
||||
|
||||
SimulateTagLowFrequency(n, 0, true);
|
||||
SimulateTagLowFrequency(n, 0, true);
|
||||
|
||||
} while (BUTTON_HELD(1000) == BUTTON_NO_CLICK);
|
||||
|
||||
|
@ -78,46 +75,38 @@ void RunMod(void)
|
|||
LEDsoff();
|
||||
}
|
||||
|
||||
static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t data[16], bitStream[sizeof(data) * 8], phase = 0;
|
||||
uint16_t i, size = pTag->bIsLong ? sizeof(data) : (sizeof(data) / 2);
|
||||
static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag) {
|
||||
int ret = 0;
|
||||
uint8_t data[16], bitStream[sizeof(data) * 8], phase = 0;
|
||||
uint16_t i, size = pTag->bIsLong ? sizeof(data) : (sizeof(data) / 2);
|
||||
|
||||
NedapGen(pTag->subType, pTag->customerCode, pTag->id, pTag->bIsLong, data);
|
||||
bytes_to_bytebits(data, size, bitStream);
|
||||
size <<= 3;
|
||||
NedapGen(pTag->subType, pTag->customerCode, pTag->id, pTag->bIsLong, data);
|
||||
bytes_to_bytebits(data, size, bitStream);
|
||||
size <<= 3;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
biphaseSimBitInverted(!bitStream[i], &ret, &phase);
|
||||
}
|
||||
if (phase == 1) //run a second set inverted to keep phase in check
|
||||
{
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
biphaseSimBitInverted(!bitStream[i], &ret, &phase);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
biphaseSimBitInverted(!bitStream[i], &ret, &phase);
|
||||
}
|
||||
if (phase == 1) { //run a second set inverted to keep phase in check
|
||||
for (i = 0; i < size; i++) {
|
||||
biphaseSimBitInverted(!bitStream[i], &ret, &phase);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase)
|
||||
{
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase) {
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
if (c)
|
||||
{
|
||||
memset(dest + (*n), c ^ 1 ^ *phase, 32);
|
||||
memset(dest + (*n) + 32, c ^ *phase, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(dest + (*n), c ^ *phase, 64);
|
||||
*phase ^= 1;
|
||||
}
|
||||
*n += 64;
|
||||
if (c) {
|
||||
memset(dest + (*n), c ^ 1 ^ *phase, 32);
|
||||
memset(dest + (*n) + 32, c ^ *phase, 32);
|
||||
} else {
|
||||
memset(dest + (*n), c ^ *phase, 64);
|
||||
*phase ^= 1;
|
||||
}
|
||||
*n += 64;
|
||||
}
|
||||
|
||||
#define FIXED_71 0x71
|
||||
|
@ -190,13 +179,11 @@ static uint8_t isEven_64_63(const uint8_t *data) { // 8
|
|||
return (bitcount32(tmp[0]) + (bitcount32(tmp[1] & 0xfeffffff))) & 1;
|
||||
}
|
||||
|
||||
static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest)
|
||||
{
|
||||
static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) {
|
||||
uint8_t *s = (uint8_t *)src, *d = (uint8_t *)dest;
|
||||
size_t i = srclen * 8, j = srclen;
|
||||
|
||||
while (j--)
|
||||
{
|
||||
while (j--) {
|
||||
uint8_t b = s[j];
|
||||
d[--i] = (b >> 0) & 1;
|
||||
d[--i] = (b >> 1) & 1;
|
||||
|
@ -209,8 +196,7 @@ static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest)
|
|||
}
|
||||
}
|
||||
|
||||
static inline uint32_t bitcount32(uint32_t a)
|
||||
{
|
||||
static inline uint32_t bitcount32(uint32_t a) {
|
||||
#if defined __GNUC__
|
||||
return __builtin_popcountl(a);
|
||||
#else
|
||||
|
|
|
@ -298,7 +298,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
|||
// 8-byte IDm, number of blocks, blocks numbers
|
||||
// number of blocks limited to 4 for FelicaLite(S)
|
||||
static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t *blocks) {
|
||||
if (blocknum > 4 || blocknum <= 0)
|
||||
if (blocknum > 4 || blocknum == 0)
|
||||
Dbprintf("Invalid number of blocks, %d != 4", blocknum);
|
||||
|
||||
uint8_t c = 0, i = 0;
|
||||
|
|
|
@ -235,9 +235,10 @@ static int json_get_utf8_char_len(unsigned char ch) {
|
|||
|
||||
/* string = '"' { quoted_printable_chars } '"' */
|
||||
static int json_parse_string(struct frozen *f) {
|
||||
int n, ch = 0, len = 0;
|
||||
int ch = 0;
|
||||
TRY(json_test_and_skip(f, '"'));
|
||||
{
|
||||
int len = 0;
|
||||
SET_STATE(f, f->cur, "", 0);
|
||||
for (; f->cur < f->end; f->cur += len) {
|
||||
ch = *(unsigned char *) f->cur;
|
||||
|
@ -245,6 +246,7 @@ static int json_parse_string(struct frozen *f) {
|
|||
EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */
|
||||
EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE);
|
||||
if (ch == '\\') {
|
||||
int n;
|
||||
EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n);
|
||||
len += n;
|
||||
} else if (ch == '"') {
|
||||
|
@ -295,17 +297,17 @@ static int json_parse_number(struct frozen *f) {
|
|||
#if JSON_ENABLE_ARRAY
|
||||
/* array = '[' [ value { ',' value } ] ']' */
|
||||
static int json_parse_array(struct frozen *f) {
|
||||
int i = 0, current_path_len;
|
||||
char buf[20];
|
||||
CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0);
|
||||
TRY(json_test_and_skip(f, '['));
|
||||
{
|
||||
{
|
||||
int i = 0;
|
||||
SET_STATE(f, f->cur - 1, "", 0);
|
||||
while (json_cur(f) != ']') {
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "[%d]", i);
|
||||
i++;
|
||||
current_path_len = json_append_to_path(f, buf, strlen(buf));
|
||||
int current_path_len = json_append_to_path(f, buf, strlen(buf));
|
||||
f->cur_name =
|
||||
f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/;
|
||||
f->cur_name_len = strlen(buf) - 2 /*braces*/;
|
||||
|
@ -1427,9 +1429,12 @@ static void json_next_cb(void *userdata, const char *name, size_t name_len,
|
|||
|
||||
static void *json_next(const char *s, int len, void *handle, const char *path,
|
||||
struct json_token *key, struct json_token *val, int *i) {
|
||||
struct json_token tmpval, *v = val == NULL ? &tmpval : val;
|
||||
struct json_token tmpkey, *k = key == NULL ? &tmpkey : key;
|
||||
int tmpidx, *pidx = i == NULL ? &tmpidx : i;
|
||||
struct json_token tmpval;
|
||||
struct json_token *v = val == NULL ? &tmpval : val;
|
||||
struct json_token tmpkey;
|
||||
struct json_token *k = key == NULL ? &tmpkey : key;
|
||||
int tmpidx;
|
||||
int *pidx = i == NULL ? &tmpidx : i;
|
||||
struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx};
|
||||
json_walk(s, len, json_next_cb, &data);
|
||||
return data.found ? data.handle : NULL;
|
||||
|
|
|
@ -1268,7 +1268,6 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) {
|
|||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen = 0;
|
||||
uint8_t tx[HITAG_FRAME_LEN];
|
||||
size_t txlen;
|
||||
int t_wait = HITAG_T_WAIT_MAX;
|
||||
|
||||
|
||||
|
@ -1284,7 +1283,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) {
|
|||
WDT_HIT();
|
||||
|
||||
//send read request
|
||||
txlen = 0;
|
||||
size_t txlen = 0;
|
||||
uint8_t cmd = 0x0c;
|
||||
txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4);
|
||||
uint8_t addr = pageNum;
|
||||
|
|
|
@ -1258,7 +1258,6 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *
|
|||
uint16_t timeout, uint32_t *eof_time, bool shallow_mod) {
|
||||
|
||||
uint16_t resp_len = 0;
|
||||
int res;
|
||||
while (tries-- > 0) {
|
||||
|
||||
iclass_send_as_reader(cmd, cmdsize, start_time, eof_time, shallow_mod);
|
||||
|
@ -1267,7 +1266,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *
|
|||
return true;
|
||||
}
|
||||
|
||||
res = GetIso15693AnswerFromTag(resp, max_resp_size, timeout, eof_time, false, true, &resp_len);
|
||||
int res = GetIso15693AnswerFromTag(resp, max_resp_size, timeout, eof_time, false, true, &resp_len);
|
||||
if (res == PM3_SUCCESS && expected_size == resp_len) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1814,17 +1814,17 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
static const uint8_t x_wup2[] = { 0x5D, 0x37, 0x21, 0x71, 0x71 };
|
||||
uint8_t slot_mark[1];
|
||||
|
||||
uint8_t x_atqb[24] = {0x0}; // ATQB len = 18
|
||||
uint8_t x_atqb[24] = {0x0}; // ATQB len = 18
|
||||
|
||||
uint32_t start_time = 0;
|
||||
uint32_t eof_time = 0;
|
||||
|
||||
iso14b_set_timeout(24); // wait for carrier
|
||||
iso14b_set_timeout(24); // wait for carrier
|
||||
|
||||
// wup1
|
||||
CodeAndTransmit14443bAsReader(x_wup1, sizeof(x_wup1), &start_time, &eof_time, true);
|
||||
|
||||
start_time = eof_time + US_TO_SSP(9000); // 9ms before next cmd
|
||||
start_time = eof_time + US_TO_SSP(9000); // 9ms before next cmd
|
||||
|
||||
// wup2
|
||||
CodeAndTransmit14443bAsReader(x_wup2, sizeof(x_wup2), &start_time, &eof_time, true);
|
||||
|
@ -1836,7 +1836,7 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
int slot;
|
||||
|
||||
for (slot = 0; slot < 4; slot++) {
|
||||
start_time = eof_time + ETU_TO_SSP(30); //(24); // next slot after 24 ETU
|
||||
start_time = eof_time + ETU_TO_SSP(30); //(24); // next slot after 24 ETU
|
||||
|
||||
retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time);
|
||||
|
||||
|
@ -1850,14 +1850,14 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
|
||||
// tx unframed slot-marker
|
||||
|
||||
if (Demod.posCount) { // no rx, but subcarrier burst detected
|
||||
if (Demod.posCount) { // no rx, but subcarrier burst detected
|
||||
uid |= (uint64_t)slot << uid_pos;
|
||||
|
||||
slot_mark[0] = 0xB1 + (slot << 1); // ack slot
|
||||
slot_mark[0] = 0xB1 + (slot << 1); // ack slot
|
||||
CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false);
|
||||
break;
|
||||
} else { // no subcarrier burst
|
||||
slot_mark[0] = 0xA1 + (slot << 1); // nak slot
|
||||
} else { // no subcarrier burst
|
||||
slot_mark[0] = 0xA1 + (slot << 1); // nak slot
|
||||
CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false);
|
||||
}
|
||||
}
|
||||
|
@ -1884,7 +1884,7 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) {
|
|||
}
|
||||
|
||||
// VALIDATE CRC
|
||||
if (check_crc(CRC_14443_B, x_atqb, 18) == false) { // use fixed len because unstable EOF catch
|
||||
if (check_crc(CRC_14443_B, x_atqb, 18) == false) { // use fixed len because unstable EOF catch
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -461,7 +461,6 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo
|
|||
uint16_t len = 0;
|
||||
uint32_t pos = 0;
|
||||
uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send
|
||||
uint8_t res = 0;
|
||||
|
||||
uint8_t d_block[18], d_block_enc[18];
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||
|
@ -495,7 +494,7 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo
|
|||
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
|
||||
|
||||
if (len != 0) { // Something not right, len == 0 (no response is ok as its waiting for transfer
|
||||
res = 0;
|
||||
uint8_t res = 0;
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0;
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1;
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2;
|
||||
|
|
|
@ -293,9 +293,9 @@ set (TARGET_SOURCES
|
|||
${PM3_ROOT}/client/src/cmdhfseos.c
|
||||
${PM3_ROOT}/client/src/cmdhfst.c
|
||||
${PM3_ROOT}/client/src/cmdhfst25ta.c
|
||||
${PM3_ROOT}/client/src/cmdhftexkom.c
|
||||
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
||||
${PM3_ROOT}/client/src/cmdhftopaz.c
|
||||
${PM3_ROOT}/client/src/cmdhftexkom.c
|
||||
${PM3_ROOT}/client/src/cmdhfwaveshare.c
|
||||
${PM3_ROOT}/client/src/cmdhfxerox.c
|
||||
${PM3_ROOT}/client/src/cmdhw.c
|
||||
|
|
|
@ -530,7 +530,6 @@ stop_tests:
|
|||
bucket_states_tested += bucket_size[block_idx];
|
||||
// prepare to set new states
|
||||
state_p = &states[KEYSTREAM_SIZE];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
out:
|
||||
|
|
|
@ -276,6 +276,7 @@ set (TARGET_SOURCES
|
|||
${PM3_ROOT}/client/src/cmdhfepa.c
|
||||
${PM3_ROOT}/client/src/cmdhffelica.c
|
||||
${PM3_ROOT}/client/src/cmdhffido.c
|
||||
${PM3_ROOT}/client/src/cmdhffudan.c
|
||||
${PM3_ROOT}/client/src/cmdhfgallagher.c
|
||||
${PM3_ROOT}/client/src/cmdhfcipurse.c
|
||||
${PM3_ROOT}/client/src/cmdhficlass.c
|
||||
|
@ -293,9 +294,11 @@ set (TARGET_SOURCES
|
|||
${PM3_ROOT}/client/src/cmdhfseos.c
|
||||
${PM3_ROOT}/client/src/cmdhfst.c
|
||||
${PM3_ROOT}/client/src/cmdhfst25ta.c
|
||||
${PM3_ROOT}/client/src/cmdhftexkom.c
|
||||
${PM3_ROOT}/client/src/cmdhfthinfilm.c
|
||||
${PM3_ROOT}/client/src/cmdhftopaz.c
|
||||
${PM3_ROOT}/client/src/cmdhfwaveshare.c
|
||||
${PM3_ROOT}/client/src/cmdhfxerox.c
|
||||
${PM3_ROOT}/client/src/cmdhw.c
|
||||
${PM3_ROOT}/client/src/cmdlf.c
|
||||
${PM3_ROOT}/client/src/cmdlfawid.c
|
||||
|
@ -334,6 +337,7 @@ set (TARGET_SOURCES
|
|||
${PM3_ROOT}/client/src/cmdmain.c
|
||||
${PM3_ROOT}/client/src/cmdnfc.c
|
||||
${PM3_ROOT}/client/src/cmdparser.c
|
||||
${PM3_ROOT}/client/src/cmdpiv.c
|
||||
${PM3_ROOT}/client/src/cmdscript.c
|
||||
${PM3_ROOT}/client/src/cmdsmartcard.c
|
||||
${PM3_ROOT}/client/src/cmdtrace.c
|
||||
|
|
|
@ -62,7 +62,7 @@ function main(args)
|
|||
|
||||
local i
|
||||
local cmds = {}
|
||||
--check for params
|
||||
--check for params
|
||||
for o, a in getopt.getopt(args, 'h') do
|
||||
if o == 'h' then return help() end
|
||||
end
|
||||
|
|
|
@ -63,8 +63,8 @@ local function card_format(key_a,key_b,ab,user,s70)
|
|||
core.console(cmd)
|
||||
print(cmd)
|
||||
core.clearCommandBuffer()
|
||||
if s70 == false and k > 15 then
|
||||
return
|
||||
if s70 == false and k > 15 then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -109,8 +109,8 @@ local function main(args)
|
|||
command = 'hf 14a sim -t 1 -u ' .. uid_format
|
||||
msg('Bruteforcing Mifare Classic card numbers')
|
||||
elseif mftype == 'mfc4' then
|
||||
command = 'hf 14a sim -t 8 -u ' .. uid_format
|
||||
msg('Bruteforcing Mifare Classic 4K card numbers')
|
||||
command = 'hf 14a sim -t 8 -u ' .. uid_format
|
||||
msg('Bruteforcing Mifare Classic 4K card numbers')
|
||||
elseif mftype == 'mfu' then
|
||||
command = 'hf 14a sim -t 2 -u ' .. uid_format
|
||||
msg('Bruteforcing Mifare Ultralight card numbers')
|
||||
|
|
|
@ -50,17 +50,17 @@ arguments = [[
|
|||
-c read magic configuration
|
||||
-u UID (8-14 hexsymbols), set UID on tag
|
||||
-t tag type to impersonate
|
||||
1 = Mifare Mini S20 4-byte 12 = NTAG 210
|
||||
2 = Mifare Mini S20 7-byte 13 = NTAG 212
|
||||
3 = Mifare 1k S50 4-byte 14 = NTAG 213
|
||||
4 = Mifare 1k S50 7-byte 15 = NTAG 215
|
||||
5 = Mifare 4k S70 4-byte 16 = NTAG 216
|
||||
6 = Mifare 4k S70 7-byte 17 = NTAG I2C 1K
|
||||
*** 7 = UL - NOT WORKING FULLY 18 = NTAG I2C 2K
|
||||
*** 8 = UL-C - NOT WORKING FULLY 19 = NTAG I2C 1K PLUS
|
||||
9 = UL EV1 48b 20 = NTAG I2C 2K PLUS
|
||||
10 = UL EV1 128b 21 = NTAG 213F
|
||||
*** 11 = UL Plus - NOT WORKING YET 22 = NTAG 216F
|
||||
1 = Mifare Mini S20 4-byte 12 = NTAG 210
|
||||
2 = Mifare Mini S20 7-byte 13 = NTAG 212
|
||||
3 = Mifare 1k S50 4-byte 14 = NTAG 213
|
||||
4 = Mifare 1k S50 7-byte 15 = NTAG 215
|
||||
5 = Mifare 4k S70 4-byte 16 = NTAG 216
|
||||
6 = Mifare 4k S70 7-byte 17 = NTAG I2C 1K
|
||||
*** 7 = UL - NOT WORKING FULLY 18 = NTAG I2C 2K
|
||||
*** 8 = UL-C - NOT WORKING FULLY 19 = NTAG I2C 1K PLUS
|
||||
9 = UL EV1 48b 20 = NTAG I2C 2K PLUS
|
||||
10 = UL EV1 128b 21 = NTAG 213F
|
||||
*** 11 = UL Plus - NOT WORKING YET 22 = NTAG 216F
|
||||
|
||||
-p NTAG password (8 hexsymbols), set NTAG password on tag.
|
||||
-a NTAG pack ( 4 hexsymbols), set NTAG pack on tag.
|
||||
|
@ -178,7 +178,7 @@ local function read_config()
|
|||
if not info then return false, "Can't select card" end
|
||||
-- read Ultimate Magic Card CONFIG
|
||||
if magicconfig == nil then
|
||||
magicconfig = send("CF".._key.."C6")
|
||||
magicconfig = send("CF".._key.."C6")
|
||||
else print('No Config')
|
||||
end
|
||||
-- extract data from CONFIG - based on CONFIG in https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md#gen-4-gtu
|
||||
|
@ -196,92 +196,92 @@ local function read_config()
|
|||
else atsstr = (string.sub(ats, 3))
|
||||
end
|
||||
if ulprotocol == '00' then
|
||||
cardprotocol = 'MIFARE Classic Protocol'
|
||||
ultype = 'Disabled'
|
||||
if uidlength == '00' then
|
||||
uid = send("CF".._key.."CE00"):sub(1,8)
|
||||
if atqaf == '00 04' and sak == '09' then cardtype = 'MIFARE Mini S20 4-byte UID'
|
||||
elseif atqaf == '00 04' and sak == '08' then cardtype = 'MIFARE 1k S50 4-byte UID'
|
||||
elseif atqaf == '00 02' and sak == '18' then cardtype = 'MIFARE 4k S70 4-byte UID'
|
||||
end
|
||||
elseif uidlength == '01' then
|
||||
uid = send("CF".._key.."CE00"):sub(1,14)
|
||||
if atqaf == '00 44' and sak == '09' then cardtype = 'MIFARE Mini S20 7-byte UID'
|
||||
elseif atqaf == '00 44' and sak == '08' then cardtype = 'MIFARE 1k S50 7-byte UID'
|
||||
elseif atqaf == '00 42' and sak == '18' then cardtype = 'MIFARE 4k S70 7-byte UID'
|
||||
end
|
||||
end
|
||||
cardprotocol = 'MIFARE Classic Protocol'
|
||||
ultype = 'Disabled'
|
||||
if uidlength == '00' then
|
||||
uid = send("CF".._key.."CE00"):sub(1,8)
|
||||
if atqaf == '00 04' and sak == '09' then cardtype = 'MIFARE Mini S20 4-byte UID'
|
||||
elseif atqaf == '00 04' and sak == '08' then cardtype = 'MIFARE 1k S50 4-byte UID'
|
||||
elseif atqaf == '00 02' and sak == '18' then cardtype = 'MIFARE 4k S70 4-byte UID'
|
||||
end
|
||||
elseif uidlength == '01' then
|
||||
uid = send("CF".._key.."CE00"):sub(1,14)
|
||||
if atqaf == '00 44' and sak == '09' then cardtype = 'MIFARE Mini S20 7-byte UID'
|
||||
elseif atqaf == '00 44' and sak == '08' then cardtype = 'MIFARE 1k S50 7-byte UID'
|
||||
elseif atqaf == '00 42' and sak == '18' then cardtype = 'MIFARE 4k S70 7-byte UID'
|
||||
end
|
||||
end
|
||||
elseif ulprotocol == '01' then
|
||||
-- Read Ultralight config only if UL protocol is enabled
|
||||
cardprotocol = 'MIFARE Ultralight/NTAG'
|
||||
block0 = send("3000")
|
||||
uid0 = block0:sub(1,6)
|
||||
uid = uid0..block0:sub(9,16)
|
||||
if ulmode == '00' then ultype = 'Ultralight EV1'
|
||||
elseif ulmode == '01' then ultype = 'NTAG21x'
|
||||
elseif ulmode == '02' then ultype = 'Ultralight-C'
|
||||
elseif ulmode == '03' then ultype = 'Ultralight'
|
||||
end
|
||||
-- read VERSION
|
||||
cversion = send('30FA'):sub(1,16)
|
||||
-- pwdblock must be set since the 30F1 and 30F2 special commands don't work on the ntag21x part of the UMC
|
||||
if ulmode == '03' then versionstr = 'Ultralight'
|
||||
elseif ulmode == '02' then versionstr = 'Ultralight-C'
|
||||
elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b'
|
||||
elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b'
|
||||
elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210'
|
||||
elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212'
|
||||
elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213'
|
||||
elseif cversion == '0004040201001103' then versionstr = 'NTAG 215'
|
||||
elseif cversion == '0004040201001303' then versionstr = 'NTAG 216'
|
||||
elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K'
|
||||
elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K'
|
||||
elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS'
|
||||
elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS'
|
||||
elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F'
|
||||
elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F'
|
||||
end
|
||||
-- read PWD
|
||||
cpwd = send("30F0"):sub(1,8)
|
||||
pwd = send("30E5"):sub(1,8)
|
||||
-- 04 response indicates that blocks has been locked down.
|
||||
if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end
|
||||
-- read PACK
|
||||
cpack = send("30F1"):sub(1,4)
|
||||
pack = send("30E6"):sub(1,4)
|
||||
-- read SIGNATURE
|
||||
signature1 = send('30F2'):sub(1,32)
|
||||
signature2 = send('30F6'):sub(1,32)
|
||||
lib14a.disconnect()
|
||||
-- Read Ultralight config only if UL protocol is enabled
|
||||
cardprotocol = 'MIFARE Ultralight/NTAG'
|
||||
block0 = send("3000")
|
||||
uid0 = block0:sub(1,6)
|
||||
uid = uid0..block0:sub(9,16)
|
||||
if ulmode == '00' then ultype = 'Ultralight EV1'
|
||||
elseif ulmode == '01' then ultype = 'NTAG21x'
|
||||
elseif ulmode == '02' then ultype = 'Ultralight-C'
|
||||
elseif ulmode == '03' then ultype = 'Ultralight'
|
||||
end
|
||||
-- read VERSION
|
||||
cversion = send('30FA'):sub(1,16)
|
||||
-- pwdblock must be set since the 30F1 and 30F2 special commands don't work on the ntag21x part of the UMC
|
||||
if ulmode == '03' then versionstr = 'Ultralight'
|
||||
elseif ulmode == '02' then versionstr = 'Ultralight-C'
|
||||
elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b'
|
||||
elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b'
|
||||
elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210'
|
||||
elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212'
|
||||
elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213'
|
||||
elseif cversion == '0004040201001103' then versionstr = 'NTAG 215'
|
||||
elseif cversion == '0004040201001303' then versionstr = 'NTAG 216'
|
||||
elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K'
|
||||
elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K'
|
||||
elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS'
|
||||
elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS'
|
||||
elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F'
|
||||
elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F'
|
||||
end
|
||||
-- read PWD
|
||||
cpwd = send("30F0"):sub(1,8)
|
||||
pwd = send("30E5"):sub(1,8)
|
||||
-- 04 response indicates that blocks has been locked down.
|
||||
if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end
|
||||
-- read PACK
|
||||
cpack = send("30F1"):sub(1,4)
|
||||
pack = send("30E6"):sub(1,4)
|
||||
-- read SIGNATURE
|
||||
signature1 = send('30F2'):sub(1,32)
|
||||
signature2 = send('30F6'):sub(1,32)
|
||||
lib14a.disconnect()
|
||||
end
|
||||
if _print < 1 then
|
||||
print(string.rep('=', 88))
|
||||
print('\t\t\tUltimate Magic Card Configuration')
|
||||
print(string.rep('=', 88))
|
||||
print(' - Raw Config ', string.sub(magicconfig, 1, -9))
|
||||
print(' - Card Protocol ', cardprotocol)
|
||||
print(' - Ultralight Mode ', ultype)
|
||||
print(' - ULM Backdoor Key ', readpass)
|
||||
print(' - GTU Mode ', gtustr)
|
||||
if ulprotocol == '01' then
|
||||
print(' - Card Type ', versionstr)
|
||||
else
|
||||
print(' - Card Type ', cardtype)
|
||||
end
|
||||
print(' - UID ', uid)
|
||||
print(' - ATQA ', atqaf)
|
||||
print(' - SAK ', sak)
|
||||
if ulprotocol == '01' then
|
||||
print('')
|
||||
print(string.rep('=', 88))
|
||||
print('\t\t\tMagic UL/NTAG 21* Configuration')
|
||||
print(string.rep('=', 88))
|
||||
print(' - ATS ', atsstr)
|
||||
print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd)
|
||||
print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack)
|
||||
print(' - Version ', cversion)
|
||||
print(' - Signature ', signature1..signature2)
|
||||
end
|
||||
print(string.rep('=', 88))
|
||||
print('\t\t\tUltimate Magic Card Configuration')
|
||||
print(string.rep('=', 88))
|
||||
print(' - Raw Config ', string.sub(magicconfig, 1, -9))
|
||||
print(' - Card Protocol ', cardprotocol)
|
||||
print(' - Ultralight Mode ', ultype)
|
||||
print(' - ULM Backdoor Key ', readpass)
|
||||
print(' - GTU Mode ', gtustr)
|
||||
if ulprotocol == '01' then
|
||||
print(' - Card Type ', versionstr)
|
||||
else
|
||||
print(' - Card Type ', cardtype)
|
||||
end
|
||||
print(' - UID ', uid)
|
||||
print(' - ATQA ', atqaf)
|
||||
print(' - SAK ', sak)
|
||||
if ulprotocol == '01' then
|
||||
print('')
|
||||
print(string.rep('=', 88))
|
||||
print('\t\t\tMagic UL/NTAG 21* Configuration')
|
||||
print(string.rep('=', 88))
|
||||
print(' - ATS ', atsstr)
|
||||
print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd)
|
||||
print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack)
|
||||
print(' - Version ', cversion)
|
||||
print(' - Signature ', signature1..signature2)
|
||||
end
|
||||
end
|
||||
lib14a.disconnect()
|
||||
return true, 'Ok'
|
||||
|
@ -291,41 +291,41 @@ end
|
|||
local function write_uid(useruid)
|
||||
-- read CONFIG
|
||||
if not magicconfig then
|
||||
_print = 1
|
||||
read_config()
|
||||
_print = 1
|
||||
read_config()
|
||||
end
|
||||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
-- Writes a MFC UID with GEN4 magic commands.
|
||||
if ulprotocol == '00' then
|
||||
-- uid string checks
|
||||
if useruid == nil then return nil, 'empty uid string' end
|
||||
if #useruid == 0 then return nil, 'empty uid string' end
|
||||
if (#useruid ~= 8) and (#useruid ~= 14) then return nil, 'UID wrong length. Should be 4 or 7 hex bytes' end
|
||||
print('Writing new UID ', useruid)
|
||||
local uidbytes = utils.ConvertHexToBytes(useruid)
|
||||
local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), uidbytes[4])
|
||||
local block0 = string.format('%02X%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], uidbytes[4], bcc1)
|
||||
local resp = send('CF'.._key..'CD00'..block0)
|
||||
-- uid string checks
|
||||
if useruid == nil then return nil, 'empty uid string' end
|
||||
if #useruid == 0 then return nil, 'empty uid string' end
|
||||
if (#useruid ~= 8) and (#useruid ~= 14) then return nil, 'UID wrong length. Should be 4 or 7 hex bytes' end
|
||||
print('Writing new UID ', useruid)
|
||||
local uidbytes = utils.ConvertHexToBytes(useruid)
|
||||
local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), uidbytes[4])
|
||||
local block0 = string.format('%02X%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], uidbytes[4], bcc1)
|
||||
local resp = send('CF'.._key..'CD00'..block0)
|
||||
-- Writes a MFUL UID with bcc1, bcc2 using NTAG21xx commands.
|
||||
elseif ulprotocol == '01' then
|
||||
-- uid string checks
|
||||
if useruid == nil then return nil, 'empty uid string' end
|
||||
if #useruid == 0 then return nil, 'empty uid string' end
|
||||
if #useruid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end
|
||||
print('Writing new UID ', useruid)
|
||||
local uidbytes = utils.ConvertHexToBytes(useruid)
|
||||
local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88)
|
||||
local bcc2 = bxor(bxor(bxor(uidbytes[4], uidbytes[5]), uidbytes[6]), uidbytes[7])
|
||||
local block0 = string.format('%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], bcc1)
|
||||
local block1 = string.format('%02X%02X%02X%02X', uidbytes[4], uidbytes[5], uidbytes[6], uidbytes[7])
|
||||
local block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00)
|
||||
local resp
|
||||
resp = send('A200'..block0)
|
||||
resp = send('A201'..block1)
|
||||
resp = send('A202'..block2)
|
||||
-- uid string checks
|
||||
if useruid == nil then return nil, 'empty uid string' end
|
||||
if #useruid == 0 then return nil, 'empty uid string' end
|
||||
if #useruid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end
|
||||
print('Writing new UID ', useruid)
|
||||
local uidbytes = utils.ConvertHexToBytes(useruid)
|
||||
local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88)
|
||||
local bcc2 = bxor(bxor(bxor(uidbytes[4], uidbytes[5]), uidbytes[6]), uidbytes[7])
|
||||
local block0 = string.format('%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], bcc1)
|
||||
local block1 = string.format('%02X%02X%02X%02X', uidbytes[4], uidbytes[5], uidbytes[6], uidbytes[7])
|
||||
local block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00)
|
||||
local resp
|
||||
resp = send('A200'..block0)
|
||||
resp = send('A201'..block1)
|
||||
resp = send('A202'..block2)
|
||||
else
|
||||
print('Incorrect ul')
|
||||
print('Incorrect ul')
|
||||
end
|
||||
lib14a.disconnect()
|
||||
if resp ~= nil then
|
||||
|
@ -339,8 +339,8 @@ end
|
|||
local function write_atqasak(atqasak)
|
||||
-- read CONFIG
|
||||
if not magicconfig then
|
||||
_print = 1
|
||||
read_config()
|
||||
_print = 1
|
||||
read_config()
|
||||
end
|
||||
if atqasak == nil then return nil, 'Empty ATQA/SAK string' end
|
||||
if #atqasak == 0 then return nil, 'Empty ATQA/SAK string' end
|
||||
|
@ -350,25 +350,25 @@ end
|
|||
local atqauserf = atqauser2..atqauser1
|
||||
local sakuser = atqasak:sub(5,6)
|
||||
if sakuser == '04' then
|
||||
print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required')
|
||||
return nil
|
||||
print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required')
|
||||
return nil
|
||||
elseif (sakuser == '20' or sakuser == '28') and atslen == '00' then
|
||||
print('When SAK equals 20 or 28, ATS must be turned on')
|
||||
return nil
|
||||
print('When SAK equals 20 or 28, ATS must be turned on')
|
||||
return nil
|
||||
elseif atqauser2 == '40' then
|
||||
print('ATQA of [00 40] will cause the card to not answer.')
|
||||
return nil
|
||||
print('ATQA of [00 40] will cause the card to not answer.')
|
||||
return nil
|
||||
else
|
||||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser)
|
||||
local resp = send("CF".._key.."35"..atqauserf..sakuser)
|
||||
lib14a.disconnect()
|
||||
if resp == nil then
|
||||
return nil, oops('Failed to write ATQA/SAK')
|
||||
else
|
||||
return true, 'Ok'
|
||||
end
|
||||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser)
|
||||
local resp = send("CF".._key.."35"..atqauserf..sakuser)
|
||||
lib14a.disconnect()
|
||||
if resp == nil then
|
||||
return nil, oops('Failed to write ATQA/SAK')
|
||||
else
|
||||
return true, 'Ok'
|
||||
end
|
||||
end
|
||||
end
|
||||
---
|
||||
|
@ -376,8 +376,8 @@ end
|
|||
local function write_ntagpwd(ntagpwd)
|
||||
-- read CONFIG
|
||||
if not magicconfig then
|
||||
_print = 1
|
||||
read_config()
|
||||
_print = 1
|
||||
read_config()
|
||||
end
|
||||
if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
|
||||
-- PWD string checks
|
||||
|
@ -401,8 +401,8 @@ end
|
|||
local function write_pack(userpack)
|
||||
-- read CONFIG
|
||||
if not magicconfig then
|
||||
_print = 1
|
||||
read_config()
|
||||
_print = 1
|
||||
read_config()
|
||||
end
|
||||
if ulprotocol == 0 then return nil, 'Magic Card is not using the Ultralight Protocol' end
|
||||
-- PACK string checks
|
||||
|
@ -426,8 +426,8 @@ local function write_otp(block3)
|
|||
if #block3 ~= 8 then return nil, 'OTP wrong length. Should be 4 hex bytes' end
|
||||
-- read CONFIG
|
||||
if not magicconfig then
|
||||
_print = 1
|
||||
read_config()
|
||||
_print = 1
|
||||
read_config()
|
||||
end
|
||||
if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
|
||||
local info = connect()
|
||||
|
@ -450,8 +450,8 @@ local function write_version(data)
|
|||
if #data ~= 16 then return nil, 'version wrong length. Should be 8 hex bytes' end
|
||||
-- read CONFIG
|
||||
if not magicconfig then
|
||||
_print = 1
|
||||
read_config()
|
||||
_print = 1
|
||||
read_config()
|
||||
end
|
||||
if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
|
||||
print('Writing new version', data)
|
||||
|
@ -478,8 +478,8 @@ local function write_signature(data)
|
|||
if #data ~= 64 then return nil, 'data wrong length. Should be 32 hex bytes' end
|
||||
-- read CONFIG
|
||||
if not magicconfig then
|
||||
_print = 1
|
||||
read_config()
|
||||
_print = 1
|
||||
read_config()
|
||||
end
|
||||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
|
@ -508,19 +508,19 @@ local function write_gtu(gtu)
|
|||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
if gtu == '00' then
|
||||
print('Enabling GTU Pre-Write')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
print('Enabling GTU Pre-Write')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
elseif gtu == '01' then
|
||||
print('Enabling GTU Restore Mode')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
print('Enabling GTU Restore Mode')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
elseif gtu == '02' then
|
||||
print('Disabled GTU')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
print('Disabled GTU')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
elseif gtu == '03' then
|
||||
print('Disabled GTU, high speed R/W mode for Ultralight')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
print('Disabled GTU, high speed R/W mode for Ultralight')
|
||||
send('CF'.._key..'32'..gtu)
|
||||
else
|
||||
print('Failed to set GTU mode')
|
||||
print('Failed to set GTU mode')
|
||||
end
|
||||
lib14a.disconnect()
|
||||
return true, 'Ok'
|
||||
|
@ -536,13 +536,13 @@ local function write_ats(atsuser)
|
|||
local atscardlendecimal = tonumber(atscardlen, 16)
|
||||
local atsf = string.sub(atsuser, 3)
|
||||
if (#atsf / 2) ~= atscardlendecimal then
|
||||
oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')')
|
||||
return true, 'Ok'
|
||||
oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')')
|
||||
return true, 'Ok'
|
||||
else
|
||||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
print('Writing '..atscardlendecimal..' ATS bytes of '..atsf)
|
||||
send("CF".._key.."34"..atsuser)
|
||||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
print('Writing '..atscardlendecimal..' ATS bytes of '..atsf)
|
||||
send("CF".._key.."34"..atsuser)
|
||||
end
|
||||
lib14a.disconnect()
|
||||
return true, 'Ok'
|
||||
|
@ -556,11 +556,11 @@ local function write_ulp(ulp)
|
|||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
if ulp == '00' then
|
||||
print('Changing card to Mifare Classic Protocol')
|
||||
send("CF".._key.."69"..ulp)
|
||||
print('Changing card to Mifare Classic Protocol')
|
||||
send("CF".._key.."69"..ulp)
|
||||
elseif ulp == '01' then
|
||||
print('Changing card to Ultralight Protocol')
|
||||
send("CF".._key.."69"..ulp)
|
||||
print('Changing card to Ultralight Protocol')
|
||||
send("CF".._key.."69"..ulp)
|
||||
else
|
||||
oops('Protocol needs to be either 00 or 01')
|
||||
end
|
||||
|
@ -576,17 +576,17 @@ local function write_ulm(ulm)
|
|||
local info = connect()
|
||||
if not info then return false, "Can't select card" end
|
||||
if ulm == '00' then
|
||||
print('Changing card UL mode to Ultralight EV1')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
print('Changing card UL mode to Ultralight EV1')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
elseif ulm == '01' then
|
||||
print('Changing card UL mode to NTAG')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
print('Changing card UL mode to NTAG')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
elseif ulm == '02' then
|
||||
print('Changing card UL mode to Ultralight-C')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
print('Changing card UL mode to Ultralight-C')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
elseif ulm == '03' then
|
||||
print('Changing card UL mode to Ultralight')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
print('Changing card UL mode to Ultralight')
|
||||
send("CF".._key.."6A"..ulm)
|
||||
else
|
||||
oops('UL mode needs to be either 00, 01, 02, 03')
|
||||
end
|
||||
|
@ -603,50 +603,50 @@ local function set_type(tagtype)
|
|||
if tagtype == 1 then
|
||||
print('Setting: Ultimate Magic card to Mifare mini S20 4-byte')
|
||||
connect()
|
||||
send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900")
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900")
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233')
|
||||
-- Setting Mifare mini S20 7-byte
|
||||
elseif tagtype == 2 then
|
||||
print('Setting: Ultimate Magic card to Mifare mini S20 7-byte')
|
||||
connect()
|
||||
send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900")
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900")
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
-- Setting Mifare 1k S50 4--byte
|
||||
elseif tagtype == 3 then
|
||||
print('Setting: Ultimate Magic card to Mifare 1k S50 4-byte')
|
||||
connect()
|
||||
send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800")
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800")
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233')
|
||||
-- Setting Mifare 1k S50 7-byte
|
||||
elseif tagtype == 4 then
|
||||
print('Setting: Ultimate Magic card to Mifare 1k S50 7-byte')
|
||||
connect()
|
||||
send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800")
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800")
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
-- Setting Mifare 4k S70 4-byte
|
||||
elseif tagtype == 5 then
|
||||
print('Setting: Ultimate Magic card to Mifare 4k S70 4-byte')
|
||||
connect()
|
||||
send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800")
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800")
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233')
|
||||
-- Setting Mifare 4k S70 7-byte
|
||||
elseif tagtype == 6 then
|
||||
print('Setting: Ultimate Magic card to Mifare 4k S70 7-byte')
|
||||
connect()
|
||||
send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800")
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800")
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
-- Setting UL
|
||||
elseif tagtype == 7 then
|
||||
print('Setting: Ultimate Magic card to UL')
|
||||
connect()
|
||||
send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003")
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003")
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_otp('00000000') -- Setting OTP to default 00 00 00 00
|
||||
write_version('0000000000000000') -- UL-C does not have a version
|
||||
|
@ -654,48 +654,48 @@ local function set_type(tagtype)
|
|||
elseif tagtype == 8 then
|
||||
print('Setting: Ultimate Magic card to UL-C')
|
||||
connect()
|
||||
send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002")
|
||||
print('Setting default permissions and 3des key')
|
||||
send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication
|
||||
send('A22B80000000') -- Auth1 read and write access restricted
|
||||
send('A22C42524541') -- Default 3des key
|
||||
send('A22D4B4D4549')
|
||||
send('A22E46594F55')
|
||||
send('A22F43414E21')
|
||||
lib14a.disconnect()
|
||||
send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002")
|
||||
print('Setting default permissions and 3des key')
|
||||
send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication
|
||||
send('A22B80000000') -- Auth1 read and write access restricted
|
||||
send('A22C42524541') -- Default 3des key
|
||||
send('A22D4B4D4549')
|
||||
send('A22E46594F55')
|
||||
send('A22F43414E21')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_otp('00000000') -- Setting OTP to default 00 00 00 00
|
||||
write_version('0000000000000000') -- UL-C does not have a version
|
||||
elseif tagtype == 9 then
|
||||
print('Setting: Ultimate Magic card to UL-EV1 48')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
|
||||
-- Setting UL-Ev1 default config bl 16,17
|
||||
send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
|
||||
send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
|
||||
send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
|
||||
send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
|
||||
send('a210000000FF')
|
||||
send('a21100050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_otp('00000000') -- Setting OTP to default 00 00 00 00
|
||||
write_version('0004030101000b03') -- UL-EV1 (48) 00 04 03 01 01 00 0b 03
|
||||
elseif tagtype == 10 then
|
||||
print('Setting: Ultimate Magic card to UL-EV1 128')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
|
||||
-- Setting UL-Ev1 default config bl 37,38
|
||||
send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
|
||||
send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
|
||||
send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
|
||||
send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
|
||||
send('a225000000FF')
|
||||
send('a22600050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_otp('00000000') -- Setting OTP to default 00 00 00 00
|
||||
write_version('0004030101000e03') -- UL-EV1 (128) 00 04 03 01 01 00 0e 03
|
||||
elseif tagtype == 12 then
|
||||
print('Setting: Ultimate Magic card to NTAG 210')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG210 default CC block456
|
||||
send('a203e1100600')
|
||||
send('a2040300fe00')
|
||||
|
@ -703,13 +703,13 @@ local function set_type(tagtype)
|
|||
-- Setting cfg1/cfg2
|
||||
send('a210000000FF')
|
||||
send('a21100050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03
|
||||
elseif tagtype == 13 then
|
||||
print('Setting: Ultimate Magic card to NTAG 212')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG212 default CC block456
|
||||
send('a203e1101000')
|
||||
send('a2040103900a')
|
||||
|
@ -717,13 +717,13 @@ local function set_type(tagtype)
|
|||
-- Setting cfg1/cfg2
|
||||
send('a225000000FF')
|
||||
send('a22600050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03
|
||||
elseif tagtype == 14 then
|
||||
print('Setting: Ultimate Magic card to NTAG 213')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG213 default CC block456
|
||||
send('a203e1101200')
|
||||
send('a2040103a00c')
|
||||
|
@ -731,13 +731,13 @@ local function set_type(tagtype)
|
|||
-- setting cfg1/cfg2
|
||||
send('a229000000ff')
|
||||
send('a22a00050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03
|
||||
elseif tagtype == 15 then
|
||||
print('Setting: Ultimate Magic card to NTAG 215')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG215 default CC block456
|
||||
send('a203e1103e00')
|
||||
send('a2040300fe00')
|
||||
|
@ -745,13 +745,13 @@ local function set_type(tagtype)
|
|||
-- setting cfg1/cfg2
|
||||
send('a283000000ff')
|
||||
send('a28400050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03
|
||||
elseif tagtype == 16 then
|
||||
print('Setting: Ultimate Magic card to NTAG 216')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG216 default CC block456
|
||||
send('a203e1106d00')
|
||||
send('a2040300fe00')
|
||||
|
@ -759,56 +759,56 @@ local function set_type(tagtype)
|
|||
-- setting cfg1/cfg2
|
||||
send('a2e3000000ff')
|
||||
send('a2e400050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03
|
||||
elseif tagtype == 17 then
|
||||
print('Setting: Ultimate Magic card to NTAG I2C 1K')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG I2C 1K default CC block456
|
||||
send('a203e1106D00')
|
||||
send('a2040300fe00')
|
||||
send('a20500000000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03
|
||||
elseif tagtype == 18 then
|
||||
print('Setting: Ultimate Magic card to NTAG I2C 2K')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG I2C 2K default CC block456
|
||||
send('a203e110EA00')
|
||||
send('a2040300fe00')
|
||||
send('a20500000000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03
|
||||
elseif tagtype == 19 then
|
||||
print('Setting: Ultimate Magic card to NTAG I2C plus 1K')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG I2C 1K default CC block456
|
||||
send('a203e1106D00')
|
||||
send('a2040300fe00')
|
||||
send('a20500000000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03
|
||||
elseif tagtype == 20 then
|
||||
print('Setting: Ultimate Magic card to NTAG I2C plus 2K')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG I2C 2K default CC block456
|
||||
send('a203e1106D00')
|
||||
send('a2040300fe00')
|
||||
send('a20500000000')
|
||||
write_uid('04112233445566')
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03
|
||||
elseif tagtype == 21 then
|
||||
print('Setting: Ultimate Magic card to NTAG 213F')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG213 default CC block456
|
||||
send('a203e1101200')
|
||||
send('a2040103a00c')
|
||||
|
@ -816,13 +816,13 @@ local function set_type(tagtype)
|
|||
-- setting cfg1/cfg2
|
||||
send('a229000000ff')
|
||||
send('a22a00050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03
|
||||
elseif tagtype == 22 then
|
||||
print('Setting: Ultimate Magic card to NTAG 216F')
|
||||
connect()
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
|
||||
-- Setting NTAG216 default CC block456
|
||||
send('a203e1106d00')
|
||||
send('a2040300fe00')
|
||||
|
@ -830,11 +830,11 @@ local function set_type(tagtype)
|
|||
-- setting cfg1/cfg2
|
||||
send('a2e3000000ff')
|
||||
send('a2e400050000')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
lib14a.disconnect()
|
||||
write_uid('04112233445566')
|
||||
write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03
|
||||
else
|
||||
oops('No matching tag types')
|
||||
oops('No matching tag types')
|
||||
end
|
||||
lib14a.disconnect()
|
||||
if resp == '04' then
|
||||
|
|
|
@ -1384,11 +1384,11 @@ static int CmdHF15WriteAfi(const char *Cmd) {
|
|||
// arg0 (datalen, cmd len? .arg0 == crc?)
|
||||
// arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 )
|
||||
// arg2 (recv == 1 == expect a response)
|
||||
uint8_t read_respone = 1;
|
||||
uint8_t read_response = 1;
|
||||
|
||||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_respone, req, reqlen);
|
||||
SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_response, req, reqlen);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
|
||||
PrintAndLogEx(ERR, "iso15693 timeout");
|
||||
|
|
|
@ -1965,10 +1965,10 @@ int infoHF_EMRTD_offline(const char *path) {
|
|||
strcat(filepath, dg_table[EF_COM].filename);
|
||||
|
||||
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) &&
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) {
|
||||
PrintAndLogEx(ERR, "Failed to read EF_COM");
|
||||
free(filepath);
|
||||
return PM3_ESOFT;
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) {
|
||||
PrintAndLogEx(ERR, "Failed to read EF_COM");
|
||||
free(filepath);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
int res = emrtd_print_ef_com_info(data, datalen);
|
||||
|
@ -1999,9 +1999,9 @@ int infoHF_EMRTD_offline(const char *path) {
|
|||
strcat(filepath, dg_table[EF_CardAccess].filename);
|
||||
|
||||
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) ||
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) {
|
||||
emrtd_print_ef_cardaccess_info(data, datalen);
|
||||
free(data);
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) {
|
||||
emrtd_print_ef_cardaccess_info(data, datalen);
|
||||
free(data);
|
||||
} else {
|
||||
PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE");
|
||||
}
|
||||
|
@ -2011,10 +2011,10 @@ int infoHF_EMRTD_offline(const char *path) {
|
|||
strcat(filepath, dg_table[EF_SOD].filename);
|
||||
|
||||
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) &&
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) {
|
||||
PrintAndLogEx(ERR, "Failed to read EF_SOD");
|
||||
free(filepath);
|
||||
return PM3_ESOFT;
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) {
|
||||
PrintAndLogEx(ERR, "Failed to read EF_SOD");
|
||||
free(filepath);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
// coverity scan CID 395630,
|
||||
|
@ -2040,7 +2040,7 @@ int infoHF_EMRTD_offline(const char *path) {
|
|||
strncat(filepath, PATHSEP, 2);
|
||||
strcat(filepath, dg->filename);
|
||||
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) ||
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) {
|
||||
(loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) {
|
||||
// we won't halt on parsing errors
|
||||
if (dg->parser != NULL) {
|
||||
dg->parser(data, datalen);
|
||||
|
@ -2111,7 +2111,7 @@ static int CmdHFeMRTDDump(const char *Cmd) {
|
|||
if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) {
|
||||
BAC = false;
|
||||
} else {
|
||||
strn_upper((char*)docnum, slen);
|
||||
strn_upper((char *)docnum, slen);
|
||||
if (slen != 9) {
|
||||
// Pad to 9 with <
|
||||
memset(docnum + slen, '<', 9 - slen);
|
||||
|
@ -2144,7 +2144,7 @@ static int CmdHFeMRTDDump(const char *Cmd) {
|
|||
error = true;
|
||||
} else {
|
||||
BAC = true;
|
||||
strn_upper((char*)mrz, slen);
|
||||
strn_upper((char *)mrz, slen);
|
||||
memcpy(docnum, &mrz[0], 9);
|
||||
memcpy(dob, &mrz[13], 6);
|
||||
memcpy(expiry, &mrz[21], 6);
|
||||
|
@ -2213,7 +2213,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) {
|
|||
if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) {
|
||||
BAC = false;
|
||||
} else {
|
||||
strn_upper((char*)docnum, slen);
|
||||
strn_upper((char *)docnum, slen);
|
||||
if (slen != 9) {
|
||||
memset(docnum + slen, '<', 9 - slen);
|
||||
}
|
||||
|
@ -2245,7 +2245,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) {
|
|||
error = true;
|
||||
} else {
|
||||
BAC = true;
|
||||
strn_upper((char*)mrz, slen);
|
||||
strn_upper((char *)mrz, slen);
|
||||
memcpy(docnum, &mrz[0], 9);
|
||||
memcpy(dob, &mrz[13], 6);
|
||||
memcpy(expiry, &mrz[21], 6);
|
||||
|
|
|
@ -228,7 +228,7 @@ static int CmdHFEPAPACESimulate(const char *Cmd) {
|
|||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
// bool use_pc = arg_get_lit(ctx, 1);
|
||||
// uint8_t pwd_type = 0;
|
||||
// uint8_t pwd_type = 0;
|
||||
|
||||
int plen = 0;
|
||||
uint8_t pwd[6] = {0};
|
||||
|
@ -273,7 +273,7 @@ static command_t CommandTable[] = {
|
|||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"},
|
||||
{"replay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"},
|
||||
{"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"},
|
||||
{"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ static bool mf_write_block(const uint8_t *key, uint8_t keytype, uint8_t blockno,
|
|||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) {
|
||||
PrintAndLogEx(FAILED, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
return false;
|
||||
}
|
||||
|
||||
return (resp.oldarg[0] & 0xff);
|
||||
|
@ -3688,8 +3688,6 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
|||
}
|
||||
CLIParserFree(ctx);
|
||||
|
||||
nonces_t data[1];
|
||||
|
||||
sector_t *k_sector = NULL;
|
||||
|
||||
//Validations
|
||||
|
@ -3780,7 +3778,7 @@ static int CmdHF14AMfSim(const char *Cmd) {
|
|||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue;
|
||||
if (!(flags & FLAG_NR_AR_ATTACK)) break;
|
||||
if ((resp.oldarg[0] & 0xffff) != CMD_HF_MIFARE_SIMULATE) break;
|
||||
|
||||
nonces_t data[1];
|
||||
memcpy(data, resp.data.asBytes, sizeof(data));
|
||||
readerAttack(k_sector, k_sectorsCount, data[0], setEmulatorMem, verbose);
|
||||
}
|
||||
|
@ -6915,9 +6913,14 @@ static int CmdHF14AMfView(const char *Cmd) {
|
|||
return res;
|
||||
}
|
||||
|
||||
typedef union UDATA {
|
||||
uint8_t *bytes;
|
||||
mfc_vigik_t *vigik;
|
||||
} UDATA;
|
||||
// allocate memory
|
||||
uint8_t *d = calloc(bytes_read, sizeof(uint8_t));
|
||||
if (d == NULL) {
|
||||
UDATA d;
|
||||
d.bytes = calloc(bytes_read, sizeof(uint8_t));
|
||||
if (d.bytes == NULL) {
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
uint16_t dlen = 0;
|
||||
|
@ -6925,14 +6928,14 @@ static int CmdHF14AMfView(const char *Cmd) {
|
|||
// vigik struture sector 0
|
||||
uint8_t *pdump = dump;
|
||||
|
||||
memcpy(d + dlen, pdump, MFBLOCK_SIZE * 3);
|
||||
memcpy(d.bytes + dlen, pdump, MFBLOCK_SIZE * 3);
|
||||
dlen += MFBLOCK_SIZE * 3;
|
||||
pdump += (MFBLOCK_SIZE * 4); // skip sectortrailer
|
||||
|
||||
// extract memory from MAD sectors
|
||||
for (int i = 0; i <= madlen; i++) {
|
||||
if (0x4910 == mad[i] || 0x4916 == mad[i]) {
|
||||
memcpy(d + dlen, pdump, MFBLOCK_SIZE * 3);
|
||||
memcpy(d.bytes + dlen, pdump, MFBLOCK_SIZE * 3);
|
||||
dlen += MFBLOCK_SIZE * 3;
|
||||
}
|
||||
|
||||
|
@ -6940,8 +6943,8 @@ static int CmdHF14AMfView(const char *Cmd) {
|
|||
}
|
||||
|
||||
// convert_mfc_2_arr(pdump, bytes_read, d, &dlen);
|
||||
vigik_annotate(d);
|
||||
free(d);
|
||||
vigik_annotate(d.vigik);
|
||||
free(d.bytes);
|
||||
}
|
||||
|
||||
free(dump);
|
||||
|
@ -7613,7 +7616,6 @@ static int CmdHF14AMfValue(const char *Cmd) {
|
|||
int64_t decval = (int64_t)arg_get_u64_def(ctx, 5, -1); // Inc by -1 is invalid, so not set.
|
||||
int64_t setval = (int64_t)arg_get_u64_def(ctx, 6, 0x7FFFFFFFFFFFFFFF); // out of bounds (for int32) so not set
|
||||
bool getval = arg_get_lit(ctx, 7);
|
||||
uint8_t block[MFBLOCK_SIZE] = {0x00};
|
||||
int dlen = 0;
|
||||
uint8_t data[16] = {0};
|
||||
CLIGetHexWithReturn(ctx, 9, data, &dlen);
|
||||
|
@ -7621,7 +7623,6 @@ static int CmdHF14AMfValue(const char *Cmd) {
|
|||
|
||||
uint8_t action = 3; // 0 Increment, 1 - Decrement, 2 - Set, 3 - Get, 4 - Decode from data
|
||||
uint32_t value = 0;
|
||||
uint8_t isok = true;
|
||||
|
||||
// Need to check we only have 1 of inc/dec/set and get the value from the selected option
|
||||
int optionsprovided = 0;
|
||||
|
@ -7677,11 +7678,12 @@ static int CmdHF14AMfValue(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (action < 3) {
|
||||
|
||||
uint8_t isok = true;
|
||||
if (g_session.pm3_present == false)
|
||||
return PM3_ENOTTY;
|
||||
|
||||
if (action <= 1) { // increment/decrement value
|
||||
uint8_t block[MFBLOCK_SIZE] = {0x00};
|
||||
memcpy(block, (uint8_t *)&value, 4);
|
||||
uint8_t cmddata[26];
|
||||
memcpy(cmddata, key, sizeof(key)); // Key == 6 data went to 10, so lets offset 9 for inc/dec
|
||||
|
|
|
@ -306,7 +306,7 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) {
|
|||
}
|
||||
|
||||
// ref: https://www.nxp.com/docs/en/application-note/AN12343.pdf p7
|
||||
static nxp_producttype_t getProductType(uint8_t *versionhw) {
|
||||
static nxp_producttype_t getProductType(const uint8_t *versionhw) {
|
||||
|
||||
uint8_t product = versionhw[2];
|
||||
|
||||
|
@ -323,7 +323,7 @@ static nxp_producttype_t getProductType(uint8_t *versionhw) {
|
|||
return DESFIRE_UNKNOWN_PROD;
|
||||
}
|
||||
|
||||
static const char *getProductTypeStr(uint8_t *versionhw) {
|
||||
static const char *getProductTypeStr(const uint8_t *versionhw) {
|
||||
|
||||
uint8_t product = versionhw[2];
|
||||
|
||||
|
|
|
@ -311,7 +311,7 @@ static bool TexcomTK15Decode(uint32_t *implengths, uint32_t implengthslen, char
|
|||
bool prevbit = (implengths[implengthslen - 3] > implengths[implengthslen - 2]);
|
||||
bool thesamebit = (abs(lastimplen - (int)implengths[implengthslen - 3]) < abs(lastimplen - (int)implengths[implengthslen - 2]));
|
||||
|
||||
if (prevbit ^ !thesamebit) {
|
||||
if (prevbit ^ (!thesamebit)) {
|
||||
strcat(bitstring, "10");
|
||||
strcat(cbitstring, "1");
|
||||
} else {
|
||||
|
|
|
@ -292,7 +292,7 @@ static bool topaz_byte_is_locked(uint16_t byteno) {
|
|||
}
|
||||
}
|
||||
|
||||
static int topaz_set_cc_dynamic(uint8_t *data) {
|
||||
static int topaz_set_cc_dynamic(const uint8_t *data) {
|
||||
|
||||
if (data[0] != 0xE1) {
|
||||
topaz_tag.size = TOPAZ_STATIC_MEMORY;
|
||||
|
@ -583,9 +583,7 @@ static void topaz_print_lifecycle_state(uint8_t *data) {
|
|||
// to be done
|
||||
}
|
||||
|
||||
static void printTopazDumpContents(uint8_t *dump, size_t size) {
|
||||
|
||||
topaz_tag_t *t = (topaz_tag_t *)dump;
|
||||
static void printTopazDumpContents(topaz_tag_t *dump) {
|
||||
|
||||
// uses a global var for all
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
@ -608,14 +606,14 @@ static void printTopazDumpContents(uint8_t *dump, size_t size) {
|
|||
PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| %s | %s",
|
||||
i,
|
||||
i,
|
||||
sprint_hex(&t->data_blocks[i][0], 8),
|
||||
sprint_hex(&dump->data_blocks[i][0], 8),
|
||||
lockstr,
|
||||
block_info
|
||||
);
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0D, 0x0D, sprint_hex(&t->data_blocks[0x0D][0], 8), topaz_ks[2]);
|
||||
PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0E, 0x0E, sprint_hex(&t->data_blocks[0x0E][0], 8), topaz_ks[3]);
|
||||
PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0D, 0x0D, sprint_hex(&dump->data_blocks[0x0D][0], 8), topaz_ks[2]);
|
||||
PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0E, 0x0E, sprint_hex(&dump->data_blocks[0x0E][0], 8), topaz_ks[3]);
|
||||
PrintAndLogEx(SUCCESS, "------------+-------------------------+---+------------");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
@ -797,7 +795,7 @@ static int CmdHFTopazDump(const char *Cmd) {
|
|||
if (status != PM3_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
printTopazDumpContents((uint8_t *)&topaz_tag, sizeof(topaz_tag_t));
|
||||
printTopazDumpContents(&topaz_tag);
|
||||
|
||||
bool set_dynamic = false;
|
||||
if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) {
|
||||
|
@ -853,14 +851,17 @@ static int CmdHFTopazView(const char *Cmd) {
|
|||
CLIParserFree(ctx);
|
||||
|
||||
// read dump file
|
||||
uint8_t *dump = NULL;
|
||||
topaz_tag_t *dump = NULL;
|
||||
size_t bytes_read = TOPAZ_MAX_SIZE;
|
||||
int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(topaz_tag_t) + TOPAZ_MAX_SIZE);
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
printTopazDumpContents(dump, bytes_read);
|
||||
if (bytes_read < sizeof(topaz_tag_t)) {
|
||||
free(dump);
|
||||
return PM3_EFAILED;
|
||||
}
|
||||
printTopazDumpContents(dump);
|
||||
|
||||
if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) {
|
||||
|
||||
|
|
|
@ -660,7 +660,6 @@ static int start_drawing_1in54B(uint8_t model_nr, uint8_t *black, uint8_t *red)
|
|||
}
|
||||
|
||||
static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
||||
uint8_t progress;
|
||||
uint8_t step0[2] = {0xcd, 0x0d};
|
||||
uint8_t step1[3] = {0xcd, 0x00, 10}; // select e-paper type and reset e-paper
|
||||
// 4 :2.13inch e-Paper
|
||||
|
@ -687,7 +686,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
// uint8_t step13[2]={0xcd,0x0b}; // Judge whether the power supply is turned off successfully
|
||||
// uint8_t step14[2]={0xcd,0x0c}; // The end of the transmission
|
||||
uint8_t rx[20];
|
||||
uint16_t actrxlen[20], i;
|
||||
uint16_t actrxlen[20];
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0);
|
||||
|
@ -812,6 +811,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
}
|
||||
// 1.54B Data transfer is complete and wait for refresh
|
||||
} else {
|
||||
uint8_t progress;
|
||||
PrintAndLogEx(DEBUG, "Step5: e-paper config2");
|
||||
ret = transceive_blocking(step5, 2, rx, 20, actrxlen, true); // cd 05
|
||||
if (ret != PM3_SUCCESS) {
|
||||
|
@ -831,7 +831,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
}
|
||||
PrintAndLogEx(DEBUG, "Step8: Start data transfer");
|
||||
if (model_nr == M2in13) { // 2.13inch
|
||||
for (i = 0; i < 250; i++) {
|
||||
for (uint16_t i = 0; i < 250; i++) {
|
||||
read_black(i, step8, model_nr, black);
|
||||
ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08
|
||||
if (ret != PM3_SUCCESS) {
|
||||
|
@ -841,7 +841,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||
}
|
||||
} else if (model_nr == M2in9) {
|
||||
for (i = 0; i < 296; i++) {
|
||||
for (uint16_t i = 0; i < 296; i++) {
|
||||
read_black(i, step8, model_nr, black);
|
||||
ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08
|
||||
if (ret != PM3_SUCCESS) {
|
||||
|
@ -851,7 +851,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||
}
|
||||
} else if (model_nr == M4in2) { //4.2inch
|
||||
for (i = 0; i < 150; i++) {
|
||||
for (uint16_t i = 0; i < 150; i++) {
|
||||
read_black(i, step8, model_nr, black);
|
||||
ret = transceive_blocking(step8, 103, rx, 20, actrxlen, true); // cd 08
|
||||
if (ret != PM3_SUCCESS) {
|
||||
|
@ -861,7 +861,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||
}
|
||||
} else if (model_nr == M7in5) { //7.5inch
|
||||
for (i = 0; i < 400; i++) {
|
||||
for (uint16_t i = 0; i < 400; i++) {
|
||||
read_black(i, step8, model_nr, black);
|
||||
ret = transceive_blocking(step8, 123, rx, 20, actrxlen, true); // cd 08
|
||||
if (ret != PM3_SUCCESS) {
|
||||
|
@ -872,7 +872,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
msleep(6);
|
||||
}
|
||||
} else if (model_nr == M2in13B) { //2.13inch B
|
||||
for (i = 0; i < 26; i++) {
|
||||
for (uint16_t i = 0; i < 26; i++) {
|
||||
read_black(i, step8, model_nr, black);
|
||||
ret = transceive_blocking(step8, 109, rx, 20, actrxlen, false); // cd 08
|
||||
if (ret != PM3_SUCCESS) {
|
||||
|
@ -883,7 +883,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
}
|
||||
} else if (model_nr == M7in5HD) { //7.5HD
|
||||
|
||||
for (i = 0; i < 484; i++) {
|
||||
for (uint16_t i = 0; i < 484; i++) {
|
||||
read_black(i, step8, model_nr, black);
|
||||
//memset(&step8[3], 0xf0, 120);
|
||||
ret = transceive_blocking(step8, 123, rx, 20, actrxlen, true); // cd 08
|
||||
|
@ -899,7 +899,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
return ret;
|
||||
}
|
||||
} else if (model_nr == M2in7) { //2.7inch
|
||||
for (i = 0; i < 48; i++) {
|
||||
for (uint16_t i = 0; i < 48; i++) {
|
||||
//read_black(i,step8, model_nr, black);
|
||||
memset(&step8[3], 0xFF, sizeof(step8) - 3);
|
||||
ret = transceive_blocking(step8, 124, rx, 20, actrxlen, true); // cd 08
|
||||
|
@ -925,7 +925,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
}
|
||||
PrintAndLogEx(DEBUG, "Step9b");
|
||||
if (model_nr == M2in7) {
|
||||
for (i = 0; i < 48; i++) {
|
||||
for (uint16_t i = 0; i < 48; i++) {
|
||||
read_black(i, step13, model_nr, black);
|
||||
ret = transceive_blocking(step13, 124, rx, 20, actrxlen, true); //CD 19
|
||||
if (ret != PM3_SUCCESS) {
|
||||
|
@ -935,7 +935,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
|
|||
PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
|
||||
}
|
||||
} else if (model_nr == M2in13B) {
|
||||
for (i = 0; i < 26; i++) {
|
||||
for (uint16_t i = 0; i < 26; i++) {
|
||||
read_red(i, step13, model_nr, red);
|
||||
//memset(&step13[3], 0xfE, 106);
|
||||
ret = transceive_blocking(step13, 109, rx, 20, actrxlen, false);
|
||||
|
|
|
@ -15,77 +15,77 @@
|
|||
#define TIMEOUT 2000
|
||||
|
||||
|
||||
#define c2l(c,l) (l = ((unsigned long)(*((c)++))), \
|
||||
l |= ((unsigned long)(*((c)++))) << 8L, \
|
||||
l |= ((unsigned long)(*((c)++))) << 16L, \
|
||||
l |= ((unsigned long)(*((c)++))) << 24L)
|
||||
#define c2l(c,l) (l = ((unsigned long)(*((c)++))), \
|
||||
l |= ((unsigned long)(*((c)++))) << 8L, \
|
||||
l |= ((unsigned long)(*((c)++))) << 16L, \
|
||||
l |= ((unsigned long)(*((c)++))) << 24L)
|
||||
|
||||
/* NOTE - c is not incremented as per c2l */
|
||||
#define c2ln(c,l1,l2,n) { \
|
||||
c += n; \
|
||||
l1 = l2 = 0; \
|
||||
switch (n) { \
|
||||
case 8: l2 = ((unsigned long)(*(--(c)))) << 24L; \
|
||||
case 7: l2 |= ((unsigned long)(*(--(c)))) << 16L; \
|
||||
case 6: l2 |= ((unsigned long)(*(--(c)))) << 8L; \
|
||||
case 5: l2 |= ((unsigned long)(*(--(c)))); \
|
||||
case 4: l1 = ((unsigned long)(*(--(c)))) << 24L; \
|
||||
case 3: l1 |= ((unsigned long)(*(--(c)))) << 16L; \
|
||||
case 2: l1 |= ((unsigned long)(*(--(c)))) << 8L; \
|
||||
case 1: l1 |= ((unsigned long)(*(--(c)))); \
|
||||
} \
|
||||
}
|
||||
#define c2ln(c,l1,l2,n) { \
|
||||
c += n; \
|
||||
l1 = l2 = 0; \
|
||||
switch (n) { \
|
||||
case 8: l2 = ((unsigned long)(*(--(c)))) << 24L; \
|
||||
case 7: l2 |= ((unsigned long)(*(--(c)))) << 16L; \
|
||||
case 6: l2 |= ((unsigned long)(*(--(c)))) << 8L; \
|
||||
case 5: l2 |= ((unsigned long)(*(--(c)))); \
|
||||
case 4: l1 = ((unsigned long)(*(--(c)))) << 24L; \
|
||||
case 3: l1 |= ((unsigned long)(*(--(c)))) << 16L; \
|
||||
case 2: l1 |= ((unsigned long)(*(--(c)))) << 8L; \
|
||||
case 1: l1 |= ((unsigned long)(*(--(c)))); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define l2c(l,c) (*((c)++) = (uint8_t)(((l)) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 24L) & 0xff))
|
||||
#define l2c(l,c) (*((c)++) = (uint8_t)(((l)) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 24L) & 0xff))
|
||||
|
||||
/* NOTE - c is not incremented as per l2c */
|
||||
#define l2cn(l1,l2,c,n) { \
|
||||
c += n; \
|
||||
switch (n) { \
|
||||
case 8: *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
|
||||
case 7: *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
|
||||
case 6: *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
|
||||
case 5: *(--(c)) = (uint8_t)(((l2)) & 0xff); \
|
||||
case 4: *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
|
||||
case 3: *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
|
||||
case 2: *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
|
||||
case 1: *(--(c)) = (uint8_t)(((l1)) & 0xff); \
|
||||
} \
|
||||
}
|
||||
#define l2cn(l1,l2,c,n) { \
|
||||
c += n; \
|
||||
switch (n) { \
|
||||
case 8: *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
|
||||
case 7: *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
|
||||
case 6: *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
|
||||
case 5: *(--(c)) = (uint8_t)(((l2)) & 0xff); \
|
||||
case 4: *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
|
||||
case 3: *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
|
||||
case 2: *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
|
||||
case 1: *(--(c)) = (uint8_t)(((l1)) & 0xff); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NOTE - c is not incremented as per n2l */
|
||||
#define n2ln(c,l1,l2,n) { \
|
||||
c += n; \
|
||||
l1 = l2 = 0; \
|
||||
switch (n) { \
|
||||
case 8: l2 = ((unsigned long)(*(--(c)))); \
|
||||
case 7: l2 |= ((unsigned long)(*(--(c)))) << 8; \
|
||||
case 6: l2 |= ((unsigned long)(*(--(c)))) << 16; \
|
||||
case 5: l2 |= ((unsigned long)(*(--(c)))) << 24; \
|
||||
case 4: l1 = ((unsigned long)(*(--(c)))); \
|
||||
case 3: l1 |= ((unsigned long)(*(--(c)))) << 8; \
|
||||
case 2: l1 |= ((unsigned long)(*(--(c)))) << 16; \
|
||||
case 1: l1 |= ((unsigned long)(*(--(c)))) << 24; \
|
||||
} \
|
||||
}
|
||||
#define n2ln(c,l1,l2,n) { \
|
||||
c += n; \
|
||||
l1 = l2 = 0; \
|
||||
switch (n) { \
|
||||
case 8: l2 = ((unsigned long)(*(--(c)))); \
|
||||
case 7: l2 |= ((unsigned long)(*(--(c)))) << 8; \
|
||||
case 6: l2 |= ((unsigned long)(*(--(c)))) << 16; \
|
||||
case 5: l2 |= ((unsigned long)(*(--(c)))) << 24; \
|
||||
case 4: l1 = ((unsigned long)(*(--(c)))); \
|
||||
case 3: l1 |= ((unsigned long)(*(--(c)))) << 8; \
|
||||
case 2: l1 |= ((unsigned long)(*(--(c)))) << 16; \
|
||||
case 1: l1 |= ((unsigned long)(*(--(c)))) << 24; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* NOTE - c is not incremented as per l2n */
|
||||
#define l2nn(l1,l2,c,n) { \
|
||||
c+=n; \
|
||||
switch (n) { \
|
||||
case 8: *(--(c)) = (uint8_t)(((l2)) & 0xff); \
|
||||
case 7: *(--(c)) = (uint8_t)(((l2) >> 8) & 0xff); \
|
||||
case 6: *(--(c)) = (uint8_t)(((l2) >> 16) & 0xff); \
|
||||
case 5: *(--(c)) = (uint8_t)(((l2) >> 24) & 0xff); \
|
||||
case 4: *(--(c)) = (uint8_t)(((l1)) & 0xff); \
|
||||
case 3: *(--(c)) = (uint8_t)(((l1) >> 8) & 0xff); \
|
||||
case 2: *(--(c)) = (uint8_t)(((l1) >> 16) & 0xff); \
|
||||
case 1: *(--(c)) = (uint8_t)(((l1) >> 24) & 0xff); \
|
||||
} \
|
||||
}
|
||||
#define l2nn(l1,l2,c,n) { \
|
||||
c+=n; \
|
||||
switch (n) { \
|
||||
case 8: *(--(c)) = (uint8_t)(((l2)) & 0xff); \
|
||||
case 7: *(--(c)) = (uint8_t)(((l2) >> 8) & 0xff); \
|
||||
case 6: *(--(c)) = (uint8_t)(((l2) >> 16) & 0xff); \
|
||||
case 5: *(--(c)) = (uint8_t)(((l2) >> 24) & 0xff); \
|
||||
case 4: *(--(c)) = (uint8_t)(((l1)) & 0xff); \
|
||||
case 3: *(--(c)) = (uint8_t)(((l1) >> 8) & 0xff); \
|
||||
case 2: *(--(c)) = (uint8_t)(((l1) >> 16) & 0xff); \
|
||||
case 1: *(--(c)) = (uint8_t)(((l1) >> 24) & 0xff); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define n2l(c,l) (l = ((unsigned long)(*((c)++))) << 24L, \
|
||||
l |= ((unsigned long)(*((c)++))) << 16L, \
|
||||
|
@ -98,17 +98,17 @@
|
|||
*((c)++) = (uint8_t)(((l)) & 0xff))
|
||||
|
||||
#define C_RC2(n) \
|
||||
t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; \
|
||||
x0 = (t << 1) | (t >> 15); \
|
||||
t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; \
|
||||
x1 = (t << 2) | (t >> 14); \
|
||||
t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; \
|
||||
x2 = (t << 3) | (t >> 13); \
|
||||
t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; \
|
||||
x3 = (t << 5) | (t >> 11);
|
||||
t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; \
|
||||
x0 = (t << 1) | (t >> 15); \
|
||||
t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; \
|
||||
x1 = (t << 2) | (t >> 14); \
|
||||
t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; \
|
||||
x2 = (t << 3) | (t >> 13); \
|
||||
t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; \
|
||||
x3 = (t << 5) | (t >> 11);
|
||||
|
||||
#define RC2_ENCRYPT 1
|
||||
#define RC2_DECRYPT 0
|
||||
#define RC2_ENCRYPT 1
|
||||
#define RC2_DECRYPT 0
|
||||
|
||||
typedef unsigned int RC2_INT;
|
||||
|
||||
|
@ -202,7 +202,7 @@ void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) {
|
|||
void RC2_encrypt(unsigned long *d, RC2_KEY *key) {
|
||||
int i, n;
|
||||
register RC2_INT *p0, *p1;
|
||||
register RC2_INT x0, x1, x2, x3, t;
|
||||
register RC2_INT x0, x1, x2, x3;
|
||||
unsigned long l;
|
||||
|
||||
l = d[0];
|
||||
|
@ -217,7 +217,7 @@ void RC2_encrypt(unsigned long *d, RC2_KEY *key) {
|
|||
|
||||
p0 = p1 = &(key->data[0]);
|
||||
for (;;) {
|
||||
t = (x0 + (x1 & ~x3) + (x2 & x3) + * (p0++)) & 0xffff;
|
||||
register RC2_INT t = (x0 + (x1 & ~x3) + (x2 & x3) + * (p0++)) & 0xffff;
|
||||
x0 = (t << 1) | (t >> 15);
|
||||
t = (x1 + (x2 & ~x0) + (x3 & x0) + * (p0++)) & 0xffff;
|
||||
x1 = (t << 2) | (t >> 14);
|
||||
|
@ -244,7 +244,7 @@ void RC2_encrypt(unsigned long *d, RC2_KEY *key) {
|
|||
void RC2_decrypt(unsigned long *d, RC2_KEY *key) {
|
||||
int i, n;
|
||||
register RC2_INT *p0, *p1;
|
||||
register RC2_INT x0, x1, x2, x3, t;
|
||||
register RC2_INT x0, x1, x2, x3;
|
||||
unsigned long l;
|
||||
|
||||
l = d[0];
|
||||
|
@ -260,7 +260,7 @@ void RC2_decrypt(unsigned long *d, RC2_KEY *key) {
|
|||
p0 = &(key->data[63]);
|
||||
p1 = &(key->data[0]);
|
||||
for (;;) {
|
||||
t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
|
||||
register RC2_INT t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
|
||||
x3 = (t - (x0 & ~x2) - (x1 & x2) - * (p0--)) & 0xffff;
|
||||
t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
|
||||
x2 = (t - (x3 & ~x1) - (x0 & x1) - * (p0--)) & 0xffff;
|
||||
|
@ -533,8 +533,8 @@ static int CmdHFXeroxInfo(const char *Cmd) {
|
|||
packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW);
|
||||
packet->rawlen = 11;
|
||||
packet->raw[0] = 0x02;
|
||||
packet->raw[1] = 0x20; // set command: read mem
|
||||
memcpy(packet->raw + 2, card.uid, 8); // store uid
|
||||
packet->raw[1] = 0x20; // set command: read mem
|
||||
memcpy(packet->raw + 2, card.uid, 8); // store uid
|
||||
|
||||
for (int retry = 0; (retry < 5 && blocknum < sizeof(info_blocks)); retry++) {
|
||||
|
||||
|
@ -623,7 +623,7 @@ static int CmdHFXeroxDump(const char *Cmd) {
|
|||
}
|
||||
|
||||
iso14b_card_select_t card;
|
||||
int status = findXerox(&card, false); // remain RF on
|
||||
int status = findXerox(&card, false); // remain RF on
|
||||
if (status != PM3_SUCCESS) {
|
||||
free(packet);
|
||||
switch_off_field();
|
||||
|
@ -632,20 +632,20 @@ static int CmdHFXeroxDump(const char *Cmd) {
|
|||
|
||||
PrintAndLogEx(INFO, "Reading memory from tag UID " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen));
|
||||
|
||||
int blocknum = 1; // block 0 all zeros
|
||||
int blocknum = 1; // block 0 all zeros
|
||||
uint8_t data[256 * 4] = {0};
|
||||
|
||||
// set up the read command
|
||||
packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW);
|
||||
packet->rawlen = 11;
|
||||
packet->raw[0] = 0x02;
|
||||
memcpy(packet->raw + 2, card.uid, 8); // store uid
|
||||
memcpy(packet->raw + 2, card.uid, 8); // store uid
|
||||
|
||||
PrintAndLogEx(INFO, "." NOLF);
|
||||
|
||||
for (int retry = 0; (retry < 5 && blocknum < 0x100); retry++) {
|
||||
|
||||
packet->raw[1] = (blocknum < 12) ? 0x30 : 0x20; // set command: read ext mem or read mem
|
||||
packet->raw[1] = (blocknum < 12) ? 0x30 : 0x20; // set command: read ext mem or read mem
|
||||
packet->raw[10] = blocknum & 0xFF;
|
||||
|
||||
PacketResponseNG resp;
|
||||
|
@ -657,7 +657,7 @@ static int CmdHFXeroxDump(const char *Cmd) {
|
|||
resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2],
|
||||
resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f');
|
||||
*/
|
||||
if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status
|
||||
if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status
|
||||
PrintAndLogEx(FAILED, "retrying one more time");
|
||||
continue;
|
||||
}
|
||||
|
@ -722,8 +722,8 @@ static int CmdHFXeroxDump(const char *Cmd) {
|
|||
memcpy(k1, k2, sizeof(k1));
|
||||
|
||||
k1[2] = k2[3] ^ data[0x22 * 4 + 0];
|
||||
k1[3] = k2[4] ^ data[0x22 * 4 + 1]; // first_key[7];
|
||||
k1[5] = k2[1] ^ 0x01; // 01 = crypto method? rfid[23][2]
|
||||
k1[3] = k2[4] ^ data[0x22 * 4 + 1]; // first_key[7];
|
||||
k1[5] = k2[1] ^ 0x01; // 01 = crypto method? rfid[23][2]
|
||||
|
||||
RC2_set_key(&exp_key, 8, k1, 64);
|
||||
|
||||
|
@ -747,7 +747,7 @@ static int CmdHFXeroxDump(const char *Cmd) {
|
|||
uint16_t cs, csd;
|
||||
|
||||
// calc checksum
|
||||
for (b = 0, cs = 0; b < sizeof(decr) - 2; b += 2) cs += decr[b] | (decr[b + 1] << 8);
|
||||
for (b = 0, cs = 0; b < sizeof(decr) - 2; b += 2) cs += decr[b] | (decr[b + 1] << 8);
|
||||
cs = ~cs;
|
||||
csd = (decr[7] << 8) | decr[6];
|
||||
|
||||
|
@ -772,7 +772,7 @@ static int CmdHFXeroxDump(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "---------+--------------+----------");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
if (0 == filename[0]) { // generate filename from uid
|
||||
if (0 == filename[0]) { // generate filename from uid
|
||||
/*
|
||||
PrintAndLogEx(INFO, "Using UID as filename");
|
||||
|
||||
|
|
|
@ -592,12 +592,12 @@ static int CmdLCD(const char *Cmd) {
|
|||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
int r_len = 0;
|
||||
uint8_t raw[1] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &r_len);
|
||||
int j = arg_get_int_def(ctx, 2, 1);
|
||||
CLIParserFree(ctx);
|
||||
if (j < 1) {
|
||||
PrintAndLogEx(WARNING, "Count must be larger than zero");
|
||||
return PM3_EINVARG;
|
||||
|
|
|
@ -672,11 +672,6 @@ static int CmdEM410xClone(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
char cardtype[16] = {"T55x7"};
|
||||
if (q5) {
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Preparing to clone EM4102 to " _YELLOW_("%s") " tag with EM Tag ID " _GREEN_("%010" PRIX64) " (RF/%d)", q5 ? "Q5/T5555" : (em ? "EM4305/4469" : "T55x7"), id, clk);
|
||||
|
||||
struct {
|
||||
|
|
|
@ -2025,10 +2025,8 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
|||
size_t idx = 0;
|
||||
// loop though sample buffer
|
||||
while (idx < g_GraphTraceLen) {
|
||||
bool eop = false;
|
||||
bool haveData = false;
|
||||
bool pwd = false;
|
||||
uint32_t tmpValue;
|
||||
|
||||
idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples);
|
||||
size_t pktOffset = idx;
|
||||
|
@ -2044,6 +2042,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
|||
memset(bits.ptr, 0, bits.size);
|
||||
bits.idx = 0;
|
||||
|
||||
bool eop = false;
|
||||
while ((idx < g_GraphTraceLen) && !eop) {
|
||||
CycleWidth = idx;
|
||||
idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples);
|
||||
|
@ -2081,7 +2080,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
|||
pwd = true;
|
||||
cmdText = "Logon";
|
||||
strncpy(blkAddr, " ", sizeof(blkAddr));
|
||||
tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[4], fwd);
|
||||
uint32_t tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[4], fwd);
|
||||
snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
|
||||
}
|
||||
|
||||
|
@ -2089,7 +2088,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
|||
if ((strncmp(bits.ptr, "0101", 4) == 0) && (bits.idx == 56)) {
|
||||
haveData = true;
|
||||
cmdText = "Write";
|
||||
tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
|
||||
uint32_t tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
|
||||
snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
|
||||
if (tmpValue == 2) {
|
||||
pwd = true;
|
||||
|
@ -2103,7 +2102,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
|||
haveData = true;
|
||||
pwd = false;
|
||||
cmdText = "Read";
|
||||
tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
|
||||
uint32_t tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3);
|
||||
snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
|
||||
strncpy(dataText, " ", sizeof(dataText));
|
||||
}
|
||||
|
@ -2114,7 +2113,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
|||
pwd = false;
|
||||
cmdText = "Protect";
|
||||
strncpy(blkAddr, " ", sizeof(blkAddr));
|
||||
tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
|
||||
uint32_t tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
|
||||
snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
|
||||
}
|
||||
|
||||
|
@ -2124,7 +2123,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
|
|||
pwd = false;
|
||||
cmdText = "Disable";
|
||||
strncpy(blkAddr, " ", sizeof(blkAddr));
|
||||
tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
|
||||
uint32_t tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd);
|
||||
snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -404,7 +404,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
|
|||
uint8_t data[MAX_GRAPH_TRACE_LEN] = {0};
|
||||
size_t datasize = getFromGraphBuf(data);
|
||||
|
||||
uint8_t rawbits[4096];
|
||||
uint8_t rawbits[4096] = {0};
|
||||
int rawbit = 0;
|
||||
int worst = 0, worstPos = 0;
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ static int CmdParadoxClone(const char *Cmd) {
|
|||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t blocks[4];
|
||||
uint32_t blocks[4] = {0};
|
||||
|
||||
if (raw_len != 0) {
|
||||
if (raw_len != 12) {
|
||||
|
@ -284,27 +284,27 @@ static int CmdParadoxClone(const char *Cmd) {
|
|||
manchester[3] = 0x55; // Leading zeros back 4 bits once we have the crc (done below)
|
||||
|
||||
// add FC
|
||||
t1 = manchesterEncode2Bytes (fc);
|
||||
t1 = manchesterEncode2Bytes(fc);
|
||||
manchester[4] = (t1 >> 8) & 0xFF;
|
||||
manchester[5] = t1 & 0xFF;
|
||||
|
||||
// add cn
|
||||
t1 = manchesterEncode2Bytes (cn);
|
||||
t1 = manchesterEncode2Bytes(cn);
|
||||
manchester[6] = (t1 >> 24) & 0xFF;
|
||||
manchester[7] = (t1 >> 16) & 0xFF;
|
||||
manchester[8] = (t1 >> 8) & 0xFF;
|
||||
manchester[9] = t1 & 0xFF;
|
||||
|
||||
uint8_t crc = (CRC8Maxim(manchester+1, 9) ^ 0x6) & 0xFF;
|
||||
uint8_t crc = (CRC8Maxim(manchester + 1, 9) ^ 0x6) & 0xFF;
|
||||
|
||||
// add crc
|
||||
t1 = manchesterEncode2Bytes (crc);
|
||||
t1 = manchesterEncode2Bytes(crc);
|
||||
manchester[10] = (t1 >> 8) & 0xFF;
|
||||
manchester[11] = t1 & 0xFF;
|
||||
|
||||
// move left 4 bits left 4 bits - Now that we have the CRC we need to re-align the data.
|
||||
for (int i = 1; i < 12; i++)
|
||||
manchester[i] = (manchester[i] << 4) + (manchester[i+1] >> 4);
|
||||
manchester[i] = (manchester[i] << 4) + (manchester[i + 1] >> 4);
|
||||
|
||||
// Add trailing 1010 (11)
|
||||
manchester[11] |= (1 << 3);
|
||||
|
@ -312,7 +312,7 @@ static int CmdParadoxClone(const char *Cmd) {
|
|||
|
||||
// move into tag blocks
|
||||
for (int i = 0; i < 12; i++)
|
||||
blocks[1 + (i/4)] += (manchester[i] << (8 * (3 - i % 4)));
|
||||
blocks[1 + (i / 4)] += (manchester[i] << (8 * (3 - i % 4)));
|
||||
}
|
||||
|
||||
// Paradox - FSK2a, data rate 50, 3 data blocks
|
||||
|
|
|
@ -2362,7 +2362,7 @@ static int CmdT55xxRestore(const char *Cmd) {
|
|||
}
|
||||
|
||||
// read dump file
|
||||
uint8_t *dump = NULL;
|
||||
uint32_t *dump = NULL;
|
||||
size_t bytes_read = 0;
|
||||
res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (T55x7_BLOCK_COUNT * 4));
|
||||
if (res != PM3_SUCCESS) {
|
||||
|
@ -2387,11 +2387,10 @@ static int CmdT55xxRestore(const char *Cmd) {
|
|||
snprintf(pwdopt, sizeof(pwdopt), "-p %08X", password);
|
||||
}
|
||||
|
||||
uint32_t *data = (uint32_t *) dump;
|
||||
uint8_t idx;
|
||||
// Restore endien for writing to card
|
||||
for (idx = 0; idx < 12; idx++) {
|
||||
data[idx] = BSWAP_32(data[idx]);
|
||||
dump[idx] = BSWAP_32(dump[idx]);
|
||||
}
|
||||
|
||||
// Have data ready, lets write
|
||||
|
@ -2400,12 +2399,12 @@ static int CmdT55xxRestore(const char *Cmd) {
|
|||
// write blocks 1..3 page 1
|
||||
// update downlink mode (if needed) and write b 0
|
||||
downlink_mode = 0;
|
||||
if ((((data[11] >> 28) & 0xF) == 6) || (((data[11] >> 28) & 0xF) == 9))
|
||||
downlink_mode = (data[11] >> 10) & 3;
|
||||
if ((((dump[11] >> 28) & 0xF) == 6) || (((dump[11] >> 28) & 0xF) == 9))
|
||||
downlink_mode = (dump[11] >> 10) & 3;
|
||||
|
||||
// write out blocks 1-7 page 0
|
||||
for (idx = 1; idx <= 7; idx++) {
|
||||
snprintf(wcmd, sizeof(wcmd), "-b %d -d %08X %s", idx, data[idx], pwdopt);
|
||||
snprintf(wcmd, sizeof(wcmd), "-b %d -d %08X %s", idx, dump[idx], pwdopt);
|
||||
|
||||
if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx);
|
||||
|
@ -2414,12 +2413,12 @@ static int CmdT55xxRestore(const char *Cmd) {
|
|||
|
||||
// if password was set on the "blank" update as we may have just changed it
|
||||
if (usepwd) {
|
||||
snprintf(pwdopt, sizeof(pwdopt), "-p %08X", data[7]);
|
||||
snprintf(pwdopt, sizeof(pwdopt), "-p %08X", dump[7]);
|
||||
}
|
||||
|
||||
// write out blocks 1-3 page 1
|
||||
for (idx = 9; idx <= 11; idx++) {
|
||||
snprintf(wcmd, sizeof(wcmd), "-b %d --pg1 -d %08X %s", idx - 8, data[idx], pwdopt);
|
||||
snprintf(wcmd, sizeof(wcmd), "-b %d --pg1 -d %08X %s", idx - 8, dump[idx], pwdopt);
|
||||
|
||||
if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx);
|
||||
|
@ -2430,7 +2429,7 @@ static int CmdT55xxRestore(const char *Cmd) {
|
|||
config.downlink_mode = downlink_mode;
|
||||
|
||||
// Write the page 0 config
|
||||
snprintf(wcmd, sizeof(wcmd), "-b 0 -d %08X %s", data[0], pwdopt);
|
||||
snprintf(wcmd, sizeof(wcmd), "-b 0 -d %08X %s", dump[0], pwdopt);
|
||||
if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Warning: error writing blk 0");
|
||||
}
|
||||
|
@ -4012,7 +4011,6 @@ static int CmdT55xxSniff(const char *Cmd) {
|
|||
size_t idx = 0;
|
||||
uint32_t usedPassword, blockData;
|
||||
int pulseSamples = 0, pulseIdx = 0;
|
||||
const char *modeText;
|
||||
char pwdText[100];
|
||||
char dataText[100];
|
||||
int pulseBuffer[80] = { 0 }; // max should be 73 +/- - Holds Pulse widths
|
||||
|
@ -4038,7 +4036,7 @@ static int CmdT55xxSniff(const char *Cmd) {
|
|||
int maxWidth = 0;
|
||||
data[0] = 0;
|
||||
bool have_data = false;
|
||||
modeText = "Default";
|
||||
const char *modeText = "Default";
|
||||
strncpy(pwdText, " ", sizeof(pwdText));
|
||||
strncpy(dataText, " ", sizeof(dataText));
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static const struct piv_container PIV_CONTAINERS[] = {
|
|||
{0x0100, PIV_TAG_ID("\x5F\xC1\x0A"), 3, PIV_CONDITIONAL, "X.509 Certificate for Digital Signature (key ref 9C)"},
|
||||
{0x0102, PIV_TAG_ID("\x5F\xC1\x0B"), 3, PIV_CONDITIONAL, "X.509 Certificate for Key Management (key ref 9D)"},
|
||||
{0x3001, PIV_TAG_ID("\x5F\xC1\x09"), 3, PIV_OPTIONAL, "Printed Information"},
|
||||
{0x6050, PIV_TAG_ID( "\x7E"), 1, PIV_OPTIONAL, "Discovery Object"},
|
||||
{0x6050, PIV_TAG_ID("\x7E"), 1, PIV_OPTIONAL, "Discovery Object"},
|
||||
{0x6060, PIV_TAG_ID("\x5F\xC1\x0C"), 3, PIV_OPTIONAL, "Key History Object"},
|
||||
{0x1001, PIV_TAG_ID("\x5F\xC1\x0D"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 1 (key ref 82)"},
|
||||
{0x1002, PIV_TAG_ID("\x5F\xC1\x0E"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 2 (key ref 83)"},
|
||||
|
@ -89,7 +89,7 @@ static const struct piv_container PIV_CONTAINERS[] = {
|
|||
{0x1013, PIV_TAG_ID("\x5F\xC1\x1F"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 19 (key ref 94)"},
|
||||
{0x1014, PIV_TAG_ID("\x5F\xC1\x20"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 20 (key ref 95)"},
|
||||
{0x1015, PIV_TAG_ID("\x5F\xC1\x21"), 3, PIV_OPTIONAL, "Cardholder Iris Images"},
|
||||
{0x1016, PIV_TAG_ID( "\x7F\x61"), 2, PIV_OPTIONAL, "Biometric Information Templates Group Template"},
|
||||
{0x1016, PIV_TAG_ID("\x7F\x61"), 2, PIV_OPTIONAL, "Biometric Information Templates Group Template"},
|
||||
{0x1017, PIV_TAG_ID("\x5F\xC1\x22"), 3, PIV_OPTIONAL, "Secure Messaging Certificate Signer"},
|
||||
{0x1018, PIV_TAG_ID("\x5F\xC1\x23"), 3, PIV_OPTIONAL, "Pairing Code Reference Data Container"},
|
||||
PIV_CONTAINER_FINISH,
|
||||
|
@ -493,13 +493,13 @@ static void piv_print_cb(void *data, const struct tlv *tlv, int level, bool is_l
|
|||
}
|
||||
}
|
||||
|
||||
static void PrintTLV(const struct tlvdb* tlvdb) {
|
||||
static void PrintTLV(const struct tlvdb *tlvdb) {
|
||||
if (tlvdb) {
|
||||
tlvdb_visit(tlvdb, piv_print_cb, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintTLVFromBuffer(const uint8_t* buf, size_t len) {
|
||||
static void PrintTLVFromBuffer(const uint8_t *buf, size_t len) {
|
||||
if (buf == NULL || len == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -598,7 +598,7 @@ static int PivGetData(Iso7816CommandChannel channel, const uint8_t tag[], size_t
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int PivGetDataByCidAndPrint(Iso7816CommandChannel channel, const struct piv_container* cid, bool decodeTLV, bool verbose) {
|
||||
static int PivGetDataByCidAndPrint(Iso7816CommandChannel channel, const struct piv_container *cid, bool decodeTLV, bool verbose) {
|
||||
struct tlvdb_root *root = NULL;
|
||||
|
||||
if (cid == NULL) {
|
||||
|
@ -940,9 +940,8 @@ static int CmdPIVScan(const char *Cmd) {
|
|||
memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET));
|
||||
aid_len = sizeof(PIV_APPLET);
|
||||
}
|
||||
int res = 0;
|
||||
if (activateField == true) {
|
||||
res = PivSelect(channel, activateField, true, decodeTLV, true, applet_id, aid_len);
|
||||
int res = PivSelect(channel, activateField, true, decodeTLV, true, applet_id, aid_len);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (leaveSignalON == false) {
|
||||
DropFieldEx(channel);
|
||||
|
|
|
@ -485,8 +485,6 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
uint32_t end_of_transmission_timestamp = 0;
|
||||
uint8_t topaz_reader_command[9];
|
||||
char explanation[40] = {0};
|
||||
uint8_t mfData[32] = {0};
|
||||
size_t mfDataLen = 0;
|
||||
tracelog_hdr_t *first_hdr = (tracelog_hdr_t *)(trace);
|
||||
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos);
|
||||
|
||||
|
@ -871,6 +869,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
|
|||
}
|
||||
|
||||
if (protocol == PROTO_MIFARE) {
|
||||
uint8_t mfData[32] = {0};
|
||||
size_t mfDataLen = 0;
|
||||
if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen, mfDicKeys, mfDicKeysCount)) {
|
||||
memset(explanation, 0x00, sizeof(explanation));
|
||||
annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen, hdr->isResponse);
|
||||
|
|
|
@ -381,8 +381,6 @@ static int EMVCheckAID(Iso7816CommandChannel channel, bool decodeTLV, struct tlv
|
|||
int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) {
|
||||
uint8_t data[APDU_RES_LEN] = {0};
|
||||
size_t datalen = 0;
|
||||
uint8_t sfidata[0x11][APDU_RES_LEN];
|
||||
size_t sfidatalen[0x11] = {0};
|
||||
uint16_t sw = 0;
|
||||
int res;
|
||||
const char *PSE_or_PPSE = PSENum == 1 ? "PSE" : "PPSE";
|
||||
|
@ -402,6 +400,8 @@ int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFi
|
|||
// PSE/PPSE with SFI
|
||||
struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]) {0x6f, 0xa5, 0x88, 0x00});
|
||||
if (tsfi) {
|
||||
uint8_t sfidata[0x11][APDU_RES_LEN];
|
||||
size_t sfidatalen[0x11] = {0};
|
||||
uint8_t sfin = 0;
|
||||
tlv_get_uint8(tlvdb_get_tlv(tsfi), &sfin);
|
||||
PrintAndLogEx(INFO, "* PPSE get SFI: 0x%02x.", sfin);
|
||||
|
@ -669,10 +669,6 @@ static const unsigned char default_ddol_value[] = {0x9f, 0x37, 0x04};
|
|||
static struct tlv default_ddol_tlv = {.tag = 0x9f49, .len = 3, .value = default_ddol_value };
|
||||
|
||||
int trDDA(Iso7816CommandChannel channel, bool decodeTLV, struct tlvdb *tlv) {
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
uint16_t sw = 0;
|
||||
|
||||
struct emv_pk *pk = get_ca_pk(tlv);
|
||||
if (!pk) {
|
||||
PrintAndLogEx(ERR, "Error: Key not found, exiting");
|
||||
|
@ -767,6 +763,9 @@ int trDDA(Iso7816CommandChannel channel, bool decodeTLV, struct tlvdb *tlv) {
|
|||
tlvdb_free(atc_db);
|
||||
|
||||
} else {
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
uint16_t sw = 0;
|
||||
struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv);
|
||||
if (dac_db) {
|
||||
const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL);
|
||||
|
|
|
@ -258,7 +258,7 @@ static size_t path_size(savePaths_t a) {
|
|||
if (a == spItemCount) {
|
||||
return 0;
|
||||
}
|
||||
return strlen( g_session.defaultPaths[a] );
|
||||
return strlen(g_session.defaultPaths[a]);
|
||||
}
|
||||
|
||||
char *newfilenamemcopy(const char *preferredName, const char *suffix) {
|
||||
|
@ -1162,12 +1162,18 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
goto out;
|
||||
}
|
||||
|
||||
uint8_t *udata = (uint8_t *)data;
|
||||
typedef union UDATA {
|
||||
void *v;
|
||||
uint8_t *bytes;
|
||||
mfu_dump_t *mfu;
|
||||
topaz_tag_t *topaz;
|
||||
} UDATA;
|
||||
UDATA udata = (UDATA)data;
|
||||
char ctype[100] = {0};
|
||||
JsonLoadStr(root, "$.FileType", ctype);
|
||||
|
||||
if (!strcmp(ctype, "raw")) {
|
||||
JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen);
|
||||
JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen);
|
||||
}
|
||||
|
||||
if (!strcmp(ctype, "mfcard")) {
|
||||
|
@ -1187,7 +1193,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
goto out;
|
||||
}
|
||||
|
||||
memcpy(&udata[sptr], block, 16);
|
||||
memcpy(&udata.bytes[sptr], block, 16);
|
||||
sptr += len;
|
||||
}
|
||||
|
||||
|
@ -1206,7 +1212,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
snprintf(blocks, sizeof(blocks), "$.blocks.%d", i);
|
||||
|
||||
size_t len = 0;
|
||||
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len);
|
||||
JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
|
@ -1218,18 +1224,16 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
|
||||
if (!strcmp(ctype, "mfu")) {
|
||||
|
||||
mfu_dump_t *mem = (mfu_dump_t *)udata;
|
||||
|
||||
JsonLoadBufAsHex(root, "$.Card.Version", mem->version, sizeof(mem->version), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.TBO_0", mem->tbo, sizeof(mem->tbo), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.TBO_1", mem->tbo1, sizeof(mem->tbo1), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Signature", mem->signature, sizeof(mem->signature), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Counter0", &mem->counter_tearing[0][0], 3, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Tearing0", &mem->counter_tearing[0][3], 1, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Counter1", &mem->counter_tearing[1][0], 3, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Tearing1", &mem->counter_tearing[1][3], 1, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Counter2", &mem->counter_tearing[2][0], 3, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Tearing2", &mem->counter_tearing[2][3], 1, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Version", udata.mfu->version, sizeof(udata.mfu->version), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.TBO_0", udata.mfu->tbo, sizeof(udata.mfu->tbo), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.TBO_1", udata.mfu->tbo1, sizeof(udata.mfu->tbo1), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Signature", udata.mfu->signature, sizeof(udata.mfu->signature), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Counter0", &udata.mfu->counter_tearing[0][0], 3, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Tearing0", &udata.mfu->counter_tearing[0][3], 1, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Counter1", &udata.mfu->counter_tearing[1][0], 3, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Tearing1", &udata.mfu->counter_tearing[1][3], 1, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Counter2", &udata.mfu->counter_tearing[2][0], 3, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Tearing2", &udata.mfu->counter_tearing[2][3], 1, datalen);
|
||||
*datalen = MFU_DUMP_PREFIX_LENGTH;
|
||||
|
||||
size_t sptr = 0;
|
||||
|
@ -1243,15 +1247,15 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
snprintf(blocks, sizeof(blocks), "$.blocks.%d", i);
|
||||
|
||||
size_t len = 0;
|
||||
JsonLoadBufAsHex(root, blocks, &mem->data[sptr], MFU_BLOCK_SIZE, &len);
|
||||
JsonLoadBufAsHex(root, blocks, &udata.mfu->data[sptr], MFU_BLOCK_SIZE, &len);
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
sptr += len;
|
||||
mem->pages++;
|
||||
udata.mfu->pages++;
|
||||
}
|
||||
// remove one, since pages indicates a index rather than number of available pages
|
||||
--mem->pages;
|
||||
--udata.mfu->pages;
|
||||
|
||||
*datalen += sptr;
|
||||
}
|
||||
|
@ -1268,7 +1272,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
|
||||
|
||||
size_t len = 0;
|
||||
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len);
|
||||
JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
|
@ -1290,7 +1294,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
|
||||
|
||||
size_t len = 0;
|
||||
JsonLoadBufAsHex(root, blocks, &udata[sptr], 8, &len);
|
||||
JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 8, &len);
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
|
@ -1311,7 +1315,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
|
||||
|
||||
size_t len = 0;
|
||||
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len);
|
||||
JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
|
@ -1332,7 +1336,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
|
||||
|
||||
size_t len = 0;
|
||||
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len);
|
||||
JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
|
@ -1342,19 +1346,18 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
}
|
||||
|
||||
if (!strcmp(ctype, "15693")) {
|
||||
JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen);
|
||||
JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen);
|
||||
}
|
||||
|
||||
if (!strcmp(ctype, "legic")) {
|
||||
JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen);
|
||||
JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen);
|
||||
}
|
||||
|
||||
if (!strcmp(ctype, "topaz")) {
|
||||
|
||||
topaz_tag_t *mem = (topaz_tag_t *)udata;
|
||||
JsonLoadBufAsHex(root, "$.Card.UID", mem->uid, sizeof(mem->uid), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.HR01", mem->HR01, sizeof(mem->HR01), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *) & (mem->size), 2, datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.UID", udata.topaz->uid, sizeof(udata.topaz->uid), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.HR01", udata.topaz->HR01, sizeof(udata.topaz->HR01), datalen);
|
||||
JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *) & (udata.topaz->size), 2, datalen);
|
||||
|
||||
size_t sptr = 0;
|
||||
for (int i = 0; i < (TOPAZ_STATIC_MEMORY / 8); i++) {
|
||||
|
@ -1368,7 +1371,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
|||
snprintf(blocks, sizeof(blocks), "$.blocks.%d", i);
|
||||
|
||||
size_t len = 0;
|
||||
JsonLoadBufAsHex(root, blocks, &mem->data_blocks[sptr][0], TOPAZ_BLOCK_SIZE, &len);
|
||||
JsonLoadBufAsHex(root, blocks, &udata.topaz->data_blocks[sptr][0], TOPAZ_BLOCK_SIZE, &len);
|
||||
if (!len)
|
||||
break;
|
||||
|
||||
|
|
|
@ -440,7 +440,8 @@ int APDUDecode(uint8_t *data, int len, APDU_t *apdu) {
|
|||
int APDUEncode(APDU_t *apdu, uint8_t *data, int *len) {
|
||||
if (len)
|
||||
*len = 0;
|
||||
|
||||
if (apdu == NULL)
|
||||
return 1;
|
||||
if (apdu->le > 0x10000)
|
||||
return 1;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ typedef struct {
|
|||
KEY_TYPE key, const char* defaultValue) { \
|
||||
struct _ksx6924_enum_ ## KEY_TYPE *r = bsearch( \
|
||||
&key, KSX6924_ENUM_ ## NAME, \
|
||||
sizeof(KSX6924_ENUM_ ## NAME) / sizeof(KSX6924_ENUM_ ## NAME [0]), \
|
||||
ARRAYLEN(KSX6924_ENUM_ ## NAME), \
|
||||
sizeof(KSX6924_ENUM_ ## NAME [0]), \
|
||||
_ksx6924_ ## KEY_TYPE ## _enum_compare); \
|
||||
if (r == NULL) { \
|
||||
|
|
|
@ -2301,9 +2301,9 @@ static const char *GetDesfireKeyType(uint8_t keytype) {
|
|||
}
|
||||
|
||||
const char *GetDesfireAccessRightStr(uint8_t right) {
|
||||
static char int_access_str[200];
|
||||
|
||||
if (right <= 0x0d) {
|
||||
static char int_access_str[200];
|
||||
snprintf(int_access_str, sizeof(int_access_str), "key 0x%02x", right);
|
||||
return int_access_str;
|
||||
}
|
||||
|
|
|
@ -1499,7 +1499,7 @@ static void reverse_array(const uint8_t *src, int src_len, uint8_t *dest) {
|
|||
}
|
||||
};
|
||||
|
||||
int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) {
|
||||
int vigik_verify(mfc_vigik_t *d) {
|
||||
|
||||
// iso9796
|
||||
// Exponent V = 2
|
||||
|
@ -1507,16 +1507,16 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
|
|||
|
||||
if (g_debugMode == DEBUG) {
|
||||
PrintAndLogEx(INFO, "Raw");
|
||||
print_hex_noascii_break(uid, uidlen, MFBLOCK_SIZE * 2);
|
||||
print_hex_noascii_break((uint8_t *)d, sizeof(*d) - sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
||||
|
||||
PrintAndLogEx(INFO, "Raw signature");
|
||||
print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2);
|
||||
print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
||||
}
|
||||
uint8_t rev_sig[128];
|
||||
reverse_array(signature, signature_len, rev_sig);
|
||||
reverse_array(d->rsa_signature, sizeof(d->rsa_signature), rev_sig);
|
||||
|
||||
PrintAndLogEx(INFO, "Raw signature reverse");
|
||||
print_hex_noascii_break(rev_sig, signature_len, MFBLOCK_SIZE * 2);
|
||||
print_hex_noascii_break(rev_sig, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
||||
|
||||
// t = 0xBC = Implicitly known
|
||||
// t = 0xCC = look at byte before to determine hash function
|
||||
|
@ -1563,10 +1563,10 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
|
|||
mbedtls_mpi_init(&sqr);
|
||||
mbedtls_mpi_init(&res);
|
||||
|
||||
mbedtls_mpi_read_binary(&N, (const unsigned char*)n, PUBLIC_VIGIK_KEYLEN);
|
||||
mbedtls_mpi_read_binary(&N, (const unsigned char *)n, PUBLIC_VIGIK_KEYLEN);
|
||||
|
||||
//mbedtls_mpi_read_binary(&s, (const unsigned char*)signature, signature_len);
|
||||
mbedtls_mpi_read_binary(&s, (const unsigned char*)rev_sig, signature_len);
|
||||
mbedtls_mpi_read_binary(&s, (const unsigned char *)rev_sig, sizeof(d->rsa_signature));
|
||||
|
||||
// check is sign < (N/2)
|
||||
|
||||
|
@ -1574,7 +1574,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
|
|||
mbedtls_mpi_init(&n_2);
|
||||
mbedtls_mpi_copy(&n_2, &N);
|
||||
mbedtls_mpi_shift_r(&n_2, 1);
|
||||
bool is_less = (mbedtls_mpi_cmp_mpi(&s, &n_2) > 0) ? false : true;
|
||||
bool is_less = (mbedtls_mpi_cmp_mpi(&s, &n_2) > 0) ? false : true;
|
||||
PrintAndLogEx(DEBUG, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO"));
|
||||
mbedtls_mpi_free(&n_2);
|
||||
|
||||
|
@ -1644,10 +1644,10 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
|
|||
|
||||
PrintAndLogEx(DEBUG, "LSB............ " _GREEN_("%u"), lsb);
|
||||
if (g_debugMode == DEBUG) {
|
||||
mbedtls_mpi_write_file( "[=] N.............. ", &N, 16, NULL );
|
||||
mbedtls_mpi_write_file( "[=] signature...... ", &s, 16, NULL );
|
||||
mbedtls_mpi_write_file( "[=] square mod n... ", &sqr, 16, NULL );
|
||||
mbedtls_mpi_write_file( "[=] n-fs........... ", &res, 16, NULL );
|
||||
mbedtls_mpi_write_file("[=] N.............. ", &N, 16, NULL);
|
||||
mbedtls_mpi_write_file("[=] signature...... ", &s, 16, NULL);
|
||||
mbedtls_mpi_write_file("[=] square mod n... ", &sqr, 16, NULL);
|
||||
mbedtls_mpi_write_file("[=] n-fs........... ", &res, 16, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1656,9 +1656,9 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
|
|||
|
||||
// xor 0xDC01
|
||||
int count_zero = 0;
|
||||
for (int x = 0; x < sizeof(nfs); x +=2) {
|
||||
for (int x = 0; x < sizeof(nfs); x += 2) {
|
||||
nfs[x] ^= 0xDC;
|
||||
nfs[x+1] ^= 0x01;
|
||||
nfs[x + 1] ^= 0x01;
|
||||
|
||||
if (nfs[x] == 0x00)
|
||||
count_zero++;
|
||||
|
@ -1725,7 +1725,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
|
|||
|
||||
if (is_valid == false || i == ARRAYLEN(vigik_rsa_pk)) {
|
||||
PrintAndLogEx(INFO, "Signature:");
|
||||
print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2);
|
||||
print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
||||
PrintAndLogEx(SUCCESS, "Signature verification: " _RED_("failed"));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
@ -1738,37 +1738,35 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
|
|||
PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 192);
|
||||
|
||||
PrintAndLogEx(INFO, "Signature:");
|
||||
print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2);
|
||||
print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Signature verification: " _GREEN_("successful"));
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int vigik_annotate(uint8_t *d) {
|
||||
int vigik_annotate(mfc_vigik_t *d) {
|
||||
if (d == NULL)
|
||||
return PM3_EINVARG;
|
||||
|
||||
mfc_vigik_t *foo = (mfc_vigik_t*)d;
|
||||
|
||||
PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(foo->b0, sizeof(foo->b0)));
|
||||
PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(foo->mad, sizeof(foo->mad)));
|
||||
PrintAndLogEx(INFO, "Counters............ %u", foo->counters);
|
||||
PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(foo->rtf, sizeof(foo->rtf)));
|
||||
PrintAndLogEx(INFO, "Service code........ 0x%08x / %u - " _YELLOW_("%s"), foo->service_code, foo->service_code, vigik_get_service(foo->service_code));
|
||||
PrintAndLogEx(INFO, "Info flag........... %u -", foo->info_flag); // , sprint_bin(foo->info_flag, 1));
|
||||
PrintAndLogEx(INFO, "Key version......... %u", foo->key_version);
|
||||
PrintAndLogEx(INFO, "PTR Counter......... %u", foo->ptr_counter);
|
||||
PrintAndLogEx(INFO, "Counter num......... %u", foo->counter_num);
|
||||
PrintAndLogEx(INFO, "Slot access date.... %s", sprint_hex(foo->slot_access_date, sizeof(foo->slot_access_date)));
|
||||
PrintAndLogEx(INFO, "Slot dst duration... %u", foo->slot_dst_duration);
|
||||
PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(foo->other_slots, sizeof(foo->other_slots)));
|
||||
PrintAndLogEx(INFO, "Services counter.... %u", foo->services_counter);
|
||||
PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(foo->loading_date, sizeof(foo->loading_date)));
|
||||
PrintAndLogEx(INFO, "Reserved null....... %u", foo->reserved_null);
|
||||
PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(d->b0, sizeof(d->b0)));
|
||||
PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(d->mad, sizeof(d->mad)));
|
||||
PrintAndLogEx(INFO, "Counters............ %u", d->counters);
|
||||
PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(d->rtf, sizeof(d->rtf)));
|
||||
PrintAndLogEx(INFO, "Service code........ 0x%08x / %u - " _YELLOW_("%s"), d->service_code, d->service_code, vigik_get_service(d->service_code));
|
||||
PrintAndLogEx(INFO, "Info flag........... %u -", d->info_flag); // , sprint_bin(d->info_flag, 1));
|
||||
PrintAndLogEx(INFO, "Key version......... %u", d->key_version);
|
||||
PrintAndLogEx(INFO, "PTR Counter......... %u", d->ptr_counter);
|
||||
PrintAndLogEx(INFO, "Counter num......... %u", d->counter_num);
|
||||
PrintAndLogEx(INFO, "Slot access date.... %s", sprint_hex(d->slot_access_date, sizeof(d->slot_access_date)));
|
||||
PrintAndLogEx(INFO, "Slot dst duration... %u", d->slot_dst_duration);
|
||||
PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(d->other_slots, sizeof(d->other_slots)));
|
||||
PrintAndLogEx(INFO, "Services counter.... %u", d->services_counter);
|
||||
PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(d->loading_date, sizeof(d->loading_date)));
|
||||
PrintAndLogEx(INFO, "Reserved null....... %u", d->reserved_null);
|
||||
PrintAndLogEx(INFO, "----------------------------------------------------------------");
|
||||
PrintAndLogEx(INFO, "");
|
||||
vigik_verify(d, 96, foo->rsa_signature, sizeof(foo->rsa_signature));
|
||||
vigik_verify(d);
|
||||
PrintAndLogEx(INFO, "----------------------------------------------------------------");
|
||||
PrintAndLogEx(INFO, "");
|
||||
return PM3_SUCCESS;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "common.h"
|
||||
|
||||
#include "util.h" // FILE_PATH_SIZE
|
||||
#include "protocol_vigik.h"
|
||||
|
||||
#define MIFARE_SECTOR_RETRY 10
|
||||
|
||||
|
@ -113,6 +114,6 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i
|
|||
// remove all sector trailers in a MFC dump
|
||||
int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen);
|
||||
const char *vigik_get_service(uint16_t service_code);
|
||||
int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len);
|
||||
int vigik_annotate(uint8_t *d);
|
||||
int vigik_verify(mfc_vigik_t *d);
|
||||
int vigik_annotate(mfc_vigik_t *d);
|
||||
#endif
|
||||
|
|
|
@ -740,6 +740,7 @@ const static vocabulory_t vocabulory[] = {
|
|||
{ 1, "piv help" },
|
||||
{ 0, "piv select" },
|
||||
{ 0, "piv getdata" },
|
||||
{ 0, "piv authsign" },
|
||||
{ 0, "piv scan" },
|
||||
{ 1, "piv list" },
|
||||
{ 1, "smart help" },
|
||||
|
|
|
@ -62,9 +62,9 @@ pthread_mutex_t g_print_lock = PTHREAD_MUTEX_INITIALIZER;
|
|||
static void fPrintAndLog(FILE *stream, const char *fmt, ...);
|
||||
|
||||
#ifdef _WIN32
|
||||
#define MKDIR_CHK _mkdir(path)
|
||||
#define MKDIR_CHK _mkdir(path)
|
||||
#else
|
||||
#define MKDIR_CHK mkdir(path, 0700)
|
||||
#define MKDIR_CHK mkdir(path, 0700)
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -107,8 +107,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
|
|||
|
||||
if ((result != 0) && create_home) {
|
||||
|
||||
if (MKDIR_CHK)
|
||||
{
|
||||
if (MKDIR_CHK) {
|
||||
fprintf(stderr, "Could not create user directory %s\n", path);
|
||||
free(path);
|
||||
return PM3_EFILE;
|
||||
|
@ -140,8 +139,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
|
|||
|
||||
if ((result != 0) && create_home) {
|
||||
|
||||
if (MKDIR_CHK)
|
||||
{
|
||||
if (MKDIR_CHK) {
|
||||
fprintf(stderr, "Could not create user directory %s\n", path);
|
||||
free(path);
|
||||
return PM3_EFILE;
|
||||
|
@ -155,7 +153,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
|
|||
}
|
||||
|
||||
pathlen += strlen(filename);
|
||||
char *tmp = realloc(path, pathlen *sizeof(char));
|
||||
char *tmp = realloc(path, pathlen * sizeof(char));
|
||||
if (tmp == NULL) {
|
||||
//free(path);
|
||||
return PM3_EMALLOC;
|
||||
|
@ -533,12 +531,11 @@ void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode
|
|||
uint8_t emojified_token_length = 0;
|
||||
char *current_token = NULL;
|
||||
uint8_t current_token_length = 0;
|
||||
char current_char;
|
||||
char *rdest = (char *)dest;
|
||||
char *rsrc = (char *)src;
|
||||
uint16_t si = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
current_char = rsrc[i];
|
||||
char current_char = rsrc[i];
|
||||
|
||||
if (current_token_length == 0) {
|
||||
// starting a new token.
|
||||
|
|
|
@ -1247,7 +1247,7 @@ inline uint64_t leadingzeros64(uint64_t a) {
|
|||
}
|
||||
|
||||
|
||||
int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen) {
|
||||
int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen) {
|
||||
|
||||
size_t max = srclen - plen + 1;
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ uint64_t bitcount64(uint64_t a);
|
|||
uint32_t leadingzeros32(uint32_t a);
|
||||
uint64_t leadingzeros64(uint64_t a);
|
||||
|
||||
int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen);
|
||||
int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen);
|
||||
|
||||
struct smartbuf {
|
||||
char *ptr;
|
||||
|
|
|
@ -280,7 +280,6 @@ void cm_auth(const uint8_t *Gc, const uint8_t *Ci, const uint8_t *Q, uint8_t *Ch
|
|||
|
||||
static void cm_crypt(const CryptoAction ca, const uint8_t offset, const uint8_t len, const uint8_t *in, uint8_t *out, crypto_state s) {
|
||||
size_t pos;
|
||||
uint8_t bt;
|
||||
|
||||
next_n(true, 5, 0, s);
|
||||
next(true, offset, s);
|
||||
|
@ -288,7 +287,7 @@ static void cm_crypt(const CryptoAction ca, const uint8_t offset, const uint8_t
|
|||
next(true, len, s);
|
||||
for (pos = 0; pos < len; pos++) {
|
||||
// Perform the crypto operation
|
||||
bt = in[pos] ^ cm_byte(s);
|
||||
uint8_t bt = in[pos] ^ cm_byte(s);
|
||||
|
||||
// Generate output
|
||||
if (out) out[pos] = bt;
|
||||
|
|
|
@ -2189,7 +2189,9 @@
|
|||
"command": "hf emrtd dump",
|
||||
"description": "Dump all files on an eMRTD",
|
||||
"notes": [
|
||||
"hf emrtd dump"
|
||||
"hf emrtd dump",
|
||||
"hf emrtd dump --dir ../dump",
|
||||
"hf emrtd dump -n 123456789 -d 19890101 -e 20250401"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
|
@ -2198,9 +2200,9 @@
|
|||
"-d, --dateofbirth <YYMMDD> date of birth in YYMMDD format",
|
||||
"-e, --expiry <YYMMDD> expiry in YYMMDD format",
|
||||
"-m, --mrz <[0-9A-Z<]> 2nd line of MRZ, 44 chars",
|
||||
"--path <dirpath> save dump to the given dirpath"
|
||||
"--dir <str> save dump to the given dirpath"
|
||||
],
|
||||
"usage": "hf emrtd dump [-h] [-n <alphanum>] [-d <YYMMDD>] [-e <YYMMDD>] [-m <[0-9A-Z<]>] [--path <dirpath>]"
|
||||
"usage": "hf emrtd dump [-h] [-n <alphanum>] [-d <YYMMDD>] [-e <YYMMDD>] [-m <[0-9A-Z<]>] [--dir <str>]"
|
||||
},
|
||||
"hf emrtd help": {
|
||||
"command": "hf emrtd help",
|
||||
|
@ -2214,7 +2216,10 @@
|
|||
"command": "hf emrtd info",
|
||||
"description": "Display info about an eMRTD",
|
||||
"notes": [
|
||||
"hf emrtd info"
|
||||
"hf emrtd info",
|
||||
"hf emrtd info --dir ../dumps",
|
||||
"hf emrtd info -n 123456789 -d 19890101 -e 20250401",
|
||||
"hf emrtd info -n 123456789 -d 19890101 -e 20250401 -i"
|
||||
],
|
||||
"offline": true,
|
||||
"options": [
|
||||
|
@ -2223,10 +2228,10 @@
|
|||
"-d, --dateofbirth <YYMMDD> date of birth in YYMMDD format",
|
||||
"-e, --expiry <YYMMDD> expiry in YYMMDD format",
|
||||
"-m, --mrz <[0-9A-Z<]> 2nd line of MRZ, 44 chars (passports only)",
|
||||
"--path <dirpath> display info from offline dump stored in dirpath",
|
||||
"--dir <str> display info from offline dump stored in dirpath",
|
||||
"-i, --images show images"
|
||||
],
|
||||
"usage": "hf emrtd info [-hi] [-n <alphanum>] [-d <YYMMDD>] [-e <YYMMDD>] [-m <[0-9A-Z<]>] [--path <dirpath>]"
|
||||
"usage": "hf emrtd info [-hi] [-n <alphanum>] [-d <YYMMDD>] [-e <YYMMDD>] [-m <[0-9A-Z<]>] [--dir <str>]"
|
||||
},
|
||||
"hf emrtd list": {
|
||||
"command": "hf emrtd list",
|
||||
|
@ -4799,7 +4804,7 @@
|
|||
},
|
||||
"hf mf wrbl": {
|
||||
"command": "hf mf wrbl",
|
||||
"description": "Write MIFARE Classic block with 16 hex bytes of data Sector 0 / Block 0 - Manufacturer block When writing to block 0 you must use a VALID block 0 data (UID, BCC, SAK, ATQA) Writing an invalid block 0 means rendering your Magic GEN2 card undetectable. Look in the magic_cards_notes.md file for help to resolve it.",
|
||||
"description": "Write MIFARE Classic block with 16 hex bytes of data Sector 0 / Block 0 - Manufacturer block When writing to block 0 you must use a VALID block 0 data (UID, BCC, SAK, ATQA) Writing an invalid block 0 means rendering your Magic GEN2 card undetectable. Look in the magic_cards_notes.md file for help to resolve it. `--force` param is used to override warnings like bad ACL and BLOCK 0 writes. if not specified, it will exit if detected",
|
||||
"notes": [
|
||||
"hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f"
|
||||
],
|
||||
|
@ -4809,7 +4814,7 @@
|
|||
"--blk <dec> block number",
|
||||
"-a input key type is key A (def)",
|
||||
"-b input key type is key B",
|
||||
"--force enforce block0 writes",
|
||||
"--force override warnings",
|
||||
"-k, --key <hex> key, 6 hex bytes",
|
||||
"-d, --data <hex> bytes to write, 16 hex bytes"
|
||||
],
|
||||
|
@ -9378,6 +9383,7 @@
|
|||
"command": "lf paradox clone",
|
||||
"description": "clone a paradox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
||||
"notes": [
|
||||
"lf paradox clone --fc 96 --cn 40426 -> encode for T55x7 tag with fc and cn",
|
||||
"lf paradox clone --raw 0f55555695596a6a9999a59a -> encode for T55x7 tag",
|
||||
"lf paradox clone --raw 0f55555695596a6a9999a59a --q5 -> encode for Q5/T5555 tag",
|
||||
"lf paradox clone --raw 0f55555695596a6a9999a59a --em -> encode for EM4305/4469"
|
||||
|
@ -9386,10 +9392,12 @@
|
|||
"options": [
|
||||
"-h, --help This help",
|
||||
"-r, --raw <hex> raw hex data. 12 bytes max",
|
||||
"--fc <dec> facility code",
|
||||
"--cn <dec> card number",
|
||||
"--q5 optional - specify writing to Q5/T5555 tag",
|
||||
"--em optional - specify writing to EM4305/4469 tag"
|
||||
],
|
||||
"usage": "lf paradox clone [-h] [-r <hex>] [--q5] [--em]"
|
||||
"usage": "lf paradox clone [-h] [-r <hex>] [--fc <dec>] [--cn <dec>] [--q5] [--em]"
|
||||
},
|
||||
"lf paradox demod": {
|
||||
"command": "lf paradox demod",
|
||||
|
@ -10952,6 +10960,27 @@
|
|||
],
|
||||
"usage": "hf 14b ndefread [-hv] [-f <fn>]"
|
||||
},
|
||||
"piv authsign": {
|
||||
"command": "piv authsign",
|
||||
"description": "Send a nonce and ask the PIV card to sign it",
|
||||
"notes": [
|
||||
"piv sign -sk -> select card, select applet, sign a NULL nonce"
|
||||
],
|
||||
"offline": false,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-s, -S, --select Activate field and select applet",
|
||||
"-k, -K, --keep Keep field for next command",
|
||||
"-a, -A, --apdu Show APDU requests and responses",
|
||||
"-t, -T, --tlv TLV decode results",
|
||||
"-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)",
|
||||
"--aid <hex> Applet ID to select. By default A0000003080000100 will be used",
|
||||
"--nonce <hex> Nonce to sign.",
|
||||
"--slot <dec id> Slot number. Default will be 0x9E (card auth cert).",
|
||||
"--alg <dec> Algorithm to use to sign. Example values: 06=RSA-1024, 07=RSA-2048, 11=ECC-P256 (default), 14=ECC-P384"
|
||||
],
|
||||
"usage": "piv sign [-hskatw] [--aid <hex>] --nonce <hex> [--slot <dec id>] [--alg <dec>]"
|
||||
},
|
||||
"piv getdata": {
|
||||
"command": "piv getdata",
|
||||
"description": "Get a data container of a given tag",
|
||||
|
@ -11731,8 +11760,8 @@
|
|||
}
|
||||
},
|
||||
"metadata": {
|
||||
"commands_extracted": 738,
|
||||
"commands_extracted": 739,
|
||||
"extracted_by": "PM3Help2JSON v1.00",
|
||||
"extracted_on": "2023-01-06T21:37:50"
|
||||
"extracted_on": "2023-01-15T01:24:39"
|
||||
}
|
||||
}
|
|
@ -1343,6 +1343,7 @@ Check column "offline" for their availability.
|
|||
|`piv help `|Y |`This help`
|
||||
|`piv select `|N |`Select the PIV applet`
|
||||
|`piv getdata `|N |`Gets a container on a PIV card`
|
||||
|`piv authsign `|N |`Authenticate with the card`
|
||||
|`piv scan `|N |`Scan PIV card for known containers`
|
||||
|`piv list `|Y |`List ISO7816 history`
|
||||
|
||||
|
|
|
@ -473,7 +473,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
|
||||
// 65 xx
|
||||
#define ISO7816_MEMORY_FULL 0x6501 // Memory failure
|
||||
#define ISO7816_WRITE_MEMORY_ERR 0x6581 // Write problem / Memory failure / Unknown mode
|
||||
#define ISO7816_WRITE_MEMORY_ERR 0x6581 // Write problem / Memory failure / Unknown mode
|
||||
|
||||
// 67 xx
|
||||
#define ISO7816_WRONG_LENGTH 0x6700 // Wrong length
|
||||
|
|
|
@ -34,7 +34,7 @@ STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM410
|
|||
STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI)
|
||||
STANDALONE_MODES_REQ_BT=(HF_REBLAY)
|
||||
STANDALONE_MODES_REQ_SMARTCARD=()
|
||||
STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_14ASNIFF HF_15SNIFF HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM)
|
||||
STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM)
|
||||
|
||||
# PM3GENERIC 256kb, no flash, need to skip some parts to reduce size
|
||||
|
||||
|
|
|
@ -331,11 +331,10 @@ static inline uint8_t next_right_fast(uint8_t in, uint64_t *right) {
|
|||
|
||||
static inline void sm_left_mask(const uint8_t *ks, uint8_t *mask, uint64_t rstate) {
|
||||
size_t pos;
|
||||
uint8_t bt;
|
||||
|
||||
for (pos = 0; pos < 16; pos++) {
|
||||
next_right_fast(0, &rstate);
|
||||
bt = next_right_fast(0, &rstate) << 4;
|
||||
uint8_t bt = next_right_fast(0, &rstate) << 4;
|
||||
next_right_fast(0, &rstate);
|
||||
bt |= next_right_fast(0, &rstate);
|
||||
|
||||
|
@ -349,7 +348,7 @@ static inline void sm_left_mask(const uint8_t *ks, uint8_t *mask, uint64_t rstat
|
|||
|
||||
static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_t> *pcrstates) {
|
||||
uint8_t tmp_mask[16];
|
||||
size_t pos, bits, bit, topbits;
|
||||
size_t pos, bit, topbits;
|
||||
uint64_t rstate, counter;
|
||||
map<uint64_t, uint64_t> bincstates;
|
||||
map<uint64_t, uint64_t>::iterator it;
|
||||
|
@ -358,7 +357,7 @@ static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_
|
|||
topbits = 0;
|
||||
for (counter = 0; counter < 0x2000000; counter++) {
|
||||
// Reset the current bitcount of correct bits
|
||||
bits = 0;
|
||||
size_t bits = 0;
|
||||
|
||||
// Copy the state we are going to test
|
||||
rstate = counter;
|
||||
|
@ -514,7 +513,7 @@ static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, c
|
|||
static inline void sm_left(const uint8_t *ks, const uint8_t *mask, vector<cs_t> *pcstates) {
|
||||
map<uint64_t, cs_t> bincstates;
|
||||
map<uint64_t, cs_t>::iterator it;
|
||||
uint64_t counter, lstate;
|
||||
uint64_t counter;
|
||||
size_t pos, bits, bit;
|
||||
uint8_t correct_bits[16];
|
||||
uint8_t bt;
|
||||
|
@ -526,7 +525,7 @@ static inline void sm_left(const uint8_t *ks, const uint8_t *mask, vector<cs_t>
|
|||
state.invalid = false;
|
||||
|
||||
for (counter = 0; counter < 0x800000000ull; counter++) {
|
||||
lstate = counter;
|
||||
uint64_t lstate = counter;
|
||||
|
||||
for (pos = 0; pos < 16; pos++) {
|
||||
lstate = (((lstate) >> 5) | ((uint64_t)left_addition[((lstate) & 0xf801f)] << 30));
|
||||
|
|
|
@ -165,6 +165,9 @@ void print_cs(const char *text, pcs s) {
|
|||
}
|
||||
|
||||
static inline uint8_t mod(uint8_t a, uint8_t m) {
|
||||
if (m == 0) {
|
||||
return 0; // Actually, divide by zero error
|
||||
}
|
||||
// Just return the input when this is less or equal than the modular value
|
||||
if (a < m) return a;
|
||||
|
||||
|
@ -199,18 +202,15 @@ static lookup_entry lookup_right[0x8000];
|
|||
static uint8_t left_addition[0x100000];
|
||||
|
||||
static inline void init_lookup_left() {
|
||||
uint8_t b3, b6, temp;
|
||||
int i, index;
|
||||
|
||||
for (i = 0; i < 0x400; i++) {
|
||||
b6 = i & 0x1f;
|
||||
b3 = (i >> 5) & 0x1f;
|
||||
index = (b3 << 15) | b6;
|
||||
for (int i = 0; i < 0x400; i++) {
|
||||
uint8_t b6 = i & 0x1f;
|
||||
uint8_t b3 = (i >> 5) & 0x1f;
|
||||
int index = (b3 << 15) | b6;
|
||||
|
||||
// b6 = bit_rotate_l(b6, 5);
|
||||
b6 = BIT_ROL(b6);
|
||||
|
||||
temp = mod(b3 + b6, 0x1f);
|
||||
uint8_t temp = mod(b3 + b6, 0x1f);
|
||||
left_addition[index] = temp;
|
||||
lookup_left[index].addition = temp;
|
||||
lookup_left[index].out = ((temp ^ b3) & 0x0f);
|
||||
|
@ -218,15 +218,12 @@ static inline void init_lookup_left() {
|
|||
}
|
||||
|
||||
static inline void init_lookup_right() {
|
||||
uint8_t b16, b18, temp;
|
||||
int i, index;
|
||||
for (int i = 0; i < 0x400; i++) {
|
||||
uint8_t b18 = i & 0x1f;
|
||||
uint8_t b16 = (i >> 5) & 0x1f;
|
||||
int index = (b16 << 10) | b18;
|
||||
|
||||
for (i = 0; i < 0x400; i++) {
|
||||
b18 = i & 0x1f;
|
||||
b16 = (i >> 5) & 0x1f;
|
||||
index = (b16 << 10) | b18;
|
||||
|
||||
temp = mod(b18 + b16, 0x1f);
|
||||
uint8_t temp = mod(b18 + b16, 0x1f);
|
||||
lookup_right[index].addition = temp;
|
||||
lookup_right[index].out = ((temp ^ b16) & 0x0f);
|
||||
}
|
||||
|
@ -589,23 +586,21 @@ static void ice_sm_left(const uint8_t *ks, uint8_t *mask, vector<cs_t> *pcstates
|
|||
|
||||
static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_t> *pcrstates) {
|
||||
uint8_t tmp_mask[16];
|
||||
size_t pos, bits, bit, topbits;
|
||||
size_t topbits = 0;
|
||||
map<uint64_t, uint64_t> bincstates;
|
||||
map<uint64_t, uint64_t>::iterator it;
|
||||
uint8_t bt;
|
||||
topbits = 0;
|
||||
|
||||
|
||||
for (uint64_t counter = 0; counter < 0x2000000; counter++) {
|
||||
// Reset the current bitcount of correct bits
|
||||
bits = 0;
|
||||
size_t bits = 0;
|
||||
|
||||
// Copy the state we are going to test
|
||||
uint64_t rstate = counter;
|
||||
|
||||
for (pos = 0; pos < 16; pos++) {
|
||||
for (size_t pos = 0; pos < 16; pos++) {
|
||||
next_right_fast(0, &rstate);
|
||||
bt = next_right_fast(0, &rstate) << 4;
|
||||
uint8_t bt = next_right_fast(0, &rstate) << 4;
|
||||
next_right_fast(0, &rstate);
|
||||
bt |= next_right_fast(0, &rstate);
|
||||
|
||||
|
@ -615,7 +610,7 @@ static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_
|
|||
// Save the mask for the left produced bits
|
||||
tmp_mask[pos] = bt;
|
||||
|
||||
for (bit = 0; bit < 8; bit++) {
|
||||
for (size_t bit = 0; bit < 8; bit++) {
|
||||
// When the bit is xored away (=zero), it was the same, so correct ;)
|
||||
if ((bt & 0x01) == 0) bits++;
|
||||
bt >>= 1;
|
||||
|
@ -744,7 +739,7 @@ static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, c
|
|||
static inline void sm_left(const uint8_t *ks, const uint8_t *mask, vector<cs_t> *pcstates) {
|
||||
map<uint64_t, cs_t> bincstates;
|
||||
map<uint64_t, cs_t>::iterator it;
|
||||
uint64_t counter, lstate;
|
||||
uint64_t counter;
|
||||
size_t pos, bits;
|
||||
uint8_t correct_bits[16];
|
||||
uint8_t bt;
|
||||
|
@ -756,7 +751,7 @@ static inline void sm_left(const uint8_t *ks, const uint8_t *mask, vector<cs_t>
|
|||
state.invalid = false;
|
||||
|
||||
for (counter = 0; counter < 0x800000000ull; counter++) {
|
||||
lstate = counter;
|
||||
uint64_t lstate = counter;
|
||||
|
||||
for (pos = 0; pos < 16; pos++) {
|
||||
|
||||
|
|
|
@ -141,6 +141,8 @@ int fnf(uint64_t s) {
|
|||
|
||||
// builds the lfsr for the prng (quick calcs for hitag2_nstep())
|
||||
void buildlfsr(Hitag_State *hstate) {
|
||||
if (hstate == NULL)
|
||||
return;
|
||||
uint64_t state = hstate->shiftreg;
|
||||
uint64_t temp = state ^ (state >> 1);
|
||||
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||
|
|
|
@ -20,11 +20,10 @@ void ComputeCrc14443(int CrcType,
|
|||
const unsigned char *Data, int Length,
|
||||
unsigned char *TransmitFirst,
|
||||
unsigned char *TransmitSecond) {
|
||||
unsigned char chBlock;
|
||||
unsigned short wCrc = CrcType;
|
||||
|
||||
do {
|
||||
chBlock = *Data++;
|
||||
unsigned char chBlock = *Data++;
|
||||
UpdateCrc14443(chBlock, &wCrc);
|
||||
} while (--Length);
|
||||
|
||||
|
|
|
@ -331,6 +331,8 @@ static bool checkValidCmd(uint32_t decrypted) {
|
|||
static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) {
|
||||
|
||||
bool ok = false;
|
||||
if (cmd == NULL)
|
||||
return false;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (cmd[0] == cmds[i][0]) {
|
||||
|
||||
|
|
|
@ -174,6 +174,8 @@ static char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const si
|
|||
static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) {
|
||||
|
||||
bool ok = false;
|
||||
if (cmd == NULL)
|
||||
return false;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (cmd[0] == cmds[i][0]) {
|
||||
|
||||
|
|
|
@ -68,13 +68,12 @@ void make_key_turbopascal_n(uint32_t seed, uint8_t key[], const size_t keylen) {
|
|||
void make_key_posix_rand_r_n(uint32_t seed, uint8_t key[], const size_t keylen) {
|
||||
|
||||
uint32_t lseed = seed;
|
||||
int result;
|
||||
|
||||
for (int i = 0; i < keylen; i++) {
|
||||
|
||||
lseed *= 1103515245;
|
||||
lseed += 12345;
|
||||
result = (uint16_t)(lseed / 0x10000) % 2048;
|
||||
int result = (uint16_t)(lseed / 0x10000) % 2048;
|
||||
|
||||
lseed *= 1103515245;
|
||||
lseed += 12345;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue