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)),)
|
||||
|
|
|
@ -46,13 +46,11 @@ 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)
|
||||
{
|
||||
void RunMod(void) {
|
||||
int n;
|
||||
|
||||
StandAloneMode();
|
||||
|
@ -62,8 +60,7 @@ void RunMod(void)
|
|||
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
|
||||
{
|
||||
do {
|
||||
WDT_HIT();
|
||||
|
||||
if (data_available())
|
||||
|
@ -78,8 +75,7 @@ void RunMod(void)
|
|||
LEDsoff();
|
||||
}
|
||||
|
||||
static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag)
|
||||
{
|
||||
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);
|
||||
|
@ -88,14 +84,11 @@ static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag)
|
|||
bytes_to_bytebits(data, size, bitStream);
|
||||
size <<= 3;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
if (phase == 1) { //run a second set inverted to keep phase in check
|
||||
for (i = 0; i < size; i++) {
|
||||
biphaseSimBitInverted(!bitStream[i], &ret, &phase);
|
||||
}
|
||||
}
|
||||
|
@ -103,17 +96,13 @@ static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase)
|
||||
{
|
||||
static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase) {
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
if (c)
|
||||
{
|
||||
if (c) {
|
||||
memset(dest + (*n), c ^ 1 ^ *phase, 32);
|
||||
memset(dest + (*n) + 32, c ^ *phase, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
memset(dest + (*n), c ^ *phase, 64);
|
||||
*phase ^= 1;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
@ -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`
|
||||
|
||||
|
|
|
@ -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