Merge pull request #1869 from RfidResearchGroup/nitride

Nitride release preparation in progress
This commit is contained in:
Iceman 2023-01-15 06:02:20 +01:00 committed by GitHub
commit 2d1c856437
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 703 additions and 692 deletions

View file

@ -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) - [ ] `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_lib` compilation & tests
- [ ] `experimental_client_with_swig` 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) - [ ] GitHub Actions - green across the board ( MacOS, Ubuntu, Windows)
# OS compilation and tests # OS compilation and tests

View file

@ -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 += 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_BT := HF_REBLAY
STANDALONE_MODES_REQ_SMARTCARD := 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)),) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)

View file

@ -11,7 +11,7 @@
// then from shell: // then from shell:
// hexdump lf.bin -e '5/1 "%02X" /0 "\n"' // 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: // Modes of operation:

View file

@ -27,14 +27,14 @@
#include "BigBuf.h" #include "BigBuf.h"
#include "crc16.h" #include "crc16.h"
#define MODULE_LONG_NAME "LF Nedap simple simulator" #define MODULE_LONG_NAME "LF Nedap simple simulator"
typedef struct _NEDAP_TAG { typedef struct _NEDAP_TAG {
uint8_t subType; uint8_t subType;
uint16_t customerCode; uint16_t customerCode;
uint32_t id; uint32_t id;
uint8_t bIsLong; uint8_t bIsLong;
} NEDAP_TAG, *PNEDAP_TAG; } NEDAP_TAG, *PNEDAP_TAG;
const NEDAP_TAG Tag = {.subType = 0x5, .customerCode = 0x123, .id = 42424, .bIsLong = 1}; const NEDAP_TAG Tag = {.subType = 0x5, .customerCode = 0x123, .id = 42424, .bIsLong = 1};
@ -46,78 +46,67 @@ static uint8_t isEven_64_63(const uint8_t *data);
static inline uint32_t bitcount32(uint32_t a); static inline uint32_t bitcount32(uint32_t a);
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);
void ModInfo(void) void ModInfo(void) {
{
DbpString(" " MODULE_LONG_NAME); DbpString(" " MODULE_LONG_NAME);
} }
void RunMod(void) void RunMod(void) {
{ int n;
int n;
StandAloneMode(); StandAloneMode();
Dbprintf("[=] " MODULE_LONG_NAME " -- started"); Dbprintf("[=] " MODULE_LONG_NAME " -- started");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); 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); 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); n = NedapPrepareBigBuffer(&Tag);
do do {
{
WDT_HIT(); WDT_HIT();
if (data_available()) if (data_available())
break; break;
SimulateTagLowFrequency(n, 0, true);
SimulateTagLowFrequency(n, 0, true);
} while (BUTTON_HELD(1000) == BUTTON_NO_CLICK); } while (BUTTON_HELD(1000) == BUTTON_NO_CLICK);
Dbprintf("[=] " MODULE_LONG_NAME " -- exiting"); Dbprintf("[=] " MODULE_LONG_NAME " -- exiting");
LEDsoff(); LEDsoff();
} }
static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag) static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag) {
{ int ret = 0;
int ret = 0; uint8_t data[16], bitStream[sizeof(data) * 8], phase = 0;
uint8_t data[16], bitStream[sizeof(data) * 8], phase = 0; uint16_t i, size = pTag->bIsLong ? sizeof(data) : (sizeof(data) / 2);
uint16_t i, size = pTag->bIsLong ? sizeof(data) : (sizeof(data) / 2);
NedapGen(pTag->subType, pTag->customerCode, pTag->id, pTag->bIsLong, data);
NedapGen(pTag->subType, pTag->customerCode, pTag->id, pTag->bIsLong, data); bytes_to_bytebits(data, size, bitStream);
bytes_to_bytebits(data, size, bitStream); size <<= 3;
size <<= 3;
for (i = 0; i < size; i++) {
for (i = 0; i < size; i++) biphaseSimBitInverted(!bitStream[i], &ret, &phase);
{ }
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 biphaseSimBitInverted(!bitStream[i], &ret, &phase);
{ }
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) static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase) {
{ uint8_t *dest = BigBuf_get_addr();
uint8_t *dest = BigBuf_get_addr();
if (c) if (c) {
{ memset(dest + (*n), c ^ 1 ^ *phase, 32);
memset(dest + (*n), c ^ 1 ^ *phase, 32); memset(dest + (*n) + 32, c ^ *phase, 32);
memset(dest + (*n) + 32, c ^ *phase, 32); } else {
} memset(dest + (*n), c ^ *phase, 64);
else *phase ^= 1;
{ }
memset(dest + (*n), c ^ *phase, 64); *n += 64;
*phase ^= 1;
}
*n += 64;
} }
#define FIXED_71 0x71 #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; 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; uint8_t *s = (uint8_t *)src, *d = (uint8_t *)dest;
size_t i = srclen * 8, j = srclen; size_t i = srclen * 8, j = srclen;
while (j--) while (j--) {
{
uint8_t b = s[j]; uint8_t b = s[j];
d[--i] = (b >> 0) & 1; d[--i] = (b >> 0) & 1;
d[--i] = (b >> 1) & 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__ #if defined __GNUC__
return __builtin_popcountl(a); return __builtin_popcountl(a);
#else #else

View file

@ -298,7 +298,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
// 8-byte IDm, number of blocks, blocks numbers // 8-byte IDm, number of blocks, blocks numbers
// number of blocks limited to 4 for FelicaLite(S) // number of blocks limited to 4 for FelicaLite(S)
static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t *blocks) { 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); Dbprintf("Invalid number of blocks, %d != 4", blocknum);
uint8_t c = 0, i = 0; uint8_t c = 0, i = 0;

View file

@ -235,9 +235,10 @@ static int json_get_utf8_char_len(unsigned char ch) {
/* string = '"' { quoted_printable_chars } '"' */ /* string = '"' { quoted_printable_chars } '"' */
static int json_parse_string(struct frozen *f) { static int json_parse_string(struct frozen *f) {
int n, ch = 0, len = 0; int ch = 0;
TRY(json_test_and_skip(f, '"')); TRY(json_test_and_skip(f, '"'));
{ {
int len = 0;
SET_STATE(f, f->cur, "", 0); SET_STATE(f, f->cur, "", 0);
for (; f->cur < f->end; f->cur += len) { for (; f->cur < f->end; f->cur += len) {
ch = *(unsigned char *) f->cur; 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(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */
EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE); EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE);
if (ch == '\\') { if (ch == '\\') {
int n;
EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n); EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n);
len += n; len += n;
} else if (ch == '"') { } else if (ch == '"') {
@ -295,17 +297,17 @@ static int json_parse_number(struct frozen *f) {
#if JSON_ENABLE_ARRAY #if JSON_ENABLE_ARRAY
/* array = '[' [ value { ',' value } ] ']' */ /* array = '[' [ value { ',' value } ] ']' */
static int json_parse_array(struct frozen *f) { 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); CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0);
TRY(json_test_and_skip(f, '[')); TRY(json_test_and_skip(f, '['));
{ {
{ {
int i = 0;
SET_STATE(f, f->cur - 1, "", 0); SET_STATE(f, f->cur - 1, "", 0);
while (json_cur(f) != ']') { while (json_cur(f) != ']') {
char buf[20];
snprintf(buf, sizeof(buf), "[%d]", i); snprintf(buf, sizeof(buf), "[%d]", i);
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->cur_name =
f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/;
f->cur_name_len = strlen(buf) - 2 /*braces*/; 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, 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 *key, struct json_token *val, int *i) {
struct json_token tmpval, *v = val == NULL ? &tmpval : val; struct json_token tmpval;
struct json_token tmpkey, *k = key == NULL ? &tmpkey : key; struct json_token *v = val == NULL ? &tmpval : val;
int tmpidx, *pidx = i == NULL ? &tmpidx : i; 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}; struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx};
json_walk(s, len, json_next_cb, &data); json_walk(s, len, json_next_cb, &data);
return data.found ? data.handle : NULL; return data.found ? data.handle : NULL;

View file

@ -1268,7 +1268,6 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) {
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN];
size_t rxlen = 0; size_t rxlen = 0;
uint8_t tx[HITAG_FRAME_LEN]; uint8_t tx[HITAG_FRAME_LEN];
size_t txlen;
int t_wait = HITAG_T_WAIT_MAX; int t_wait = HITAG_T_WAIT_MAX;
@ -1284,7 +1283,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) {
WDT_HIT(); WDT_HIT();
//send read request //send read request
txlen = 0; size_t txlen = 0;
uint8_t cmd = 0x0c; uint8_t cmd = 0x0c;
txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4); txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4);
uint8_t addr = pageNum; uint8_t addr = pageNum;

View file

@ -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 timeout, uint32_t *eof_time, bool shallow_mod) {
uint16_t resp_len = 0; uint16_t resp_len = 0;
int res;
while (tries-- > 0) { while (tries-- > 0) {
iclass_send_as_reader(cmd, cmdsize, start_time, eof_time, shallow_mod); 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; 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) { if (res == PM3_SUCCESS && expected_size == resp_len) {
return true; return true;
} }

View file

@ -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 }; static const uint8_t x_wup2[] = { 0x5D, 0x37, 0x21, 0x71, 0x71 };
uint8_t slot_mark[1]; 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 start_time = 0;
uint32_t eof_time = 0; uint32_t eof_time = 0;
iso14b_set_timeout(24); // wait for carrier iso14b_set_timeout(24); // wait for carrier
// wup1 // wup1
CodeAndTransmit14443bAsReader(x_wup1, sizeof(x_wup1), &start_time, &eof_time, true); 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 // wup2
CodeAndTransmit14443bAsReader(x_wup2, sizeof(x_wup2), &start_time, &eof_time, true); 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; int slot;
for (slot = 0; slot < 4; 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); 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 // 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; 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); CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false);
break; break;
} else { // no subcarrier burst } else { // no subcarrier burst
slot_mark[0] = 0xA1 + (slot << 1); // nak slot slot_mark[0] = 0xA1 + (slot << 1); // nak slot
CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false); 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 // 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; return 3;
} }

View file

@ -461,7 +461,6 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo
uint16_t len = 0; uint16_t len = 0;
uint32_t pos = 0; uint32_t pos = 0;
uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send 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 d_block[18], d_block_enc[18];
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; 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); len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if (len != 0) { // Something not right, len == 0 (no response is ok as its waiting for transfer 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], 0)) << 0;
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1;
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2;

View file

@ -293,9 +293,9 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/cmdhfseos.c ${PM3_ROOT}/client/src/cmdhfseos.c
${PM3_ROOT}/client/src/cmdhfst.c ${PM3_ROOT}/client/src/cmdhfst.c
${PM3_ROOT}/client/src/cmdhfst25ta.c ${PM3_ROOT}/client/src/cmdhfst25ta.c
${PM3_ROOT}/client/src/cmdhftexkom.c
${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c
${PM3_ROOT}/client/src/cmdhftopaz.c ${PM3_ROOT}/client/src/cmdhftopaz.c
${PM3_ROOT}/client/src/cmdhftexkom.c
${PM3_ROOT}/client/src/cmdhfwaveshare.c ${PM3_ROOT}/client/src/cmdhfwaveshare.c
${PM3_ROOT}/client/src/cmdhfxerox.c ${PM3_ROOT}/client/src/cmdhfxerox.c
${PM3_ROOT}/client/src/cmdhw.c ${PM3_ROOT}/client/src/cmdhw.c

View file

@ -530,7 +530,6 @@ stop_tests:
bucket_states_tested += bucket_size[block_idx]; bucket_states_tested += bucket_size[block_idx];
// prepare to set new states // prepare to set new states
state_p = &states[KEYSTREAM_SIZE]; state_p = &states[KEYSTREAM_SIZE];
continue;
} }
} }
out: out:

View file

@ -276,6 +276,7 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/cmdhfepa.c ${PM3_ROOT}/client/src/cmdhfepa.c
${PM3_ROOT}/client/src/cmdhffelica.c ${PM3_ROOT}/client/src/cmdhffelica.c
${PM3_ROOT}/client/src/cmdhffido.c ${PM3_ROOT}/client/src/cmdhffido.c
${PM3_ROOT}/client/src/cmdhffudan.c
${PM3_ROOT}/client/src/cmdhfgallagher.c ${PM3_ROOT}/client/src/cmdhfgallagher.c
${PM3_ROOT}/client/src/cmdhfcipurse.c ${PM3_ROOT}/client/src/cmdhfcipurse.c
${PM3_ROOT}/client/src/cmdhficlass.c ${PM3_ROOT}/client/src/cmdhficlass.c
@ -293,9 +294,11 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/cmdhfseos.c ${PM3_ROOT}/client/src/cmdhfseos.c
${PM3_ROOT}/client/src/cmdhfst.c ${PM3_ROOT}/client/src/cmdhfst.c
${PM3_ROOT}/client/src/cmdhfst25ta.c ${PM3_ROOT}/client/src/cmdhfst25ta.c
${PM3_ROOT}/client/src/cmdhftexkom.c
${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c
${PM3_ROOT}/client/src/cmdhftopaz.c ${PM3_ROOT}/client/src/cmdhftopaz.c
${PM3_ROOT}/client/src/cmdhfwaveshare.c ${PM3_ROOT}/client/src/cmdhfwaveshare.c
${PM3_ROOT}/client/src/cmdhfxerox.c
${PM3_ROOT}/client/src/cmdhw.c ${PM3_ROOT}/client/src/cmdhw.c
${PM3_ROOT}/client/src/cmdlf.c ${PM3_ROOT}/client/src/cmdlf.c
${PM3_ROOT}/client/src/cmdlfawid.c ${PM3_ROOT}/client/src/cmdlfawid.c
@ -334,6 +337,7 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/cmdmain.c ${PM3_ROOT}/client/src/cmdmain.c
${PM3_ROOT}/client/src/cmdnfc.c ${PM3_ROOT}/client/src/cmdnfc.c
${PM3_ROOT}/client/src/cmdparser.c ${PM3_ROOT}/client/src/cmdparser.c
${PM3_ROOT}/client/src/cmdpiv.c
${PM3_ROOT}/client/src/cmdscript.c ${PM3_ROOT}/client/src/cmdscript.c
${PM3_ROOT}/client/src/cmdsmartcard.c ${PM3_ROOT}/client/src/cmdsmartcard.c
${PM3_ROOT}/client/src/cmdtrace.c ${PM3_ROOT}/client/src/cmdtrace.c

View file

@ -62,7 +62,7 @@ function main(args)
local i local i
local cmds = {} local cmds = {}
--check for params --check for params
for o, a in getopt.getopt(args, 'h') do for o, a in getopt.getopt(args, 'h') do
if o == 'h' then return help() end if o == 'h' then return help() end
end end

View file

@ -63,8 +63,8 @@ local function card_format(key_a,key_b,ab,user,s70)
core.console(cmd) core.console(cmd)
print(cmd) print(cmd)
core.clearCommandBuffer() core.clearCommandBuffer()
if s70 == false and k > 15 then if s70 == false and k > 15 then
return return
end end
end end
end end

View file

@ -109,8 +109,8 @@ local function main(args)
command = 'hf 14a sim -t 1 -u ' .. uid_format command = 'hf 14a sim -t 1 -u ' .. uid_format
msg('Bruteforcing Mifare Classic card numbers') msg('Bruteforcing Mifare Classic card numbers')
elseif mftype == 'mfc4' then elseif mftype == 'mfc4' then
command = 'hf 14a sim -t 8 -u ' .. uid_format command = 'hf 14a sim -t 8 -u ' .. uid_format
msg('Bruteforcing Mifare Classic 4K card numbers') msg('Bruteforcing Mifare Classic 4K card numbers')
elseif mftype == 'mfu' then elseif mftype == 'mfu' then
command = 'hf 14a sim -t 2 -u ' .. uid_format command = 'hf 14a sim -t 2 -u ' .. uid_format
msg('Bruteforcing Mifare Ultralight card numbers') msg('Bruteforcing Mifare Ultralight card numbers')

View file

@ -50,17 +50,17 @@ arguments = [[
-c read magic configuration -c read magic configuration
-u UID (8-14 hexsymbols), set UID on tag -u UID (8-14 hexsymbols), set UID on tag
-t tag type to impersonate -t tag type to impersonate
1 = Mifare Mini S20 4-byte 12 = NTAG 210 1 = Mifare Mini S20 4-byte 12 = NTAG 210
2 = Mifare Mini S20 7-byte 13 = NTAG 212 2 = Mifare Mini S20 7-byte 13 = NTAG 212
3 = Mifare 1k S50 4-byte 14 = NTAG 213 3 = Mifare 1k S50 4-byte 14 = NTAG 213
4 = Mifare 1k S50 7-byte 15 = NTAG 215 4 = Mifare 1k S50 7-byte 15 = NTAG 215
5 = Mifare 4k S70 4-byte 16 = NTAG 216 5 = Mifare 4k S70 4-byte 16 = NTAG 216
6 = Mifare 4k S70 7-byte 17 = NTAG I2C 1K 6 = Mifare 4k S70 7-byte 17 = NTAG I2C 1K
*** 7 = UL - NOT WORKING FULLY 18 = NTAG I2C 2K *** 7 = UL - NOT WORKING FULLY 18 = NTAG I2C 2K
*** 8 = UL-C - NOT WORKING FULLY 19 = NTAG I2C 1K PLUS *** 8 = UL-C - NOT WORKING FULLY 19 = NTAG I2C 1K PLUS
9 = UL EV1 48b 20 = NTAG I2C 2K PLUS 9 = UL EV1 48b 20 = NTAG I2C 2K PLUS
10 = UL EV1 128b 21 = NTAG 213F 10 = UL EV1 128b 21 = NTAG 213F
*** 11 = UL Plus - NOT WORKING YET 22 = NTAG 216F *** 11 = UL Plus - NOT WORKING YET 22 = NTAG 216F
-p NTAG password (8 hexsymbols), set NTAG password on tag. -p NTAG password (8 hexsymbols), set NTAG password on tag.
-a NTAG pack ( 4 hexsymbols), set NTAG pack 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 if not info then return false, "Can't select card" end
-- read Ultimate Magic Card CONFIG -- read Ultimate Magic Card CONFIG
if magicconfig == nil then if magicconfig == nil then
magicconfig = send("CF".._key.."C6") magicconfig = send("CF".._key.."C6")
else print('No Config') else print('No Config')
end end
-- extract data from CONFIG - based on CONFIG in https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md#gen-4-gtu -- 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)) else atsstr = (string.sub(ats, 3))
end end
if ulprotocol == '00' then if ulprotocol == '00' then
cardprotocol = 'MIFARE Classic Protocol' cardprotocol = 'MIFARE Classic Protocol'
ultype = 'Disabled' ultype = 'Disabled'
if uidlength == '00' then if uidlength == '00' then
uid = send("CF".._key.."CE00"):sub(1,8) uid = send("CF".._key.."CE00"):sub(1,8)
if atqaf == '00 04' and sak == '09' then cardtype = 'MIFARE Mini S20 4-byte UID' 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 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' elseif atqaf == '00 02' and sak == '18' then cardtype = 'MIFARE 4k S70 4-byte UID'
end end
elseif uidlength == '01' then elseif uidlength == '01' then
uid = send("CF".._key.."CE00"):sub(1,14) uid = send("CF".._key.."CE00"):sub(1,14)
if atqaf == '00 44' and sak == '09' then cardtype = 'MIFARE Mini S20 7-byte UID' 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 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' elseif atqaf == '00 42' and sak == '18' then cardtype = 'MIFARE 4k S70 7-byte UID'
end end
end end
elseif ulprotocol == '01' then elseif ulprotocol == '01' then
-- Read Ultralight config only if UL protocol is enabled -- Read Ultralight config only if UL protocol is enabled
cardprotocol = 'MIFARE Ultralight/NTAG' cardprotocol = 'MIFARE Ultralight/NTAG'
block0 = send("3000") block0 = send("3000")
uid0 = block0:sub(1,6) uid0 = block0:sub(1,6)
uid = uid0..block0:sub(9,16) uid = uid0..block0:sub(9,16)
if ulmode == '00' then ultype = 'Ultralight EV1' if ulmode == '00' then ultype = 'Ultralight EV1'
elseif ulmode == '01' then ultype = 'NTAG21x' elseif ulmode == '01' then ultype = 'NTAG21x'
elseif ulmode == '02' then ultype = 'Ultralight-C' elseif ulmode == '02' then ultype = 'Ultralight-C'
elseif ulmode == '03' then ultype = 'Ultralight' elseif ulmode == '03' then ultype = 'Ultralight'
end end
-- read VERSION -- read VERSION
cversion = send('30FA'):sub(1,16) 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 -- 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' if ulmode == '03' then versionstr = 'Ultralight'
elseif ulmode == '02' then versionstr = 'Ultralight-C' elseif ulmode == '02' then versionstr = 'Ultralight-C'
elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b' elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b'
elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b' elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b'
elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210' elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210'
elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212' elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212'
elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213' elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213'
elseif cversion == '0004040201001103' then versionstr = 'NTAG 215' elseif cversion == '0004040201001103' then versionstr = 'NTAG 215'
elseif cversion == '0004040201001303' then versionstr = 'NTAG 216' elseif cversion == '0004040201001303' then versionstr = 'NTAG 216'
elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K' elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K'
elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K' elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K'
elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS' elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS'
elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS' elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS'
elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F' elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F'
elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F' elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F'
end end
-- read PWD -- read PWD
cpwd = send("30F0"):sub(1,8) cpwd = send("30F0"):sub(1,8)
pwd = send("30E5"):sub(1,8) pwd = send("30E5"):sub(1,8)
-- 04 response indicates that blocks has been locked down. -- 04 response indicates that blocks has been locked down.
if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end
-- read PACK -- read PACK
cpack = send("30F1"):sub(1,4) cpack = send("30F1"):sub(1,4)
pack = send("30E6"):sub(1,4) pack = send("30E6"):sub(1,4)
-- read SIGNATURE -- read SIGNATURE
signature1 = send('30F2'):sub(1,32) signature1 = send('30F2'):sub(1,32)
signature2 = send('30F6'):sub(1,32) signature2 = send('30F6'):sub(1,32)
lib14a.disconnect() lib14a.disconnect()
end end
if _print < 1 then if _print < 1 then
print(string.rep('=', 88)) print(string.rep('=', 88))
print('\t\t\tUltimate Magic Card Configuration') print('\t\t\tUltimate Magic Card Configuration')
print(string.rep('=', 88)) print(string.rep('=', 88))
print(' - Raw Config ', string.sub(magicconfig, 1, -9)) print(' - Raw Config ', string.sub(magicconfig, 1, -9))
print(' - Card Protocol ', cardprotocol) print(' - Card Protocol ', cardprotocol)
print(' - Ultralight Mode ', ultype) print(' - Ultralight Mode ', ultype)
print(' - ULM Backdoor Key ', readpass) print(' - ULM Backdoor Key ', readpass)
print(' - GTU Mode ', gtustr) print(' - GTU Mode ', gtustr)
if ulprotocol == '01' then if ulprotocol == '01' then
print(' - Card Type ', versionstr) print(' - Card Type ', versionstr)
else else
print(' - Card Type ', cardtype) print(' - Card Type ', cardtype)
end end
print(' - UID ', uid) print(' - UID ', uid)
print(' - ATQA ', atqaf) print(' - ATQA ', atqaf)
print(' - SAK ', sak) print(' - SAK ', sak)
if ulprotocol == '01' then if ulprotocol == '01' then
print('') print('')
print(string.rep('=', 88)) print(string.rep('=', 88))
print('\t\t\tMagic UL/NTAG 21* Configuration') print('\t\t\tMagic UL/NTAG 21* Configuration')
print(string.rep('=', 88)) print(string.rep('=', 88))
print(' - ATS ', atsstr) print(' - ATS ', atsstr)
print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd) print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd)
print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack) print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack)
print(' - Version ', cversion) print(' - Version ', cversion)
print(' - Signature ', signature1..signature2) print(' - Signature ', signature1..signature2)
end end
end end
lib14a.disconnect() lib14a.disconnect()
return true, 'Ok' return true, 'Ok'
@ -291,41 +291,41 @@ end
local function write_uid(useruid) local function write_uid(useruid)
-- read CONFIG -- read CONFIG
if not magicconfig then if not magicconfig then
_print = 1 _print = 1
read_config() read_config()
end end
local info = connect() local info = connect()
if not info then return false, "Can't select card" end if not info then return false, "Can't select card" end
-- Writes a MFC UID with GEN4 magic commands. -- Writes a MFC UID with GEN4 magic commands.
if ulprotocol == '00' then if ulprotocol == '00' then
-- uid string checks -- uid string checks
if useruid == nil then return nil, 'empty uid string' end if useruid == nil then return nil, 'empty uid string' end
if #useruid == 0 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 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) print('Writing new UID ', useruid)
local uidbytes = utils.ConvertHexToBytes(useruid) local uidbytes = utils.ConvertHexToBytes(useruid)
local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), uidbytes[4]) 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 block0 = string.format('%02X%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], uidbytes[4], bcc1)
local resp = send('CF'.._key..'CD00'..block0) local resp = send('CF'.._key..'CD00'..block0)
-- Writes a MFUL UID with bcc1, bcc2 using NTAG21xx commands. -- Writes a MFUL UID with bcc1, bcc2 using NTAG21xx commands.
elseif ulprotocol == '01' then elseif ulprotocol == '01' then
-- uid string checks -- uid string checks
if useruid == nil then return nil, 'empty uid string' end if useruid == nil then return nil, 'empty uid string' end
if #useruid == 0 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 if #useruid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end
print('Writing new UID ', useruid) print('Writing new UID ', useruid)
local uidbytes = utils.ConvertHexToBytes(useruid) local uidbytes = utils.ConvertHexToBytes(useruid)
local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88) 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 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 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 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 block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00)
local resp local resp
resp = send('A200'..block0) resp = send('A200'..block0)
resp = send('A201'..block1) resp = send('A201'..block1)
resp = send('A202'..block2) resp = send('A202'..block2)
else else
print('Incorrect ul') print('Incorrect ul')
end end
lib14a.disconnect() lib14a.disconnect()
if resp ~= nil then if resp ~= nil then
@ -339,8 +339,8 @@ end
local function write_atqasak(atqasak) local function write_atqasak(atqasak)
-- read CONFIG -- read CONFIG
if not magicconfig then if not magicconfig then
_print = 1 _print = 1
read_config() read_config()
end end
if atqasak == nil then return nil, 'Empty ATQA/SAK string' end if atqasak == nil then return nil, 'Empty ATQA/SAK string' end
if #atqasak == 0 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 atqauserf = atqauser2..atqauser1
local sakuser = atqasak:sub(5,6) local sakuser = atqasak:sub(5,6)
if sakuser == '04' then if sakuser == '04' then
print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required') print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required')
return nil return nil
elseif (sakuser == '20' or sakuser == '28') and atslen == '00' then elseif (sakuser == '20' or sakuser == '28') and atslen == '00' then
print('When SAK equals 20 or 28, ATS must be turned on') print('When SAK equals 20 or 28, ATS must be turned on')
return nil return nil
elseif atqauser2 == '40' then elseif atqauser2 == '40' then
print('ATQA of [00 40] will cause the card to not answer.') print('ATQA of [00 40] will cause the card to not answer.')
return nil return nil
else else
local info = connect() local info = connect()
if not info then return false, "Can't select card" end if not info then return false, "Can't select card" end
print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser) print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser)
local resp = send("CF".._key.."35"..atqauserf..sakuser) local resp = send("CF".._key.."35"..atqauserf..sakuser)
lib14a.disconnect() lib14a.disconnect()
if resp == nil then if resp == nil then
return nil, oops('Failed to write ATQA/SAK') return nil, oops('Failed to write ATQA/SAK')
else else
return true, 'Ok' return true, 'Ok'
end end
end end
end end
--- ---
@ -376,8 +376,8 @@ end
local function write_ntagpwd(ntagpwd) local function write_ntagpwd(ntagpwd)
-- read CONFIG -- read CONFIG
if not magicconfig then if not magicconfig then
_print = 1 _print = 1
read_config() read_config()
end end
if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
-- PWD string checks -- PWD string checks
@ -401,8 +401,8 @@ end
local function write_pack(userpack) local function write_pack(userpack)
-- read CONFIG -- read CONFIG
if not magicconfig then if not magicconfig then
_print = 1 _print = 1
read_config() read_config()
end end
if ulprotocol == 0 then return nil, 'Magic Card is not using the Ultralight Protocol' end if ulprotocol == 0 then return nil, 'Magic Card is not using the Ultralight Protocol' end
-- PACK string checks -- 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 if #block3 ~= 8 then return nil, 'OTP wrong length. Should be 4 hex bytes' end
-- read CONFIG -- read CONFIG
if not magicconfig then if not magicconfig then
_print = 1 _print = 1
read_config() read_config()
end end
if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
local info = connect() 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 if #data ~= 16 then return nil, 'version wrong length. Should be 8 hex bytes' end
-- read CONFIG -- read CONFIG
if not magicconfig then if not magicconfig then
_print = 1 _print = 1
read_config() read_config()
end end
if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
print('Writing new version', data) 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 if #data ~= 64 then return nil, 'data wrong length. Should be 32 hex bytes' end
-- read CONFIG -- read CONFIG
if not magicconfig then if not magicconfig then
_print = 1 _print = 1
read_config() read_config()
end end
local info = connect() local info = connect()
if not info then return false, "Can't select card" end if not info then return false, "Can't select card" end
@ -508,19 +508,19 @@ local function write_gtu(gtu)
local info = connect() local info = connect()
if not info then return false, "Can't select card" end if not info then return false, "Can't select card" end
if gtu == '00' then if gtu == '00' then
print('Enabling GTU Pre-Write') print('Enabling GTU Pre-Write')
send('CF'.._key..'32'..gtu) send('CF'.._key..'32'..gtu)
elseif gtu == '01' then elseif gtu == '01' then
print('Enabling GTU Restore Mode') print('Enabling GTU Restore Mode')
send('CF'.._key..'32'..gtu) send('CF'.._key..'32'..gtu)
elseif gtu == '02' then elseif gtu == '02' then
print('Disabled GTU') print('Disabled GTU')
send('CF'.._key..'32'..gtu) send('CF'.._key..'32'..gtu)
elseif gtu == '03' then elseif gtu == '03' then
print('Disabled GTU, high speed R/W mode for Ultralight') print('Disabled GTU, high speed R/W mode for Ultralight')
send('CF'.._key..'32'..gtu) send('CF'.._key..'32'..gtu)
else else
print('Failed to set GTU mode') print('Failed to set GTU mode')
end end
lib14a.disconnect() lib14a.disconnect()
return true, 'Ok' return true, 'Ok'
@ -536,13 +536,13 @@ local function write_ats(atsuser)
local atscardlendecimal = tonumber(atscardlen, 16) local atscardlendecimal = tonumber(atscardlen, 16)
local atsf = string.sub(atsuser, 3) local atsf = string.sub(atsuser, 3)
if (#atsf / 2) ~= atscardlendecimal then if (#atsf / 2) ~= atscardlendecimal then
oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')') oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')')
return true, 'Ok' return true, 'Ok'
else else
local info = connect() local info = connect()
if not info then return false, "Can't select card" end if not info then return false, "Can't select card" end
print('Writing '..atscardlendecimal..' ATS bytes of '..atsf) print('Writing '..atscardlendecimal..' ATS bytes of '..atsf)
send("CF".._key.."34"..atsuser) send("CF".._key.."34"..atsuser)
end end
lib14a.disconnect() lib14a.disconnect()
return true, 'Ok' return true, 'Ok'
@ -556,11 +556,11 @@ local function write_ulp(ulp)
local info = connect() local info = connect()
if not info then return false, "Can't select card" end if not info then return false, "Can't select card" end
if ulp == '00' then if ulp == '00' then
print('Changing card to Mifare Classic Protocol') print('Changing card to Mifare Classic Protocol')
send("CF".._key.."69"..ulp) send("CF".._key.."69"..ulp)
elseif ulp == '01' then elseif ulp == '01' then
print('Changing card to Ultralight Protocol') print('Changing card to Ultralight Protocol')
send("CF".._key.."69"..ulp) send("CF".._key.."69"..ulp)
else else
oops('Protocol needs to be either 00 or 01') oops('Protocol needs to be either 00 or 01')
end end
@ -576,17 +576,17 @@ local function write_ulm(ulm)
local info = connect() local info = connect()
if not info then return false, "Can't select card" end if not info then return false, "Can't select card" end
if ulm == '00' then if ulm == '00' then
print('Changing card UL mode to Ultralight EV1') print('Changing card UL mode to Ultralight EV1')
send("CF".._key.."6A"..ulm) send("CF".._key.."6A"..ulm)
elseif ulm == '01' then elseif ulm == '01' then
print('Changing card UL mode to NTAG') print('Changing card UL mode to NTAG')
send("CF".._key.."6A"..ulm) send("CF".._key.."6A"..ulm)
elseif ulm == '02' then elseif ulm == '02' then
print('Changing card UL mode to Ultralight-C') print('Changing card UL mode to Ultralight-C')
send("CF".._key.."6A"..ulm) send("CF".._key.."6A"..ulm)
elseif ulm == '03' then elseif ulm == '03' then
print('Changing card UL mode to Ultralight') print('Changing card UL mode to Ultralight')
send("CF".._key.."6A"..ulm) send("CF".._key.."6A"..ulm)
else else
oops('UL mode needs to be either 00, 01, 02, 03') oops('UL mode needs to be either 00, 01, 02, 03')
end end
@ -603,50 +603,50 @@ local function set_type(tagtype)
if tagtype == 1 then if tagtype == 1 then
print('Setting: Ultimate Magic card to Mifare mini S20 4-byte') print('Setting: Ultimate Magic card to Mifare mini S20 4-byte')
connect() connect()
send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900") send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900")
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233') write_uid('04112233')
-- Setting Mifare mini S20 7-byte -- Setting Mifare mini S20 7-byte
elseif tagtype == 2 then elseif tagtype == 2 then
print('Setting: Ultimate Magic card to Mifare mini S20 7-byte') print('Setting: Ultimate Magic card to Mifare mini S20 7-byte')
connect() connect()
send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900") send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900")
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
-- Setting Mifare 1k S50 4--byte -- Setting Mifare 1k S50 4--byte
elseif tagtype == 3 then elseif tagtype == 3 then
print('Setting: Ultimate Magic card to Mifare 1k S50 4-byte') print('Setting: Ultimate Magic card to Mifare 1k S50 4-byte')
connect() connect()
send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800") send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800")
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233') write_uid('04112233')
-- Setting Mifare 1k S50 7-byte -- Setting Mifare 1k S50 7-byte
elseif tagtype == 4 then elseif tagtype == 4 then
print('Setting: Ultimate Magic card to Mifare 1k S50 7-byte') print('Setting: Ultimate Magic card to Mifare 1k S50 7-byte')
connect() connect()
send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800") send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800")
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
-- Setting Mifare 4k S70 4-byte -- Setting Mifare 4k S70 4-byte
elseif tagtype == 5 then elseif tagtype == 5 then
print('Setting: Ultimate Magic card to Mifare 4k S70 4-byte') print('Setting: Ultimate Magic card to Mifare 4k S70 4-byte')
connect() connect()
send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800") send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800")
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233') write_uid('04112233')
-- Setting Mifare 4k S70 7-byte -- Setting Mifare 4k S70 7-byte
elseif tagtype == 6 then elseif tagtype == 6 then
print('Setting: Ultimate Magic card to Mifare 4k S70 7-byte') print('Setting: Ultimate Magic card to Mifare 4k S70 7-byte')
connect() connect()
send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800") send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800")
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
-- Setting UL -- Setting UL
elseif tagtype == 7 then elseif tagtype == 7 then
print('Setting: Ultimate Magic card to UL') print('Setting: Ultimate Magic card to UL')
connect() connect()
send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003") send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003")
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_otp('00000000') -- Setting OTP to default 00 00 00 00
write_version('0000000000000000') -- UL-C does not have a version write_version('0000000000000000') -- UL-C does not have a version
@ -654,48 +654,48 @@ local function set_type(tagtype)
elseif tagtype == 8 then elseif tagtype == 8 then
print('Setting: Ultimate Magic card to UL-C') print('Setting: Ultimate Magic card to UL-C')
connect() connect()
send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002") send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002")
print('Setting default permissions and 3des key') print('Setting default permissions and 3des key')
send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication
send('A22B80000000') -- Auth1 read and write access restricted send('A22B80000000') -- Auth1 read and write access restricted
send('A22C42524541') -- Default 3des key send('A22C42524541') -- Default 3des key
send('A22D4B4D4549') send('A22D4B4D4549')
send('A22E46594F55') send('A22E46594F55')
send('A22F43414E21') send('A22F43414E21')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_otp('00000000') -- Setting OTP to default 00 00 00 00
write_version('0000000000000000') -- UL-C does not have a version write_version('0000000000000000') -- UL-C does not have a version
elseif tagtype == 9 then elseif tagtype == 9 then
print('Setting: Ultimate Magic card to UL-EV1 48') print('Setting: Ultimate Magic card to UL-EV1 48')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
-- Setting UL-Ev1 default config bl 16,17 -- Setting UL-Ev1 default config bl 16,17
send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd 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('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
send('a210000000FF') send('a210000000FF')
send('a21100050000') send('a21100050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_otp('00000000') -- Setting OTP to default 00 00 00 00 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 write_version('0004030101000b03') -- UL-EV1 (48) 00 04 03 01 01 00 0b 03
elseif tagtype == 10 then elseif tagtype == 10 then
print('Setting: Ultimate Magic card to UL-EV1 128') print('Setting: Ultimate Magic card to UL-EV1 128')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
-- Setting UL-Ev1 default config bl 37,38 -- Setting UL-Ev1 default config bl 37,38
send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd 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('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
send('a225000000FF') send('a225000000FF')
send('a22600050000') send('a22600050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_otp('00000000') -- Setting OTP to default 00 00 00 00 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 write_version('0004030101000e03') -- UL-EV1 (128) 00 04 03 01 01 00 0e 03
elseif tagtype == 12 then elseif tagtype == 12 then
print('Setting: Ultimate Magic card to NTAG 210') print('Setting: Ultimate Magic card to NTAG 210')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG210 default CC block456 -- Setting NTAG210 default CC block456
send('a203e1100600') send('a203e1100600')
send('a2040300fe00') send('a2040300fe00')
@ -703,13 +703,13 @@ local function set_type(tagtype)
-- Setting cfg1/cfg2 -- Setting cfg1/cfg2
send('a210000000FF') send('a210000000FF')
send('a21100050000') send('a21100050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03 write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03
elseif tagtype == 13 then elseif tagtype == 13 then
print('Setting: Ultimate Magic card to NTAG 212') print('Setting: Ultimate Magic card to NTAG 212')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG212 default CC block456 -- Setting NTAG212 default CC block456
send('a203e1101000') send('a203e1101000')
send('a2040103900a') send('a2040103900a')
@ -717,13 +717,13 @@ local function set_type(tagtype)
-- Setting cfg1/cfg2 -- Setting cfg1/cfg2
send('a225000000FF') send('a225000000FF')
send('a22600050000') send('a22600050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03 write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03
elseif tagtype == 14 then elseif tagtype == 14 then
print('Setting: Ultimate Magic card to NTAG 213') print('Setting: Ultimate Magic card to NTAG 213')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG213 default CC block456 -- Setting NTAG213 default CC block456
send('a203e1101200') send('a203e1101200')
send('a2040103a00c') send('a2040103a00c')
@ -731,13 +731,13 @@ local function set_type(tagtype)
-- setting cfg1/cfg2 -- setting cfg1/cfg2
send('a229000000ff') send('a229000000ff')
send('a22a00050000') send('a22a00050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03 write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03
elseif tagtype == 15 then elseif tagtype == 15 then
print('Setting: Ultimate Magic card to NTAG 215') print('Setting: Ultimate Magic card to NTAG 215')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG215 default CC block456 -- Setting NTAG215 default CC block456
send('a203e1103e00') send('a203e1103e00')
send('a2040300fe00') send('a2040300fe00')
@ -745,13 +745,13 @@ local function set_type(tagtype)
-- setting cfg1/cfg2 -- setting cfg1/cfg2
send('a283000000ff') send('a283000000ff')
send('a28400050000') send('a28400050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03 write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03
elseif tagtype == 16 then elseif tagtype == 16 then
print('Setting: Ultimate Magic card to NTAG 216') print('Setting: Ultimate Magic card to NTAG 216')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG216 default CC block456 -- Setting NTAG216 default CC block456
send('a203e1106d00') send('a203e1106d00')
send('a2040300fe00') send('a2040300fe00')
@ -759,56 +759,56 @@ local function set_type(tagtype)
-- setting cfg1/cfg2 -- setting cfg1/cfg2
send('a2e3000000ff') send('a2e3000000ff')
send('a2e400050000') send('a2e400050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03 write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03
elseif tagtype == 17 then elseif tagtype == 17 then
print('Setting: Ultimate Magic card to NTAG I2C 1K') print('Setting: Ultimate Magic card to NTAG I2C 1K')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG I2C 1K default CC block456 -- Setting NTAG I2C 1K default CC block456
send('a203e1106D00') send('a203e1106D00')
send('a2040300fe00') send('a2040300fe00')
send('a20500000000') send('a20500000000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03 write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03
elseif tagtype == 18 then elseif tagtype == 18 then
print('Setting: Ultimate Magic card to NTAG I2C 2K') print('Setting: Ultimate Magic card to NTAG I2C 2K')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG I2C 2K default CC block456 -- Setting NTAG I2C 2K default CC block456
send('a203e110EA00') send('a203e110EA00')
send('a2040300fe00') send('a2040300fe00')
send('a20500000000') send('a20500000000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03 write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03
elseif tagtype == 19 then elseif tagtype == 19 then
print('Setting: Ultimate Magic card to NTAG I2C plus 1K') print('Setting: Ultimate Magic card to NTAG I2C plus 1K')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG I2C 1K default CC block456 -- Setting NTAG I2C 1K default CC block456
send('a203e1106D00') send('a203e1106D00')
send('a2040300fe00') send('a2040300fe00')
send('a20500000000') send('a20500000000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03 write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03
elseif tagtype == 20 then elseif tagtype == 20 then
print('Setting: Ultimate Magic card to NTAG I2C plus 2K') print('Setting: Ultimate Magic card to NTAG I2C plus 2K')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG I2C 2K default CC block456 -- Setting NTAG I2C 2K default CC block456
send('a203e1106D00') send('a203e1106D00')
send('a2040300fe00') send('a2040300fe00')
send('a20500000000') send('a20500000000')
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03 write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03
elseif tagtype == 21 then elseif tagtype == 21 then
print('Setting: Ultimate Magic card to NTAG 213F') print('Setting: Ultimate Magic card to NTAG 213F')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG213 default CC block456 -- Setting NTAG213 default CC block456
send('a203e1101200') send('a203e1101200')
send('a2040103a00c') send('a2040103a00c')
@ -816,13 +816,13 @@ local function set_type(tagtype)
-- setting cfg1/cfg2 -- setting cfg1/cfg2
send('a229000000ff') send('a229000000ff')
send('a22a00050000') send('a22a00050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03 write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03
elseif tagtype == 22 then elseif tagtype == 22 then
print('Setting: Ultimate Magic card to NTAG 216F') print('Setting: Ultimate Magic card to NTAG 216F')
connect() connect()
send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
-- Setting NTAG216 default CC block456 -- Setting NTAG216 default CC block456
send('a203e1106d00') send('a203e1106d00')
send('a2040300fe00') send('a2040300fe00')
@ -830,11 +830,11 @@ local function set_type(tagtype)
-- setting cfg1/cfg2 -- setting cfg1/cfg2
send('a2e3000000ff') send('a2e3000000ff')
send('a2e400050000') send('a2e400050000')
lib14a.disconnect() lib14a.disconnect()
write_uid('04112233445566') write_uid('04112233445566')
write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03 write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03
else else
oops('No matching tag types') oops('No matching tag types')
end end
lib14a.disconnect() lib14a.disconnect()
if resp == '04' then if resp == '04' then

View file

@ -1384,11 +1384,11 @@ static int CmdHF15WriteAfi(const char *Cmd) {
// arg0 (datalen, cmd len? .arg0 == crc?) // arg0 (datalen, cmd len? .arg0 == crc?)
// arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 ) // arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 )
// arg2 (recv == 1 == expect a response) // arg2 (recv == 1 == expect a response)
uint8_t read_respone = 1; uint8_t read_response = 1;
PacketResponseNG resp; PacketResponseNG resp;
clearCommandBuffer(); 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) { if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) {
PrintAndLogEx(ERR, "iso15693 timeout"); PrintAndLogEx(ERR, "iso15693 timeout");

View file

@ -1964,11 +1964,11 @@ int infoHF_EMRTD_offline(const char *path) {
strncat(filepath, PATHSEP, 2); strncat(filepath, PATHSEP, 2);
strcat(filepath, dg_table[EF_COM].filename); strcat(filepath, dg_table[EF_COM].filename);
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && 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)) {
PrintAndLogEx(ERR, "Failed to read EF_COM"); PrintAndLogEx(ERR, "Failed to read EF_COM");
free(filepath); free(filepath);
return PM3_ESOFT; return PM3_ESOFT;
} }
int res = emrtd_print_ef_com_info(data, datalen); 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); strcat(filepath, dg_table[EF_CardAccess].filename);
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || 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)) {
emrtd_print_ef_cardaccess_info(data, datalen); emrtd_print_ef_cardaccess_info(data, datalen);
free(data); free(data);
} else { } else {
PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE"); PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE");
} }
@ -2010,11 +2010,11 @@ int infoHF_EMRTD_offline(const char *path) {
strncat(filepath, PATHSEP, 2); strncat(filepath, PATHSEP, 2);
strcat(filepath, dg_table[EF_SOD].filename); strcat(filepath, dg_table[EF_SOD].filename);
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && 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)) {
PrintAndLogEx(ERR, "Failed to read EF_SOD"); PrintAndLogEx(ERR, "Failed to read EF_SOD");
free(filepath); free(filepath);
return PM3_ESOFT; return PM3_ESOFT;
} }
// coverity scan CID 395630, // coverity scan CID 395630,
@ -2040,7 +2040,7 @@ int infoHF_EMRTD_offline(const char *path) {
strncat(filepath, PATHSEP, 2); strncat(filepath, PATHSEP, 2);
strcat(filepath, dg->filename); strcat(filepath, dg->filename);
if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || 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 // we won't halt on parsing errors
if (dg->parser != NULL) { if (dg->parser != NULL) {
dg->parser(data, datalen); 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) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) {
BAC = false; BAC = false;
} else { } else {
strn_upper((char*)docnum, slen); strn_upper((char *)docnum, slen);
if (slen != 9) { if (slen != 9) {
// Pad to 9 with < // Pad to 9 with <
memset(docnum + slen, '<', 9 - slen); memset(docnum + slen, '<', 9 - slen);
@ -2144,7 +2144,7 @@ static int CmdHFeMRTDDump(const char *Cmd) {
error = true; error = true;
} else { } else {
BAC = true; BAC = true;
strn_upper((char*)mrz, slen); strn_upper((char *)mrz, slen);
memcpy(docnum, &mrz[0], 9); memcpy(docnum, &mrz[0], 9);
memcpy(dob, &mrz[13], 6); memcpy(dob, &mrz[13], 6);
memcpy(expiry, &mrz[21], 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) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) {
BAC = false; BAC = false;
} else { } else {
strn_upper((char*)docnum, slen); strn_upper((char *)docnum, slen);
if (slen != 9) { if (slen != 9) {
memset(docnum + slen, '<', 9 - slen); memset(docnum + slen, '<', 9 - slen);
} }
@ -2245,7 +2245,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) {
error = true; error = true;
} else { } else {
BAC = true; BAC = true;
strn_upper((char*)mrz, slen); strn_upper((char *)mrz, slen);
memcpy(docnum, &mrz[0], 9); memcpy(docnum, &mrz[0], 9);
memcpy(dob, &mrz[13], 6); memcpy(dob, &mrz[13], 6);
memcpy(expiry, &mrz[21], 6); memcpy(expiry, &mrz[21], 6);

View file

@ -228,7 +228,7 @@ static int CmdHFEPAPACESimulate(const char *Cmd) {
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
// bool use_pc = arg_get_lit(ctx, 1); // bool use_pc = arg_get_lit(ctx, 1);
// uint8_t pwd_type = 0; // uint8_t pwd_type = 0;
int plen = 0; int plen = 0;
uint8_t pwd[6] = {0}; uint8_t pwd[6] = {0};
@ -273,7 +273,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"}, {"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"},
{"replay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"}, {"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} {NULL, NULL, NULL, NULL}
}; };

View file

@ -369,7 +369,7 @@ static bool mf_write_block(const uint8_t *key, uint8_t keytype, uint8_t blockno,
PacketResponseNG resp; PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) {
PrintAndLogEx(FAILED, "Command execute timeout"); PrintAndLogEx(FAILED, "Command execute timeout");
return PM3_ETIMEOUT; return false;
} }
return (resp.oldarg[0] & 0xff); return (resp.oldarg[0] & 0xff);
@ -569,7 +569,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) {
uint8_t blockno = (uint8_t)b; uint8_t blockno = (uint8_t)b;
// Sector trailer sanity checks. // Sector trailer sanity checks.
// Warn if ACL is strict read-only, or invalid ACL. // Warn if ACL is strict read-only, or invalid ACL.
if (mfIsSectorTrailer(blockno)) { if (mfIsSectorTrailer(blockno)) {
PrintAndLogEx(INFO, "Sector trailer (ST) write detected"); PrintAndLogEx(INFO, "Sector trailer (ST) write detected");
@ -3688,8 +3688,6 @@ static int CmdHF14AMfSim(const char *Cmd) {
} }
CLIParserFree(ctx); CLIParserFree(ctx);
nonces_t data[1];
sector_t *k_sector = NULL; sector_t *k_sector = NULL;
//Validations //Validations
@ -3780,7 +3778,7 @@ static int CmdHF14AMfSim(const char *Cmd) {
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue;
if (!(flags & FLAG_NR_AR_ATTACK)) break; if (!(flags & FLAG_NR_AR_ATTACK)) break;
if ((resp.oldarg[0] & 0xffff) != CMD_HF_MIFARE_SIMULATE) break; if ((resp.oldarg[0] & 0xffff) != CMD_HF_MIFARE_SIMULATE) break;
nonces_t data[1];
memcpy(data, resp.data.asBytes, sizeof(data)); memcpy(data, resp.data.asBytes, sizeof(data));
readerAttack(k_sector, k_sectorsCount, data[0], setEmulatorMem, verbose); readerAttack(k_sector, k_sectorsCount, data[0], setEmulatorMem, verbose);
} }
@ -6915,9 +6913,14 @@ static int CmdHF14AMfView(const char *Cmd) {
return res; return res;
} }
typedef union UDATA {
uint8_t *bytes;
mfc_vigik_t *vigik;
} UDATA;
// allocate memory // allocate memory
uint8_t *d = calloc(bytes_read, sizeof(uint8_t)); UDATA d;
if (d == NULL) { d.bytes = calloc(bytes_read, sizeof(uint8_t));
if (d.bytes == NULL) {
return PM3_EMALLOC; return PM3_EMALLOC;
} }
uint16_t dlen = 0; uint16_t dlen = 0;
@ -6925,14 +6928,14 @@ static int CmdHF14AMfView(const char *Cmd) {
// vigik struture sector 0 // vigik struture sector 0
uint8_t *pdump = dump; uint8_t *pdump = dump;
memcpy(d + dlen, pdump, MFBLOCK_SIZE * 3); memcpy(d.bytes + dlen, pdump, MFBLOCK_SIZE * 3);
dlen += MFBLOCK_SIZE * 3; dlen += MFBLOCK_SIZE * 3;
pdump += (MFBLOCK_SIZE * 4); // skip sectortrailer pdump += (MFBLOCK_SIZE * 4); // skip sectortrailer
// extract memory from MAD sectors // extract memory from MAD sectors
for (int i = 0; i <= madlen; i++) { for (int i = 0; i <= madlen; i++) {
if (0x4910 == mad[i] || 0x4916 == mad[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; dlen += MFBLOCK_SIZE * 3;
} }
@ -6940,8 +6943,8 @@ static int CmdHF14AMfView(const char *Cmd) {
} }
// convert_mfc_2_arr(pdump, bytes_read, d, &dlen); // convert_mfc_2_arr(pdump, bytes_read, d, &dlen);
vigik_annotate(d); vigik_annotate(d.vigik);
free(d); free(d.bytes);
} }
free(dump); 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 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 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); bool getval = arg_get_lit(ctx, 7);
uint8_t block[MFBLOCK_SIZE] = {0x00};
int dlen = 0; int dlen = 0;
uint8_t data[16] = {0}; uint8_t data[16] = {0};
CLIGetHexWithReturn(ctx, 9, data, &dlen); 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 uint8_t action = 3; // 0 Increment, 1 - Decrement, 2 - Set, 3 - Get, 4 - Decode from data
uint32_t value = 0; 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 // Need to check we only have 1 of inc/dec/set and get the value from the selected option
int optionsprovided = 0; int optionsprovided = 0;
@ -7677,11 +7678,12 @@ static int CmdHF14AMfValue(const char *Cmd) {
} }
if (action < 3) { if (action < 3) {
uint8_t isok = true;
if (g_session.pm3_present == false) if (g_session.pm3_present == false)
return PM3_ENOTTY; return PM3_ENOTTY;
if (action <= 1) { // increment/decrement value if (action <= 1) { // increment/decrement value
uint8_t block[MFBLOCK_SIZE] = {0x00};
memcpy(block, (uint8_t *)&value, 4); memcpy(block, (uint8_t *)&value, 4);
uint8_t cmddata[26]; uint8_t cmddata[26];
memcpy(cmddata, key, sizeof(key)); // Key == 6 data went to 10, so lets offset 9 for inc/dec memcpy(cmddata, key, sizeof(key)); // Key == 6 data went to 10, so lets offset 9 for inc/dec

View file

@ -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 // 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]; uint8_t product = versionhw[2];
@ -323,7 +323,7 @@ static nxp_producttype_t getProductType(uint8_t *versionhw) {
return DESFIRE_UNKNOWN_PROD; return DESFIRE_UNKNOWN_PROD;
} }
static const char *getProductTypeStr(uint8_t *versionhw) { static const char *getProductTypeStr(const uint8_t *versionhw) {
uint8_t product = versionhw[2]; uint8_t product = versionhw[2];

View file

@ -1376,7 +1376,7 @@ static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authke
} }
} }
// OTP checks // OTP checks
mfu_otp_identify_t *item = mfu_match_otp_fingerprint(data); mfu_otp_identify_t *item = mfu_match_otp_fingerprint(data);
if (item) { if (item) {
PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc); PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc);
@ -1391,9 +1391,9 @@ static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authke
} }
} }
} }
// //
out: out:
free(data); free(data);

View file

@ -311,7 +311,7 @@ static bool TexcomTK15Decode(uint32_t *implengths, uint32_t implengthslen, char
bool prevbit = (implengths[implengthslen - 3] > implengths[implengthslen - 2]); bool prevbit = (implengths[implengthslen - 3] > implengths[implengthslen - 2]);
bool thesamebit = (abs(lastimplen - (int)implengths[implengthslen - 3]) < abs(lastimplen - (int)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(bitstring, "10");
strcat(cbitstring, "1"); strcat(cbitstring, "1");
} else { } else {

View file

@ -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) { if (data[0] != 0xE1) {
topaz_tag.size = TOPAZ_STATIC_MEMORY; topaz_tag.size = TOPAZ_STATIC_MEMORY;
@ -583,9 +583,7 @@ static void topaz_print_lifecycle_state(uint8_t *data) {
// to be done // to be done
} }
static void printTopazDumpContents(uint8_t *dump, size_t size) { static void printTopazDumpContents(topaz_tag_t *dump) {
topaz_tag_t *t = (topaz_tag_t *)dump;
// uses a global var for all // uses a global var for all
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -608,14 +606,14 @@ static void printTopazDumpContents(uint8_t *dump, size_t size) {
PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| %s | %s", PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| %s | %s",
i, i,
i, i,
sprint_hex(&t->data_blocks[i][0], 8), sprint_hex(&dump->data_blocks[i][0], 8),
lockstr, lockstr,
block_info 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", 0x0D, 0x0D, sprint_hex(&dump->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", 0x0E, 0x0E, sprint_hex(&dump->data_blocks[0x0E][0], 8), topaz_ks[3]);
PrintAndLogEx(SUCCESS, "------------+-------------------------+---+------------"); PrintAndLogEx(SUCCESS, "------------+-------------------------+---+------------");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
} }
@ -797,7 +795,7 @@ static int CmdHFTopazDump(const char *Cmd) {
if (status != PM3_SUCCESS) { if (status != PM3_SUCCESS) {
return status; return status;
} }
printTopazDumpContents((uint8_t *)&topaz_tag, sizeof(topaz_tag_t)); printTopazDumpContents(&topaz_tag);
bool set_dynamic = false; bool set_dynamic = false;
if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) { 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); CLIParserFree(ctx);
// read dump file // read dump file
uint8_t *dump = NULL; topaz_tag_t *dump = NULL;
size_t bytes_read = TOPAZ_MAX_SIZE; size_t bytes_read = TOPAZ_MAX_SIZE;
int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(topaz_tag_t) + TOPAZ_MAX_SIZE); int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(topaz_tag_t) + TOPAZ_MAX_SIZE);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
return res; return res;
} }
if (bytes_read < sizeof(topaz_tag_t)) {
printTopazDumpContents(dump, bytes_read); free(dump);
return PM3_EFAILED;
}
printTopazDumpContents(dump);
if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) { if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) {

View file

@ -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) { 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 step0[2] = {0xcd, 0x0d};
uint8_t step1[3] = {0xcd, 0x00, 10}; // select e-paper type and reset e-paper uint8_t step1[3] = {0xcd, 0x00, 10}; // select e-paper type and reset e-paper
// 4 :2.13inch 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 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 step14[2]={0xcd,0x0c}; // The end of the transmission
uint8_t rx[20]; uint8_t rx[20];
uint16_t actrxlen[20], i; uint16_t actrxlen[20];
clearCommandBuffer(); clearCommandBuffer();
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); 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 // 1.54B Data transfer is complete and wait for refresh
} else { } else {
uint8_t progress;
PrintAndLogEx(DEBUG, "Step5: e-paper config2"); PrintAndLogEx(DEBUG, "Step5: e-paper config2");
ret = transceive_blocking(step5, 2, rx, 20, actrxlen, true); // cd 05 ret = transceive_blocking(step5, 2, rx, 20, actrxlen, true); // cd 05
if (ret != PM3_SUCCESS) { 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"); PrintAndLogEx(DEBUG, "Step8: Start data transfer");
if (model_nr == M2in13) { // 2.13inch 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); read_black(i, step8, model_nr, black);
ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08 ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08
if (ret != PM3_SUCCESS) { 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); PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
} }
} else if (model_nr == M2in9) { } 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); read_black(i, step8, model_nr, black);
ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08 ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08
if (ret != PM3_SUCCESS) { 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); PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
} }
} else if (model_nr == M4in2) { //4.2inch } 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); read_black(i, step8, model_nr, black);
ret = transceive_blocking(step8, 103, rx, 20, actrxlen, true); // cd 08 ret = transceive_blocking(step8, 103, rx, 20, actrxlen, true); // cd 08
if (ret != PM3_SUCCESS) { 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); PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
} }
} else if (model_nr == M7in5) { //7.5inch } 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); read_black(i, step8, model_nr, black);
ret = transceive_blocking(step8, 123, rx, 20, actrxlen, true); // cd 08 ret = transceive_blocking(step8, 123, rx, 20, actrxlen, true); // cd 08
if (ret != PM3_SUCCESS) { if (ret != PM3_SUCCESS) {
@ -872,7 +872,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) {
msleep(6); msleep(6);
} }
} else if (model_nr == M2in13B) { //2.13inch B } 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); read_black(i, step8, model_nr, black);
ret = transceive_blocking(step8, 109, rx, 20, actrxlen, false); // cd 08 ret = transceive_blocking(step8, 109, rx, 20, actrxlen, false); // cd 08
if (ret != PM3_SUCCESS) { 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 } 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); read_black(i, step8, model_nr, black);
//memset(&step8[3], 0xf0, 120); //memset(&step8[3], 0xf0, 120);
ret = transceive_blocking(step8, 123, rx, 20, actrxlen, true); // cd 08 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; return ret;
} }
} else if (model_nr == M2in7) { //2.7inch } 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); //read_black(i,step8, model_nr, black);
memset(&step8[3], 0xFF, sizeof(step8) - 3); memset(&step8[3], 0xFF, sizeof(step8) - 3);
ret = transceive_blocking(step8, 124, rx, 20, actrxlen, true); // cd 08 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"); PrintAndLogEx(DEBUG, "Step9b");
if (model_nr == M2in7) { 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); read_black(i, step13, model_nr, black);
ret = transceive_blocking(step13, 124, rx, 20, actrxlen, true); //CD 19 ret = transceive_blocking(step13, 124, rx, 20, actrxlen, true); //CD 19
if (ret != PM3_SUCCESS) { 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); PrintAndLogEx(INPLACE, "Progress: %d %%", progress);
} }
} else if (model_nr == M2in13B) { } 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); read_red(i, step13, model_nr, red);
//memset(&step13[3], 0xfE, 106); //memset(&step13[3], 0xfE, 106);
ret = transceive_blocking(step13, 109, rx, 20, actrxlen, false); ret = transceive_blocking(step13, 109, rx, 20, actrxlen, false);

View file

@ -15,77 +15,77 @@
#define TIMEOUT 2000 #define TIMEOUT 2000
#define c2l(c,l) (l = ((unsigned long)(*((c)++))), \ #define c2l(c,l) (l = ((unsigned long)(*((c)++))), \
l |= ((unsigned long)(*((c)++))) << 8L, \ l |= ((unsigned long)(*((c)++))) << 8L, \
l |= ((unsigned long)(*((c)++))) << 16L, \ l |= ((unsigned long)(*((c)++))) << 16L, \
l |= ((unsigned long)(*((c)++))) << 24L) l |= ((unsigned long)(*((c)++))) << 24L)
/* NOTE - c is not incremented as per c2l */ /* NOTE - c is not incremented as per c2l */
#define c2ln(c,l1,l2,n) { \ #define c2ln(c,l1,l2,n) { \
c += n; \ c += n; \
l1 = l2 = 0; \ l1 = l2 = 0; \
switch (n) { \ switch (n) { \
case 8: l2 = ((unsigned long)(*(--(c)))) << 24L; \ case 8: l2 = ((unsigned long)(*(--(c)))) << 24L; \
case 7: l2 |= ((unsigned long)(*(--(c)))) << 16L; \ case 7: l2 |= ((unsigned long)(*(--(c)))) << 16L; \
case 6: l2 |= ((unsigned long)(*(--(c)))) << 8L; \ case 6: l2 |= ((unsigned long)(*(--(c)))) << 8L; \
case 5: l2 |= ((unsigned long)(*(--(c)))); \ case 5: l2 |= ((unsigned long)(*(--(c)))); \
case 4: l1 = ((unsigned long)(*(--(c)))) << 24L; \ case 4: l1 = ((unsigned long)(*(--(c)))) << 24L; \
case 3: l1 |= ((unsigned long)(*(--(c)))) << 16L; \ case 3: l1 |= ((unsigned long)(*(--(c)))) << 16L; \
case 2: l1 |= ((unsigned long)(*(--(c)))) << 8L; \ case 2: l1 |= ((unsigned long)(*(--(c)))) << 8L; \
case 1: l1 |= ((unsigned long)(*(--(c)))); \ case 1: l1 |= ((unsigned long)(*(--(c)))); \
} \ } \
} }
#define l2c(l,c) (*((c)++) = (uint8_t)(((l)) & 0xff), \ #define l2c(l,c) (*((c)++) = (uint8_t)(((l)) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \ *((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \ *((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \
*((c)++) = (uint8_t)(((l) >> 24L) & 0xff)) *((c)++) = (uint8_t)(((l) >> 24L) & 0xff))
/* NOTE - c is not incremented as per l2c */ /* NOTE - c is not incremented as per l2c */
#define l2cn(l1,l2,c,n) { \ #define l2cn(l1,l2,c,n) { \
c += n; \ c += n; \
switch (n) { \ switch (n) { \
case 8: *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \ case 8: *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
case 7: *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \ case 7: *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
case 6: *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \ case 6: *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
case 5: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ case 5: *(--(c)) = (uint8_t)(((l2)) & 0xff); \
case 4: *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \ case 4: *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
case 3: *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \ case 3: *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
case 2: *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \ case 2: *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
case 1: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ case 1: *(--(c)) = (uint8_t)(((l1)) & 0xff); \
} \ } \
} }
/* NOTE - c is not incremented as per n2l */ /* NOTE - c is not incremented as per n2l */
#define n2ln(c,l1,l2,n) { \ #define n2ln(c,l1,l2,n) { \
c += n; \ c += n; \
l1 = l2 = 0; \ l1 = l2 = 0; \
switch (n) { \ switch (n) { \
case 8: l2 = ((unsigned long)(*(--(c)))); \ case 8: l2 = ((unsigned long)(*(--(c)))); \
case 7: l2 |= ((unsigned long)(*(--(c)))) << 8; \ case 7: l2 |= ((unsigned long)(*(--(c)))) << 8; \
case 6: l2 |= ((unsigned long)(*(--(c)))) << 16; \ case 6: l2 |= ((unsigned long)(*(--(c)))) << 16; \
case 5: l2 |= ((unsigned long)(*(--(c)))) << 24; \ case 5: l2 |= ((unsigned long)(*(--(c)))) << 24; \
case 4: l1 = ((unsigned long)(*(--(c)))); \ case 4: l1 = ((unsigned long)(*(--(c)))); \
case 3: l1 |= ((unsigned long)(*(--(c)))) << 8; \ case 3: l1 |= ((unsigned long)(*(--(c)))) << 8; \
case 2: l1 |= ((unsigned long)(*(--(c)))) << 16; \ case 2: l1 |= ((unsigned long)(*(--(c)))) << 16; \
case 1: l1 |= ((unsigned long)(*(--(c)))) << 24; \ case 1: l1 |= ((unsigned long)(*(--(c)))) << 24; \
} \ } \
} }
/* NOTE - c is not incremented as per l2n */ /* NOTE - c is not incremented as per l2n */
#define l2nn(l1,l2,c,n) { \ #define l2nn(l1,l2,c,n) { \
c+=n; \ c+=n; \
switch (n) { \ switch (n) { \
case 8: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ case 8: *(--(c)) = (uint8_t)(((l2)) & 0xff); \
case 7: *(--(c)) = (uint8_t)(((l2) >> 8) & 0xff); \ case 7: *(--(c)) = (uint8_t)(((l2) >> 8) & 0xff); \
case 6: *(--(c)) = (uint8_t)(((l2) >> 16) & 0xff); \ case 6: *(--(c)) = (uint8_t)(((l2) >> 16) & 0xff); \
case 5: *(--(c)) = (uint8_t)(((l2) >> 24) & 0xff); \ case 5: *(--(c)) = (uint8_t)(((l2) >> 24) & 0xff); \
case 4: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ case 4: *(--(c)) = (uint8_t)(((l1)) & 0xff); \
case 3: *(--(c)) = (uint8_t)(((l1) >> 8) & 0xff); \ case 3: *(--(c)) = (uint8_t)(((l1) >> 8) & 0xff); \
case 2: *(--(c)) = (uint8_t)(((l1) >> 16) & 0xff); \ case 2: *(--(c)) = (uint8_t)(((l1) >> 16) & 0xff); \
case 1: *(--(c)) = (uint8_t)(((l1) >> 24) & 0xff); \ case 1: *(--(c)) = (uint8_t)(((l1) >> 24) & 0xff); \
} \ } \
} }
#define n2l(c,l) (l = ((unsigned long)(*((c)++))) << 24L, \ #define n2l(c,l) (l = ((unsigned long)(*((c)++))) << 24L, \
l |= ((unsigned long)(*((c)++))) << 16L, \ l |= ((unsigned long)(*((c)++))) << 16L, \
@ -98,17 +98,17 @@
*((c)++) = (uint8_t)(((l)) & 0xff)) *((c)++) = (uint8_t)(((l)) & 0xff))
#define C_RC2(n) \ #define C_RC2(n) \
t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; \ t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; \
x0 = (t << 1) | (t >> 15); \ x0 = (t << 1) | (t >> 15); \
t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; \ t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; \
x1 = (t << 2) | (t >> 14); \ x1 = (t << 2) | (t >> 14); \
t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; \ t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; \
x2 = (t << 3) | (t >> 13); \ x2 = (t << 3) | (t >> 13); \
t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; \ t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; \
x3 = (t << 5) | (t >> 11); x3 = (t << 5) | (t >> 11);
#define RC2_ENCRYPT 1 #define RC2_ENCRYPT 1
#define RC2_DECRYPT 0 #define RC2_DECRYPT 0
typedef unsigned int RC2_INT; 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) { void RC2_encrypt(unsigned long *d, RC2_KEY *key) {
int i, n; int i, n;
register RC2_INT *p0, *p1; register RC2_INT *p0, *p1;
register RC2_INT x0, x1, x2, x3, t; register RC2_INT x0, x1, x2, x3;
unsigned long l; unsigned long l;
l = d[0]; l = d[0];
@ -217,7 +217,7 @@ void RC2_encrypt(unsigned long *d, RC2_KEY *key) {
p0 = p1 = &(key->data[0]); p0 = p1 = &(key->data[0]);
for (;;) { 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); x0 = (t << 1) | (t >> 15);
t = (x1 + (x2 & ~x0) + (x3 & x0) + * (p0++)) & 0xffff; t = (x1 + (x2 & ~x0) + (x3 & x0) + * (p0++)) & 0xffff;
x1 = (t << 2) | (t >> 14); 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) { void RC2_decrypt(unsigned long *d, RC2_KEY *key) {
int i, n; int i, n;
register RC2_INT *p0, *p1; register RC2_INT *p0, *p1;
register RC2_INT x0, x1, x2, x3, t; register RC2_INT x0, x1, x2, x3;
unsigned long l; unsigned long l;
l = d[0]; l = d[0];
@ -260,7 +260,7 @@ void RC2_decrypt(unsigned long *d, RC2_KEY *key) {
p0 = &(key->data[63]); p0 = &(key->data[63]);
p1 = &(key->data[0]); p1 = &(key->data[0]);
for (;;) { for (;;) {
t = ((x3 << 11) | (x3 >> 5)) & 0xffff; register RC2_INT t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
x3 = (t - (x0 & ~x2) - (x1 & x2) - * (p0--)) & 0xffff; x3 = (t - (x0 & ~x2) - (x1 & x2) - * (p0--)) & 0xffff;
t = ((x2 << 13) | (x2 >> 3)) & 0xffff; t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
x2 = (t - (x3 & ~x1) - (x0 & x1) - * (p0--)) & 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->flags = (ISO14B_APPEND_CRC | ISO14B_RAW);
packet->rawlen = 11; packet->rawlen = 11;
packet->raw[0] = 0x02; packet->raw[0] = 0x02;
packet->raw[1] = 0x20; // set command: read mem packet->raw[1] = 0x20; // set command: read mem
memcpy(packet->raw + 2, card.uid, 8); // store uid memcpy(packet->raw + 2, card.uid, 8); // store uid
for (int retry = 0; (retry < 5 && blocknum < sizeof(info_blocks)); retry++) { 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; 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) { if (status != PM3_SUCCESS) {
free(packet); free(packet);
switch_off_field(); 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)); 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}; uint8_t data[256 * 4] = {0};
// set up the read command // set up the read command
packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW); packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW);
packet->rawlen = 11; packet->rawlen = 11;
packet->raw[0] = 0x02; 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); PrintAndLogEx(INFO, "." NOLF);
for (int retry = 0; (retry < 5 && blocknum < 0x100); retry++) { 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; packet->raw[10] = blocknum & 0xFF;
PacketResponseNG resp; 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.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'); 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"); PrintAndLogEx(FAILED, "retrying one more time");
continue; continue;
} }
@ -722,8 +722,8 @@ static int CmdHFXeroxDump(const char *Cmd) {
memcpy(k1, k2, sizeof(k1)); memcpy(k1, k2, sizeof(k1));
k1[2] = k2[3] ^ data[0x22 * 4 + 0]; k1[2] = k2[3] ^ data[0x22 * 4 + 0];
k1[3] = k2[4] ^ data[0x22 * 4 + 1]; // first_key[7]; k1[3] = k2[4] ^ data[0x22 * 4 + 1]; // first_key[7];
k1[5] = k2[1] ^ 0x01; // 01 = crypto method? rfid[23][2] k1[5] = k2[1] ^ 0x01; // 01 = crypto method? rfid[23][2]
RC2_set_key(&exp_key, 8, k1, 64); RC2_set_key(&exp_key, 8, k1, 64);
@ -747,7 +747,7 @@ static int CmdHFXeroxDump(const char *Cmd) {
uint16_t cs, csd; uint16_t cs, csd;
// calc checksum // 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; cs = ~cs;
csd = (decr[7] << 8) | decr[6]; csd = (decr[7] << 8) | decr[6];
@ -772,7 +772,7 @@ static int CmdHFXeroxDump(const char *Cmd) {
PrintAndLogEx(INFO, "---------+--------------+----------"); PrintAndLogEx(INFO, "---------+--------------+----------");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
if (0 == filename[0]) { // generate filename from uid if (0 == filename[0]) { // generate filename from uid
/* /*
PrintAndLogEx(INFO, "Using UID as filename"); PrintAndLogEx(INFO, "Using UID as filename");

View file

@ -592,12 +592,12 @@ static int CmdLCD(const char *Cmd) {
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
int r_len = 0; int r_len = 0;
uint8_t raw[1] = {0}; uint8_t raw[1] = {0};
CLIGetHexWithReturn(ctx, 1, raw, &r_len); CLIGetHexWithReturn(ctx, 1, raw, &r_len);
int j = arg_get_int_def(ctx, 2, 1); int j = arg_get_int_def(ctx, 2, 1);
CLIParserFree(ctx);
if (j < 1) { if (j < 1) {
PrintAndLogEx(WARNING, "Count must be larger than zero"); PrintAndLogEx(WARNING, "Count must be larger than zero");
return PM3_EINVARG; return PM3_EINVARG;

View file

@ -672,11 +672,6 @@ static int CmdEM410xClone(const char *Cmd) {
return PM3_EINVARG; 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); 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 { struct {

View file

@ -2025,10 +2025,8 @@ int CmdEM4x05Sniff(const char *Cmd) {
size_t idx = 0; size_t idx = 0;
// loop though sample buffer // loop though sample buffer
while (idx < g_GraphTraceLen) { while (idx < g_GraphTraceLen) {
bool eop = false;
bool haveData = false; bool haveData = false;
bool pwd = false; bool pwd = false;
uint32_t tmpValue;
idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples); idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples);
size_t pktOffset = idx; size_t pktOffset = idx;
@ -2044,6 +2042,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
memset(bits.ptr, 0, bits.size); memset(bits.ptr, 0, bits.size);
bits.idx = 0; bits.idx = 0;
bool eop = false;
while ((idx < g_GraphTraceLen) && !eop) { while ((idx < g_GraphTraceLen) && !eop) {
CycleWidth = idx; CycleWidth = idx;
idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples); idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples);
@ -2081,7 +2080,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
pwd = true; pwd = true;
cmdText = "Logon"; cmdText = "Logon";
strncpy(blkAddr, " ", sizeof(blkAddr)); 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); 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)) { if ((strncmp(bits.ptr, "0101", 4) == 0) && (bits.idx == 56)) {
haveData = true; haveData = true;
cmdText = "Write"; 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); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
if (tmpValue == 2) { if (tmpValue == 2) {
pwd = true; pwd = true;
@ -2103,7 +2102,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
haveData = true; haveData = true;
pwd = false; pwd = false;
cmdText = "Read"; 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); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue);
strncpy(dataText, " ", sizeof(dataText)); strncpy(dataText, " ", sizeof(dataText));
} }
@ -2114,7 +2113,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
pwd = false; pwd = false;
cmdText = "Protect"; cmdText = "Protect";
strncpy(blkAddr, " ", sizeof(blkAddr)); 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); snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
} }
@ -2124,7 +2123,7 @@ int CmdEM4x05Sniff(const char *Cmd) {
pwd = false; pwd = false;
cmdText = "Disable"; cmdText = "Disable";
strncpy(blkAddr, " ", sizeof(blkAddr)); 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); snprintf(dataText, sizeof(dataText), "%08X", tmpValue);
} }

View file

@ -404,7 +404,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
uint8_t data[MAX_GRAPH_TRACE_LEN] = {0}; uint8_t data[MAX_GRAPH_TRACE_LEN] = {0};
size_t datasize = getFromGraphBuf(data); size_t datasize = getFromGraphBuf(data);
uint8_t rawbits[4096]; uint8_t rawbits[4096] = {0};
int rawbit = 0; int rawbit = 0;
int worst = 0, worstPos = 0; int worst = 0, worstPos = 0;

View file

@ -263,8 +263,8 @@ static int CmdParadoxClone(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
uint32_t blocks[4]; uint32_t blocks[4] = {0};
if (raw_len != 0) { if (raw_len != 0) {
if (raw_len != 12) { if (raw_len != 12) {
PrintAndLogEx(ERR, "Data must be 12 bytes (24 HEX characters) %d", raw_len); PrintAndLogEx(ERR, "Data must be 12 bytes (24 HEX characters) %d", raw_len);
@ -280,39 +280,39 @@ static int CmdParadoxClone(const char *Cmd) {
manchester[0] = 0x0F; // preamble manchester[0] = 0x0F; // preamble
manchester[1] = 0x05; // Leading zeros - Note: from this byte on, is part of the CRC calculation manchester[1] = 0x05; // Leading zeros - Note: from this byte on, is part of the CRC calculation
manchester[2] = 0x55; // Leading zeros its 4 bits out for the CRC, so we need too move manchester[2] = 0x55; // Leading zeros its 4 bits out for the CRC, so we need too move
manchester[3] = 0x55; // Leading zeros back 4 bits once we have the crc (done below) manchester[3] = 0x55; // Leading zeros back 4 bits once we have the crc (done below)
// add FC // add FC
t1 = manchesterEncode2Bytes (fc); t1 = manchesterEncode2Bytes(fc);
manchester[4] = (t1 >> 8) & 0xFF; manchester[4] = (t1 >> 8) & 0xFF;
manchester[5] = t1 & 0xFF; manchester[5] = t1 & 0xFF;
// add cn // add cn
t1 = manchesterEncode2Bytes (cn); t1 = manchesterEncode2Bytes(cn);
manchester[6] = (t1 >> 24) & 0xFF; manchester[6] = (t1 >> 24) & 0xFF;
manchester[7] = (t1 >> 16) & 0xFF; manchester[7] = (t1 >> 16) & 0xFF;
manchester[8] = (t1 >> 8) & 0xFF; manchester[8] = (t1 >> 8) & 0xFF;
manchester[9] = t1 & 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 // add crc
t1 = manchesterEncode2Bytes (crc); t1 = manchesterEncode2Bytes(crc);
manchester[10] = (t1 >> 8) & 0xFF; manchester[10] = (t1 >> 8) & 0xFF;
manchester[11] = t1 & 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. // 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++) 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) // Add trailing 1010 (11)
manchester[11] |= (1 << 3); manchester[11] |= (1 << 3);
manchester[11] |= (1 << 1); manchester[11] |= (1 << 1);
// move into tag blocks // move into tag blocks
for (int i = 0; i < 12; i++) 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 // Paradox - FSK2a, data rate 50, 3 data blocks

View file

@ -2362,7 +2362,7 @@ static int CmdT55xxRestore(const char *Cmd) {
} }
// read dump file // read dump file
uint8_t *dump = NULL; uint32_t *dump = NULL;
size_t bytes_read = 0; size_t bytes_read = 0;
res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (T55x7_BLOCK_COUNT * 4)); res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (T55x7_BLOCK_COUNT * 4));
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
@ -2387,11 +2387,10 @@ static int CmdT55xxRestore(const char *Cmd) {
snprintf(pwdopt, sizeof(pwdopt), "-p %08X", password); snprintf(pwdopt, sizeof(pwdopt), "-p %08X", password);
} }
uint32_t *data = (uint32_t *) dump;
uint8_t idx; uint8_t idx;
// Restore endien for writing to card // Restore endien for writing to card
for (idx = 0; idx < 12; idx++) { for (idx = 0; idx < 12; idx++) {
data[idx] = BSWAP_32(data[idx]); dump[idx] = BSWAP_32(dump[idx]);
} }
// Have data ready, lets write // Have data ready, lets write
@ -2400,12 +2399,12 @@ static int CmdT55xxRestore(const char *Cmd) {
// write blocks 1..3 page 1 // write blocks 1..3 page 1
// update downlink mode (if needed) and write b 0 // update downlink mode (if needed) and write b 0
downlink_mode = 0; downlink_mode = 0;
if ((((data[11] >> 28) & 0xF) == 6) || (((data[11] >> 28) & 0xF) == 9)) if ((((dump[11] >> 28) & 0xF) == 6) || (((dump[11] >> 28) & 0xF) == 9))
downlink_mode = (data[11] >> 10) & 3; downlink_mode = (dump[11] >> 10) & 3;
// write out blocks 1-7 page 0 // write out blocks 1-7 page 0
for (idx = 1; idx <= 7; idx++) { 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) { if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); 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 password was set on the "blank" update as we may have just changed it
if (usepwd) { 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 // write out blocks 1-3 page 1
for (idx = 9; idx <= 11; idx++) { 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) { if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx);
@ -2430,7 +2429,7 @@ static int CmdT55xxRestore(const char *Cmd) {
config.downlink_mode = downlink_mode; config.downlink_mode = downlink_mode;
// Write the page 0 config // 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) { if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "Warning: error writing blk 0"); PrintAndLogEx(WARNING, "Warning: error writing blk 0");
} }
@ -4012,7 +4011,6 @@ static int CmdT55xxSniff(const char *Cmd) {
size_t idx = 0; size_t idx = 0;
uint32_t usedPassword, blockData; uint32_t usedPassword, blockData;
int pulseSamples = 0, pulseIdx = 0; int pulseSamples = 0, pulseIdx = 0;
const char *modeText;
char pwdText[100]; char pwdText[100];
char dataText[100]; char dataText[100];
int pulseBuffer[80] = { 0 }; // max should be 73 +/- - Holds Pulse widths int pulseBuffer[80] = { 0 }; // max should be 73 +/- - Holds Pulse widths
@ -4038,7 +4036,7 @@ static int CmdT55xxSniff(const char *Cmd) {
int maxWidth = 0; int maxWidth = 0;
data[0] = 0; data[0] = 0;
bool have_data = false; bool have_data = false;
modeText = "Default"; const char *modeText = "Default";
strncpy(pwdText, " ", sizeof(pwdText)); strncpy(pwdText, " ", sizeof(pwdText));
strncpy(dataText, " ", sizeof(dataText)); strncpy(dataText, " ", sizeof(dataText));

View file

@ -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)"}, {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)"}, {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"}, {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"}, {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)"}, {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)"}, {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)"}, {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)"}, {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"}, {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"}, {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"}, {0x1018, PIV_TAG_ID("\x5F\xC1\x23"), 3, PIV_OPTIONAL, "Pairing Code Reference Data Container"},
PIV_CONTAINER_FINISH, 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) { if (tlvdb) {
tlvdb_visit(tlvdb, piv_print_cb, NULL, 0); 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) { if (buf == NULL || len == 0) {
return; return;
} }
@ -598,7 +598,7 @@ static int PivGetData(Iso7816CommandChannel channel, const uint8_t tag[], size_t
return PM3_SUCCESS; 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; struct tlvdb_root *root = NULL;
if (cid == NULL) { if (cid == NULL) {
@ -940,9 +940,8 @@ static int CmdPIVScan(const char *Cmd) {
memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET)); memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET));
aid_len = sizeof(PIV_APPLET); aid_len = sizeof(PIV_APPLET);
} }
int res = 0;
if (activateField == true) { 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 (res != PM3_SUCCESS) {
if (leaveSignalON == false) { if (leaveSignalON == false) {
DropFieldEx(channel); DropFieldEx(channel);

View file

@ -485,8 +485,6 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
uint32_t end_of_transmission_timestamp = 0; uint32_t end_of_transmission_timestamp = 0;
uint8_t topaz_reader_command[9]; uint8_t topaz_reader_command[9];
char explanation[40] = {0}; 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 *first_hdr = (tracelog_hdr_t *)(trace);
tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos); 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) { 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)) { if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen, mfDicKeys, mfDicKeysCount)) {
memset(explanation, 0x00, sizeof(explanation)); memset(explanation, 0x00, sizeof(explanation));
annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen, hdr->isResponse); annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen, hdr->isResponse);

View file

@ -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) { int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) {
uint8_t data[APDU_RES_LEN] = {0}; uint8_t data[APDU_RES_LEN] = {0};
size_t datalen = 0; size_t datalen = 0;
uint8_t sfidata[0x11][APDU_RES_LEN];
size_t sfidatalen[0x11] = {0};
uint16_t sw = 0; uint16_t sw = 0;
int res; int res;
const char *PSE_or_PPSE = PSENum == 1 ? "PSE" : "PPSE"; 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 // PSE/PPSE with SFI
struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]) {0x6f, 0xa5, 0x88, 0x00}); struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]) {0x6f, 0xa5, 0x88, 0x00});
if (tsfi) { if (tsfi) {
uint8_t sfidata[0x11][APDU_RES_LEN];
size_t sfidatalen[0x11] = {0};
uint8_t sfin = 0; uint8_t sfin = 0;
tlv_get_uint8(tlvdb_get_tlv(tsfi), &sfin); tlv_get_uint8(tlvdb_get_tlv(tsfi), &sfin);
PrintAndLogEx(INFO, "* PPSE get SFI: 0x%02x.", 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 }; static struct tlv default_ddol_tlv = {.tag = 0x9f49, .len = 3, .value = default_ddol_value };
int trDDA(Iso7816CommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { 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); struct emv_pk *pk = get_ca_pk(tlv);
if (!pk) { if (!pk) {
PrintAndLogEx(ERR, "Error: Key not found, exiting"); PrintAndLogEx(ERR, "Error: Key not found, exiting");
@ -767,6 +763,9 @@ int trDDA(Iso7816CommandChannel channel, bool decodeTLV, struct tlvdb *tlv) {
tlvdb_free(atc_db); tlvdb_free(atc_db);
} else { } 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); struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv);
if (dac_db) { if (dac_db) {
const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL);

View file

@ -258,13 +258,13 @@ static size_t path_size(savePaths_t a) {
if (a == spItemCount) { if (a == spItemCount) {
return 0; return 0;
} }
return strlen( g_session.defaultPaths[a] ); return strlen(g_session.defaultPaths[a]);
} }
char *newfilenamemcopy(const char *preferredName, const char *suffix) { char *newfilenamemcopy(const char *preferredName, const char *suffix) {
if (preferredName == NULL || suffix == NULL) { if (preferredName == NULL || suffix == NULL) {
return NULL; return NULL;
} }
uint16_t p_namelen = strlen(preferredName); uint16_t p_namelen = strlen(preferredName);
if (str_endswith(preferredName, suffix)) if (str_endswith(preferredName, suffix))
@ -328,7 +328,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t
} }
char *fileName = newfilenamemcopy(preferredName, ".eml"); char *fileName = newfilenamemcopy(preferredName, ".eml");
if (fileName == NULL) { if (fileName == NULL) {
return PM3_EMALLOC; return PM3_EMALLOC;
} }
@ -1162,12 +1162,18 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
goto out; 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}; char ctype[100] = {0};
JsonLoadStr(root, "$.FileType", ctype); JsonLoadStr(root, "$.FileType", ctype);
if (!strcmp(ctype, "raw")) { if (!strcmp(ctype, "raw")) {
JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen);
} }
if (!strcmp(ctype, "mfcard")) { if (!strcmp(ctype, "mfcard")) {
@ -1187,7 +1193,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
goto out; goto out;
} }
memcpy(&udata[sptr], block, 16); memcpy(&udata.bytes[sptr], block, 16);
sptr += len; sptr += len;
} }
@ -1206,7 +1212,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); snprintf(blocks, sizeof(blocks), "$.blocks.%d", i);
size_t len = 0; size_t len = 0;
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
if (!len) if (!len)
break; break;
@ -1218,18 +1224,16 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
if (!strcmp(ctype, "mfu")) { if (!strcmp(ctype, "mfu")) {
mfu_dump_t *mem = (mfu_dump_t *)udata; 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.Version", mem->version, sizeof(mem->version), datalen); JsonLoadBufAsHex(root, "$.Card.TBO_1", udata.mfu->tbo1, sizeof(udata.mfu->tbo1), datalen);
JsonLoadBufAsHex(root, "$.Card.TBO_0", mem->tbo, sizeof(mem->tbo), datalen); JsonLoadBufAsHex(root, "$.Card.Signature", udata.mfu->signature, sizeof(udata.mfu->signature), datalen);
JsonLoadBufAsHex(root, "$.Card.TBO_1", mem->tbo1, sizeof(mem->tbo1), datalen); JsonLoadBufAsHex(root, "$.Card.Counter0", &udata.mfu->counter_tearing[0][0], 3, datalen);
JsonLoadBufAsHex(root, "$.Card.Signature", mem->signature, sizeof(mem->signature), datalen); JsonLoadBufAsHex(root, "$.Card.Tearing0", &udata.mfu->counter_tearing[0][3], 1, datalen);
JsonLoadBufAsHex(root, "$.Card.Counter0", &mem->counter_tearing[0][0], 3, datalen); JsonLoadBufAsHex(root, "$.Card.Counter1", &udata.mfu->counter_tearing[1][0], 3, datalen);
JsonLoadBufAsHex(root, "$.Card.Tearing0", &mem->counter_tearing[0][3], 1, datalen); JsonLoadBufAsHex(root, "$.Card.Tearing1", &udata.mfu->counter_tearing[1][3], 1, datalen);
JsonLoadBufAsHex(root, "$.Card.Counter1", &mem->counter_tearing[1][0], 3, datalen); JsonLoadBufAsHex(root, "$.Card.Counter2", &udata.mfu->counter_tearing[2][0], 3, datalen);
JsonLoadBufAsHex(root, "$.Card.Tearing1", &mem->counter_tearing[1][3], 1, datalen); JsonLoadBufAsHex(root, "$.Card.Tearing2", &udata.mfu->counter_tearing[2][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);
*datalen = MFU_DUMP_PREFIX_LENGTH; *datalen = MFU_DUMP_PREFIX_LENGTH;
size_t sptr = 0; 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); snprintf(blocks, sizeof(blocks), "$.blocks.%d", i);
size_t len = 0; 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) if (!len)
break; break;
sptr += len; sptr += len;
mem->pages++; udata.mfu->pages++;
} }
// remove one, since pages indicates a index rather than number of available pages // remove one, since pages indicates a index rather than number of available pages
--mem->pages; --udata.mfu->pages;
*datalen += sptr; *datalen += sptr;
} }
@ -1268,7 +1272,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
size_t len = 0; size_t len = 0;
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
if (!len) if (!len)
break; break;
@ -1290,7 +1294,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
size_t len = 0; size_t len = 0;
JsonLoadBufAsHex(root, blocks, &udata[sptr], 8, &len); JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 8, &len);
if (!len) if (!len)
break; break;
@ -1311,7 +1315,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
size_t len = 0; size_t len = 0;
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
if (!len) if (!len)
break; break;
@ -1332,7 +1336,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i);
size_t len = 0; size_t len = 0;
JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len);
if (!len) if (!len)
break; break;
@ -1342,19 +1346,18 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
} }
if (!strcmp(ctype, "15693")) { if (!strcmp(ctype, "15693")) {
JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen);
} }
if (!strcmp(ctype, "legic")) { if (!strcmp(ctype, "legic")) {
JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen);
} }
if (!strcmp(ctype, "topaz")) { if (!strcmp(ctype, "topaz")) {
topaz_tag_t *mem = (topaz_tag_t *)udata; JsonLoadBufAsHex(root, "$.Card.UID", udata.topaz->uid, sizeof(udata.topaz->uid), datalen);
JsonLoadBufAsHex(root, "$.Card.UID", mem->uid, sizeof(mem->uid), datalen); JsonLoadBufAsHex(root, "$.Card.HR01", udata.topaz->HR01, sizeof(udata.topaz->HR01), datalen);
JsonLoadBufAsHex(root, "$.Card.HR01", mem->HR01, sizeof(mem->HR01), datalen); JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *) & (udata.topaz->size), 2, datalen);
JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *) & (mem->size), 2, datalen);
size_t sptr = 0; size_t sptr = 0;
for (int i = 0; i < (TOPAZ_STATIC_MEMORY / 8); i++) { 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); snprintf(blocks, sizeof(blocks), "$.blocks.%d", i);
size_t len = 0; 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) if (!len)
break; break;

View file

@ -440,7 +440,8 @@ int APDUDecode(uint8_t *data, int len, APDU_t *apdu) {
int APDUEncode(APDU_t *apdu, uint8_t *data, int *len) { int APDUEncode(APDU_t *apdu, uint8_t *data, int *len) {
if (len) if (len)
*len = 0; *len = 0;
if (apdu == NULL)
return 1;
if (apdu->le > 0x10000) if (apdu->le > 0x10000)
return 1; return 1;

View file

@ -99,7 +99,7 @@ typedef struct {
KEY_TYPE key, const char* defaultValue) { \ KEY_TYPE key, const char* defaultValue) { \
struct _ksx6924_enum_ ## KEY_TYPE *r = bsearch( \ struct _ksx6924_enum_ ## KEY_TYPE *r = bsearch( \
&key, KSX6924_ENUM_ ## NAME, \ &key, KSX6924_ENUM_ ## NAME, \
sizeof(KSX6924_ENUM_ ## NAME) / sizeof(KSX6924_ENUM_ ## NAME [0]), \ ARRAYLEN(KSX6924_ENUM_ ## NAME), \
sizeof(KSX6924_ENUM_ ## NAME [0]), \ sizeof(KSX6924_ENUM_ ## NAME [0]), \
_ksx6924_ ## KEY_TYPE ## _enum_compare); \ _ksx6924_ ## KEY_TYPE ## _enum_compare); \
if (r == NULL) { \ if (r == NULL) { \

View file

@ -2301,9 +2301,9 @@ static const char *GetDesfireKeyType(uint8_t keytype) {
} }
const char *GetDesfireAccessRightStr(uint8_t right) { const char *GetDesfireAccessRightStr(uint8_t right) {
static char int_access_str[200];
if (right <= 0x0d) { if (right <= 0x0d) {
static char int_access_str[200];
snprintf(int_access_str, sizeof(int_access_str), "key 0x%02x", right); snprintf(int_access_str, sizeof(int_access_str), "key 0x%02x", right);
return int_access_str; return int_access_str;
} }

View file

@ -1466,7 +1466,7 @@ int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen)
ilen -= MFBLOCK_SIZE; ilen -= MFBLOCK_SIZE;
*olen += MFBLOCK_SIZE; *olen += MFBLOCK_SIZE;
} }
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static const vigik_pk_t vigik_rsa_pk[] = { static const vigik_pk_t vigik_rsa_pk[] = {
@ -1499,24 +1499,24 @@ 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 // iso9796
// Exponent V = 2 // Exponent V = 2
// n = The public modulus n is the product of the secret prime factors p and q. Its length is 1024 bits. // n = The public modulus n is the product of the secret prime factors p and q. Its length is 1024 bits.
if (g_debugMode == DEBUG) { if (g_debugMode == DEBUG) {
PrintAndLogEx(INFO, "Raw"); 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"); 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]; 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"); 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 = 0xBC = Implicitly known
// t = 0xCC = look at byte before to determine hash function // t = 0xCC = look at byte before to determine hash function
@ -1527,7 +1527,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
// signature = h( C || M1 || h(M2) ) // signature = h( C || M1 || h(M2) )
// 1024 - 786 - 160 - 16 -1 // 1024 - 786 - 160 - 16 -1
// salt C // salt C
// message M = 96 bytes, 768 bits // message M = 96 bytes, 768 bits
// sha1 hash H = 20 bytes, 160 bits // sha1 hash H = 20 bytes, 160 bits
// padding = 20 bytes, 96 bits // padding = 20 bytes, 96 bits
@ -1563,18 +1563,18 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
mbedtls_mpi_init(&sqr); mbedtls_mpi_init(&sqr);
mbedtls_mpi_init(&res); 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*)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) // check is sign < (N/2)
mbedtls_mpi n_2; mbedtls_mpi n_2;
mbedtls_mpi_init(&n_2); mbedtls_mpi_init(&n_2);
mbedtls_mpi_copy(&n_2, &N); mbedtls_mpi_copy(&n_2, &N);
mbedtls_mpi_shift_r(&n_2, 1); 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")); PrintAndLogEx(DEBUG, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO"));
mbedtls_mpi_free(&n_2); 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); PrintAndLogEx(DEBUG, "LSB............ " _GREEN_("%u"), lsb);
if (g_debugMode == DEBUG) { if (g_debugMode == DEBUG) {
mbedtls_mpi_write_file( "[=] N.............. ", &N, 16, NULL ); mbedtls_mpi_write_file("[=] N.............. ", &N, 16, NULL);
mbedtls_mpi_write_file( "[=] signature...... ", &s, 16, NULL ); mbedtls_mpi_write_file("[=] signature...... ", &s, 16, NULL);
mbedtls_mpi_write_file( "[=] square mod n... ", &sqr, 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-fs........... ", &res, 16, NULL);
} }
@ -1656,9 +1656,9 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
// xor 0xDC01 // xor 0xDC01
int count_zero = 0; 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] ^= 0xDC;
nfs[x+1] ^= 0x01; nfs[x + 1] ^= 0x01;
if (nfs[x] == 0x00) if (nfs[x] == 0x00)
count_zero++; count_zero++;
@ -1689,10 +1689,10 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
PrintAndLogEx(INFO, "Hash byte... 0x%02X", ts.hash); PrintAndLogEx(INFO, "Hash byte... 0x%02X", ts.hash);
switch(ts.rsa[126]) { switch(ts.rsa[126]) {
case 0x11: case 0x11:
PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1");
break; break;
case 0x22: case 0x22:
PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - RIPEMD"); PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - RIPEMD");
break; break;
case 0x33: case 0x33:
PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1");
@ -1711,7 +1711,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
print_hex_noascii_break(ts.rsa, sizeof(ts.rsa) - 20, 32); print_hex_noascii_break(ts.rsa, sizeof(ts.rsa) - 20, 32);
} }
*/ */
mbedtls_mpi_free(&N); mbedtls_mpi_free(&N);
mbedtls_mpi_free(&s); mbedtls_mpi_free(&s);
mbedtls_mpi_free(&res); mbedtls_mpi_free(&res);
@ -1722,10 +1722,10 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
PrintAndLogEx(INFO, "RSA: 1024bit"); PrintAndLogEx(INFO, "RSA: 1024bit");
if (is_valid == false || i == ARRAYLEN(vigik_rsa_pk)) { if (is_valid == false || i == ARRAYLEN(vigik_rsa_pk)) {
PrintAndLogEx(INFO, "Signature:"); 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")); PrintAndLogEx(SUCCESS, "Signature verification: " _RED_("failed"));
return PM3_ESOFT; return PM3_ESOFT;
} }
@ -1736,41 +1736,39 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature
PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 64); PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 64);
PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 128); PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 128);
PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 192); PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 192);
PrintAndLogEx(INFO, "Signature:"); 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")); PrintAndLogEx(SUCCESS, "Signature verification: " _GREEN_("successful"));
return PM3_SUCCESS; return PM3_SUCCESS;
} }
int vigik_annotate(uint8_t *d) { int vigik_annotate(mfc_vigik_t *d) {
if (d == NULL) if (d == NULL)
return PM3_EINVARG; return PM3_EINVARG;
mfc_vigik_t *foo = (mfc_vigik_t*)d; PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(d->b0, sizeof(d->b0)));
PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(d->mad, sizeof(d->mad)));
PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(foo->b0, sizeof(foo->b0))); PrintAndLogEx(INFO, "Counters............ %u", d->counters);
PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(foo->mad, sizeof(foo->mad))); PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(d->rtf, sizeof(d->rtf)));
PrintAndLogEx(INFO, "Counters............ %u", foo->counters); PrintAndLogEx(INFO, "Service code........ 0x%08x / %u - " _YELLOW_("%s"), d->service_code, d->service_code, vigik_get_service(d->service_code));
PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(foo->rtf, sizeof(foo->rtf))); PrintAndLogEx(INFO, "Info flag........... %u -", d->info_flag); // , sprint_bin(d->info_flag, 1));
PrintAndLogEx(INFO, "Service code........ 0x%08x / %u - " _YELLOW_("%s"), foo->service_code, foo->service_code, vigik_get_service(foo->service_code)); PrintAndLogEx(INFO, "Key version......... %u", d->key_version);
PrintAndLogEx(INFO, "Info flag........... %u -", foo->info_flag); // , sprint_bin(foo->info_flag, 1)); PrintAndLogEx(INFO, "PTR Counter......... %u", d->ptr_counter);
PrintAndLogEx(INFO, "Key version......... %u", foo->key_version); PrintAndLogEx(INFO, "Counter num......... %u", d->counter_num);
PrintAndLogEx(INFO, "PTR Counter......... %u", foo->ptr_counter); PrintAndLogEx(INFO, "Slot access date.... %s", sprint_hex(d->slot_access_date, sizeof(d->slot_access_date)));
PrintAndLogEx(INFO, "Counter num......... %u", foo->counter_num); PrintAndLogEx(INFO, "Slot dst duration... %u", d->slot_dst_duration);
PrintAndLogEx(INFO, "Slot access date.... %s", sprint_hex(foo->slot_access_date, sizeof(foo->slot_access_date))); PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(d->other_slots, sizeof(d->other_slots)));
PrintAndLogEx(INFO, "Slot dst duration... %u", foo->slot_dst_duration); PrintAndLogEx(INFO, "Services counter.... %u", d->services_counter);
PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(foo->other_slots, sizeof(foo->other_slots))); PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(d->loading_date, sizeof(d->loading_date)));
PrintAndLogEx(INFO, "Services counter.... %u", foo->services_counter); PrintAndLogEx(INFO, "Reserved null....... %u", d->reserved_null);
PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(foo->loading_date, sizeof(foo->loading_date)));
PrintAndLogEx(INFO, "Reserved null....... %u", foo->reserved_null);
PrintAndLogEx(INFO, "----------------------------------------------------------------"); PrintAndLogEx(INFO, "----------------------------------------------------------------");
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
vigik_verify(d, 96, foo->rsa_signature, sizeof(foo->rsa_signature)); vigik_verify(d);
PrintAndLogEx(INFO, "----------------------------------------------------------------"); PrintAndLogEx(INFO, "----------------------------------------------------------------");
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -23,6 +23,7 @@
#include "common.h" #include "common.h"
#include "util.h" // FILE_PATH_SIZE #include "util.h" // FILE_PATH_SIZE
#include "protocol_vigik.h"
#define MIFARE_SECTOR_RETRY 10 #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 // 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); 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); 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_verify(mfc_vigik_t *d);
int vigik_annotate(uint8_t *d); int vigik_annotate(mfc_vigik_t *d);
#endif #endif

View file

@ -740,6 +740,7 @@ const static vocabulory_t vocabulory[] = {
{ 1, "piv help" }, { 1, "piv help" },
{ 0, "piv select" }, { 0, "piv select" },
{ 0, "piv getdata" }, { 0, "piv getdata" },
{ 0, "piv authsign" },
{ 0, "piv scan" }, { 0, "piv scan" },
{ 1, "piv list" }, { 1, "piv list" },
{ 1, "smart help" }, { 1, "smart help" },

View file

@ -62,9 +62,9 @@ pthread_mutex_t g_print_lock = PTHREAD_MUTEX_INITIALIZER;
static void fPrintAndLog(FILE *stream, const char *fmt, ...); static void fPrintAndLog(FILE *stream, const char *fmt, ...);
#ifdef _WIN32 #ifdef _WIN32
#define MKDIR_CHK _mkdir(path) #define MKDIR_CHK _mkdir(path)
#else #else
#define MKDIR_CHK mkdir(path, 0700) #define MKDIR_CHK mkdir(path, 0700)
#endif #endif
@ -107,8 +107,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
if ((result != 0) && create_home) { if ((result != 0) && create_home) {
if (MKDIR_CHK) if (MKDIR_CHK) {
{
fprintf(stderr, "Could not create user directory %s\n", path); fprintf(stderr, "Could not create user directory %s\n", path);
free(path); free(path);
return PM3_EFILE; return PM3_EFILE;
@ -140,8 +139,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
if ((result != 0) && create_home) { if ((result != 0) && create_home) {
if (MKDIR_CHK) if (MKDIR_CHK) {
{
fprintf(stderr, "Could not create user directory %s\n", path); fprintf(stderr, "Could not create user directory %s\n", path);
free(path); free(path);
return PM3_EFILE; return PM3_EFILE;
@ -155,7 +153,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
} }
pathlen += strlen(filename); pathlen += strlen(filename);
char *tmp = realloc(path, pathlen *sizeof(char)); char *tmp = realloc(path, pathlen * sizeof(char));
if (tmp == NULL) { if (tmp == NULL) {
//free(path); //free(path);
return PM3_EMALLOC; 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; uint8_t emojified_token_length = 0;
char *current_token = NULL; char *current_token = NULL;
uint8_t current_token_length = 0; uint8_t current_token_length = 0;
char current_char;
char *rdest = (char *)dest; char *rdest = (char *)dest;
char *rsrc = (char *)src; char *rsrc = (char *)src;
uint16_t si = 0; uint16_t si = 0;
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
current_char = rsrc[i]; char current_char = rsrc[i];
if (current_token_length == 0) { if (current_token_length == 0) {
// starting a new token. // starting a new token.

View file

@ -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; size_t max = srclen - plen + 1;

View file

@ -148,7 +148,7 @@ uint64_t bitcount64(uint64_t a);
uint32_t leadingzeros32(uint32_t a); uint32_t leadingzeros32(uint32_t a);
uint64_t leadingzeros64(uint64_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 { struct smartbuf {
char *ptr; char *ptr;

View file

@ -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) { 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; size_t pos;
uint8_t bt;
next_n(true, 5, 0, s); next_n(true, 5, 0, s);
next(true, offset, 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); next(true, len, s);
for (pos = 0; pos < len; pos++) { for (pos = 0; pos < len; pos++) {
// Perform the crypto operation // Perform the crypto operation
bt = in[pos] ^ cm_byte(s); uint8_t bt = in[pos] ^ cm_byte(s);
// Generate output // Generate output
if (out) out[pos] = bt; if (out) out[pos] = bt;

View file

@ -2189,7 +2189,9 @@
"command": "hf emrtd dump", "command": "hf emrtd dump",
"description": "Dump all files on an eMRTD", "description": "Dump all files on an eMRTD",
"notes": [ "notes": [
"hf emrtd dump" "hf emrtd dump",
"hf emrtd dump --dir ../dump",
"hf emrtd dump -n 123456789 -d 19890101 -e 20250401"
], ],
"offline": false, "offline": false,
"options": [ "options": [
@ -2198,9 +2200,9 @@
"-d, --dateofbirth <YYMMDD> date of birth in YYMMDD format", "-d, --dateofbirth <YYMMDD> date of birth in YYMMDD format",
"-e, --expiry <YYMMDD> expiry in YYMMDD format", "-e, --expiry <YYMMDD> expiry in YYMMDD format",
"-m, --mrz <[0-9A-Z<]> 2nd line of MRZ, 44 chars", "-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": { "hf emrtd help": {
"command": "hf emrtd help", "command": "hf emrtd help",
@ -2214,7 +2216,10 @@
"command": "hf emrtd info", "command": "hf emrtd info",
"description": "Display info about an eMRTD", "description": "Display info about an eMRTD",
"notes": [ "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, "offline": true,
"options": [ "options": [
@ -2223,10 +2228,10 @@
"-d, --dateofbirth <YYMMDD> date of birth in YYMMDD format", "-d, --dateofbirth <YYMMDD> date of birth in YYMMDD format",
"-e, --expiry <YYMMDD> expiry in YYMMDD format", "-e, --expiry <YYMMDD> expiry in YYMMDD format",
"-m, --mrz <[0-9A-Z<]> 2nd line of MRZ, 44 chars (passports only)", "-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" "-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": { "hf emrtd list": {
"command": "hf emrtd list", "command": "hf emrtd list",
@ -4799,7 +4804,7 @@
}, },
"hf mf wrbl": { "hf mf wrbl": {
"command": "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": [ "notes": [
"hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f" "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f"
], ],
@ -4809,7 +4814,7 @@
"--blk <dec> block number", "--blk <dec> block number",
"-a input key type is key A (def)", "-a input key type is key A (def)",
"-b input key type is key B", "-b input key type is key B",
"--force enforce block0 writes", "--force override warnings",
"-k, --key <hex> key, 6 hex bytes", "-k, --key <hex> key, 6 hex bytes",
"-d, --data <hex> bytes to write, 16 hex bytes" "-d, --data <hex> bytes to write, 16 hex bytes"
], ],
@ -9378,6 +9383,7 @@
"command": "lf paradox clone", "command": "lf paradox clone",
"description": "clone a paradox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.", "description": "clone a paradox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
"notes": [ "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 -> encode for T55x7 tag",
"lf paradox clone --raw 0f55555695596a6a9999a59a --q5 -> encode for Q5/T5555 tag", "lf paradox clone --raw 0f55555695596a6a9999a59a --q5 -> encode for Q5/T5555 tag",
"lf paradox clone --raw 0f55555695596a6a9999a59a --em -> encode for EM4305/4469" "lf paradox clone --raw 0f55555695596a6a9999a59a --em -> encode for EM4305/4469"
@ -9386,10 +9392,12 @@
"options": [ "options": [
"-h, --help This help", "-h, --help This help",
"-r, --raw <hex> raw hex data. 12 bytes max", "-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", "--q5 optional - specify writing to Q5/T5555 tag",
"--em optional - specify writing to EM4305/4469 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": { "lf paradox demod": {
"command": "lf paradox demod", "command": "lf paradox demod",
@ -10952,6 +10960,27 @@
], ],
"usage": "hf 14b ndefread [-hv] [-f <fn>]" "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": { "piv getdata": {
"command": "piv getdata", "command": "piv getdata",
"description": "Get a data container of a given tag", "description": "Get a data container of a given tag",
@ -11731,8 +11760,8 @@
} }
}, },
"metadata": { "metadata": {
"commands_extracted": 738, "commands_extracted": 739,
"extracted_by": "PM3Help2JSON v1.00", "extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2023-01-06T21:37:50" "extracted_on": "2023-01-15T01:24:39"
} }
} }

View file

@ -1343,6 +1343,7 @@ Check column "offline" for their availability.
|`piv help `|Y |`This help` |`piv help `|Y |`This help`
|`piv select `|N |`Select the PIV applet` |`piv select `|N |`Select the PIV applet`
|`piv getdata `|N |`Gets a container on a PIV card` |`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 scan `|N |`Scan PIV card for known containers`
|`piv list `|Y |`List ISO7816 history` |`piv list `|Y |`List ISO7816 history`

View file

@ -42,4 +42,4 @@ typedef struct vigik_pk_s {
const char *n; const char *n;
} vigik_pk_t; } vigik_pk_t;
#endif #endif

View file

@ -473,7 +473,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
// 65 xx // 65 xx
#define ISO7816_MEMORY_FULL 0x6501 // Memory failure #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 // 67 xx
#define ISO7816_WRONG_LENGTH 0x6700 // Wrong length #define ISO7816_WRONG_LENGTH 0x6700 // Wrong length
@ -506,7 +506,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
#define ISO7816_LC_TLV_CONFLICT 0x6A85 // LC / TLV conlict #define ISO7816_LC_TLV_CONFLICT 0x6A85 // LC / TLV conlict
#define ISO7816_INCORRECT_P1P2 0x6A86 // Incorrect parameters (P1,P2) #define ISO7816_INCORRECT_P1P2 0x6A86 // Incorrect parameters (P1,P2)
#define ISO7816_FILE_EXISTS 0x6A89 // File exists #define ISO7816_FILE_EXISTS 0x6A89 // File exists
#define ISO7816_NOT_IMPLEMENTED 0x6AFF // #define ISO7816_NOT_IMPLEMENTED 0x6AFF //
// 6x 00 // 6x 00
#define ISO7816_WRONG_P1P2 0x6B00 // Incorrect parameters (P1,P2) #define ISO7816_WRONG_P1P2 0x6B00 // Incorrect parameters (P1,P2)

View file

@ -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+=(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_BT=(HF_REBLAY)
STANDALONE_MODES_REQ_SMARTCARD=() 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 # PM3GENERIC 256kb, no flash, need to skip some parts to reduce size

View file

@ -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) { static inline void sm_left_mask(const uint8_t *ks, uint8_t *mask, uint64_t rstate) {
size_t pos; size_t pos;
uint8_t bt;
for (pos = 0; pos < 16; pos++) { for (pos = 0; pos < 16; pos++) {
next_right_fast(0, &rstate); 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); next_right_fast(0, &rstate);
bt |= 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) { static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_t> *pcrstates) {
uint8_t tmp_mask[16]; uint8_t tmp_mask[16];
size_t pos, bits, bit, topbits; size_t pos, bit, topbits;
uint64_t rstate, counter; uint64_t rstate, counter;
map<uint64_t, uint64_t> bincstates; map<uint64_t, uint64_t> bincstates;
map<uint64_t, uint64_t>::iterator it; 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; topbits = 0;
for (counter = 0; counter < 0x2000000; counter++) { for (counter = 0; counter < 0x2000000; counter++) {
// Reset the current bitcount of correct bits // Reset the current bitcount of correct bits
bits = 0; size_t bits = 0;
// Copy the state we are going to test // Copy the state we are going to test
rstate = counter; 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) { 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> bincstates;
map<uint64_t, cs_t>::iterator it; map<uint64_t, cs_t>::iterator it;
uint64_t counter, lstate; uint64_t counter;
size_t pos, bits, bit; size_t pos, bits, bit;
uint8_t correct_bits[16]; uint8_t correct_bits[16];
uint8_t bt; 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; state.invalid = false;
for (counter = 0; counter < 0x800000000ull; counter++) { for (counter = 0; counter < 0x800000000ull; counter++) {
lstate = counter; uint64_t lstate = counter;
for (pos = 0; pos < 16; pos++) { for (pos = 0; pos < 16; pos++) {
lstate = (((lstate) >> 5) | ((uint64_t)left_addition[((lstate) & 0xf801f)] << 30)); lstate = (((lstate) >> 5) | ((uint64_t)left_addition[((lstate) & 0xf801f)] << 30));

View file

@ -165,6 +165,9 @@ void print_cs(const char *text, pcs s) {
} }
static inline uint8_t mod(uint8_t a, uint8_t m) { 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 // Just return the input when this is less or equal than the modular value
if (a < m) return a; if (a < m) return a;
@ -199,18 +202,15 @@ static lookup_entry lookup_right[0x8000];
static uint8_t left_addition[0x100000]; static uint8_t left_addition[0x100000];
static inline void init_lookup_left() { static inline void init_lookup_left() {
uint8_t b3, b6, temp; for (int i = 0; i < 0x400; i++) {
int i, index; uint8_t b6 = i & 0x1f;
uint8_t b3 = (i >> 5) & 0x1f;
for (i = 0; i < 0x400; i++) { int index = (b3 << 15) | b6;
b6 = i & 0x1f;
b3 = (i >> 5) & 0x1f;
index = (b3 << 15) | b6;
// b6 = bit_rotate_l(b6, 5); // b6 = bit_rotate_l(b6, 5);
b6 = BIT_ROL(b6); b6 = BIT_ROL(b6);
temp = mod(b3 + b6, 0x1f); uint8_t temp = mod(b3 + b6, 0x1f);
left_addition[index] = temp; left_addition[index] = temp;
lookup_left[index].addition = temp; lookup_left[index].addition = temp;
lookup_left[index].out = ((temp ^ b3) & 0x0f); lookup_left[index].out = ((temp ^ b3) & 0x0f);
@ -218,15 +218,12 @@ static inline void init_lookup_left() {
} }
static inline void init_lookup_right() { static inline void init_lookup_right() {
uint8_t b16, b18, temp; for (int i = 0; i < 0x400; i++) {
int i, index; uint8_t b18 = i & 0x1f;
uint8_t b16 = (i >> 5) & 0x1f;
int index = (b16 << 10) | b18;
for (i = 0; i < 0x400; i++) { uint8_t temp = mod(b18 + b16, 0x1f);
b18 = i & 0x1f;
b16 = (i >> 5) & 0x1f;
index = (b16 << 10) | b18;
temp = mod(b18 + b16, 0x1f);
lookup_right[index].addition = temp; lookup_right[index].addition = temp;
lookup_right[index].out = ((temp ^ b16) & 0x0f); 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) { static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector<uint64_t> *pcrstates) {
uint8_t tmp_mask[16]; 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> bincstates;
map<uint64_t, uint64_t>::iterator it; map<uint64_t, uint64_t>::iterator it;
uint8_t bt;
topbits = 0;
for (uint64_t counter = 0; counter < 0x2000000; counter++) { for (uint64_t counter = 0; counter < 0x2000000; counter++) {
// Reset the current bitcount of correct bits // Reset the current bitcount of correct bits
bits = 0; size_t bits = 0;
// Copy the state we are going to test // Copy the state we are going to test
uint64_t rstate = counter; uint64_t rstate = counter;
for (pos = 0; pos < 16; pos++) { for (size_t pos = 0; pos < 16; pos++) {
next_right_fast(0, &rstate); 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); next_right_fast(0, &rstate);
bt |= 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 // Save the mask for the left produced bits
tmp_mask[pos] = bt; 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 ;) // When the bit is xored away (=zero), it was the same, so correct ;)
if ((bt & 0x01) == 0) bits++; if ((bt & 0x01) == 0) bits++;
bt >>= 1; 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) { 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> bincstates;
map<uint64_t, cs_t>::iterator it; map<uint64_t, cs_t>::iterator it;
uint64_t counter, lstate; uint64_t counter;
size_t pos, bits; size_t pos, bits;
uint8_t correct_bits[16]; uint8_t correct_bits[16];
uint8_t bt; 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; state.invalid = false;
for (counter = 0; counter < 0x800000000ull; counter++) { for (counter = 0; counter < 0x800000000ull; counter++) {
lstate = counter; uint64_t lstate = counter;
for (pos = 0; pos < 16; pos++) { for (pos = 0; pos < 16; pos++) {

View file

@ -141,6 +141,8 @@ int fnf(uint64_t s) {
// builds the lfsr for the prng (quick calcs for hitag2_nstep()) // builds the lfsr for the prng (quick calcs for hitag2_nstep())
void buildlfsr(Hitag_State *hstate) { void buildlfsr(Hitag_State *hstate) {
if (hstate == NULL)
return;
uint64_t state = hstate->shiftreg; uint64_t state = hstate->shiftreg;
uint64_t temp = state ^ (state >> 1); uint64_t temp = state ^ (state >> 1);
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)

View file

@ -20,11 +20,10 @@ void ComputeCrc14443(int CrcType,
const unsigned char *Data, int Length, const unsigned char *Data, int Length,
unsigned char *TransmitFirst, unsigned char *TransmitFirst,
unsigned char *TransmitSecond) { unsigned char *TransmitSecond) {
unsigned char chBlock;
unsigned short wCrc = CrcType; unsigned short wCrc = CrcType;
do { do {
chBlock = *Data++; unsigned char chBlock = *Data++;
UpdateCrc14443(chBlock, &wCrc); UpdateCrc14443(chBlock, &wCrc);
} while (--Length); } while (--Length);

View file

@ -331,6 +331,8 @@ static bool checkValidCmd(uint32_t decrypted) {
static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) { static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) {
bool ok = false; bool ok = false;
if (cmd == NULL)
return false;
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
if (cmd[0] == cmds[i][0]) { if (cmd[0] == cmds[i][0]) {

View file

@ -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) { static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) {
bool ok = false; bool ok = false;
if (cmd == NULL)
return false;
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
if (cmd[0] == cmds[i][0]) { if (cmd[0] == cmds[i][0]) {

View file

@ -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) { void make_key_posix_rand_r_n(uint32_t seed, uint8_t key[], const size_t keylen) {
uint32_t lseed = seed; uint32_t lseed = seed;
int result;
for (int i = 0; i < keylen; i++) { for (int i = 0; i < keylen; i++) {
lseed *= 1103515245; lseed *= 1103515245;
lseed += 12345; lseed += 12345;
result = (uint16_t)(lseed / 0x10000) % 2048; int result = (uint16_t)(lseed / 0x10000) % 2048;
lseed *= 1103515245; lseed *= 1103515245;
lseed += 12345; lseed += 12345;