mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Merge remote-tracking branch 'upstream/master' into hf_mf_sim
This commit is contained in:
commit
2278d3372e
27 changed files with 281 additions and 175 deletions
10
Makefile
10
Makefile
|
@ -56,7 +56,7 @@ recovery/%: FORCE
|
||||||
$(MAKE) -C recovery $(patsubst recovery/%,%,$@)
|
$(MAKE) -C recovery $(patsubst recovery/%,%,$@)
|
||||||
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
||||||
|
|
||||||
.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nounce2key style FORCE
|
.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nounce2key style checks FORCE
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Multi-OS Makefile"
|
@echo "Multi-OS Makefile"
|
||||||
|
@ -76,6 +76,9 @@ help:
|
||||||
@echo "+ mfkey - Make tools/mfkey"
|
@echo "+ mfkey - Make tools/mfkey"
|
||||||
@echo "+ nounce2key - Make tools/nounce2key"
|
@echo "+ nounce2key - Make tools/nounce2key"
|
||||||
@echo
|
@echo
|
||||||
|
@echo "+ style - Apply some automated source code formatting rules"
|
||||||
|
@echo "+ checks - Detect various encoding issues in source code"
|
||||||
|
@echo
|
||||||
@echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4"
|
@echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4"
|
||||||
|
|
||||||
client: client/all
|
client: client/all
|
||||||
|
@ -138,5 +141,10 @@ style:
|
||||||
--style=google --pad-oper --unpad-paren --pad-header \
|
--style=google --pad-oper --unpad-paren --pad-header \
|
||||||
--align-pointer=name {} \;
|
--align-pointer=name {} \;
|
||||||
|
|
||||||
|
# Detecting weird codepages.
|
||||||
|
checks:
|
||||||
|
find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" -or -name "*.py" -or -name "*.pl" -or -name "Makefile" \) \
|
||||||
|
-exec sh -c "cat {} |recode utf8.. >/dev/null || echo {}" \;
|
||||||
|
|
||||||
# Dummy target to test for GNU make availability
|
# Dummy target to test for GNU make availability
|
||||||
_test:
|
_test:
|
||||||
|
|
|
@ -158,7 +158,7 @@ void RunMod() {
|
||||||
Bytes 5-7 are reserved SAK and ATQA for mifare classic
|
Bytes 5-7 are reserved SAK and ATQA for mifare classic
|
||||||
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
|
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
|
||||||
*/
|
*/
|
||||||
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
|
uint8_t oldBlock0[16] = {0}, newBlock0[16], testBlock0[16] = {0};
|
||||||
// arg0 = Flags, arg1=blockNo
|
// arg0 = Flags, arg1=blockNo
|
||||||
MifareCGetBlock(params, 0, oldBlock0);
|
MifareCGetBlock(params, 0, oldBlock0);
|
||||||
if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
|
if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
|
||||||
|
|
|
@ -1134,8 +1134,6 @@ int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
// hasAuthKey, if we was called with key, skip test.
|
// hasAuthKey, if we was called with key, skip test.
|
||||||
if (!authlim && !hasAuthKey) {
|
if (!authlim && !hasAuthKey) {
|
||||||
PrintAndLogEx(NORMAL, "\n--- Known EV1/NTAG passwords.");
|
PrintAndLogEx(NORMAL, "\n--- Known EV1/NTAG passwords.");
|
||||||
len = 0;
|
|
||||||
|
|
||||||
// test pwd gen A
|
// test pwd gen A
|
||||||
num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key);
|
num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key);
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
|
|
|
@ -1225,9 +1225,8 @@ int CmdEM4x05Write(const char *Cmd) {
|
||||||
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
|
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
|
||||||
|
|
||||||
bool usePwd = false;
|
bool usePwd = false;
|
||||||
uint8_t addr = 50; // default to invalid address
|
uint8_t addr;
|
||||||
uint32_t data = 0; // default to blank data
|
uint32_t data, pwd;
|
||||||
uint32_t pwd = 1; // default to blank password
|
|
||||||
|
|
||||||
addr = param_get8ex(Cmd, 0, 50, 10);
|
addr = param_get8ex(Cmd, 0, 50, 10);
|
||||||
data = param_get32ex(Cmd, 1, 0, 16);
|
data = param_get32ex(Cmd, 1, 0, 16);
|
||||||
|
|
|
@ -459,8 +459,8 @@ int CmdHIDWiegand(const char *Cmd) {
|
||||||
uint8_t *bs = bits;
|
uint8_t *bs = bits;
|
||||||
memset(bs, 0, sizeof(bits));
|
memset(bs, 0, sizeof(bits));
|
||||||
|
|
||||||
uint8_t ctmp = param_getchar(Cmd, 0);
|
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) == 0 || strlen(Cmd) < 3 || ctmp == 'H' || ctmp == 'h') return usage_lf_hid_wiegand();
|
if (strlen(Cmd) < 3 || ctmp == 'h') return usage_lf_hid_wiegand();
|
||||||
|
|
||||||
oem = param_get8(Cmd, 0);
|
oem = param_get8(Cmd, 0);
|
||||||
fc = param_get32ex(Cmd, 1, 0, 10);
|
fc = param_get32ex(Cmd, 1, 0, 10);
|
||||||
|
|
|
@ -1107,7 +1107,7 @@ int CmdSmartBruteforceSFI(const char *Cmd) {
|
||||||
//Validations
|
//Validations
|
||||||
if (errors) return usage_sm_brute();
|
if (errors) return usage_sm_brute();
|
||||||
|
|
||||||
const char *SELECT = "00a40400%02x%s";
|
const char *SELECT = "00a40400%02zu%s";
|
||||||
|
|
||||||
// uint8_t GENERATE_AC[] = {0x80, 0xAE};
|
// uint8_t GENERATE_AC[] = {0x80, 0xAE};
|
||||||
// uint8_t GET_CHALLENGE[] = {0x00, 0x84, 0x00};
|
// uint8_t GET_CHALLENGE[] = {0x00, 0x84, 0x00};
|
||||||
|
|
|
@ -323,7 +323,7 @@ bool asn1_tag_dump(const struct tlv *tlv, FILE *f, int level, bool *candump) {
|
||||||
const struct asn1_tag *tag = asn1_get_tag(tlv);
|
const struct asn1_tag *tag = asn1_get_tag(tlv);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PRINT_INDENT(level);
|
||||||
fprintf(f, "--%2hx[%02zx] '%s':", tlv->tag, tlv->len, tag->name);
|
fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name);
|
||||||
|
|
||||||
switch (tag->type) {
|
switch (tag->type) {
|
||||||
case ASN1_TAG_GENERIC:
|
case ASN1_TAG_GENERIC:
|
||||||
|
|
|
@ -208,7 +208,7 @@ static unsigned char *crypto_pk_polarssl_encrypt(const struct crypto_pk *_cp, co
|
||||||
|
|
||||||
res = mbedtls_rsa_public(&cp->ctx, buf, result);
|
res = mbedtls_rsa_public(&cp->ctx, buf, result);
|
||||||
if (res) {
|
if (res) {
|
||||||
printf("RSA encrypt failed. Error: %x data len: %zd key len: %zd\n", res * -1, len, keylen);
|
printf("RSA encrypt failed. Error: %x data len: %zu key len: %zu\n", res * -1, len, keylen);
|
||||||
free(result);
|
free(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ static unsigned char *crypto_pk_polarssl_decrypt(const struct crypto_pk *_cp, co
|
||||||
|
|
||||||
res = mbedtls_rsa_private(&cp->ctx, NULL, NULL, buf, result); // CHECK???
|
res = mbedtls_rsa_private(&cp->ctx, NULL, NULL, buf, result); // CHECK???
|
||||||
if (res) {
|
if (res) {
|
||||||
printf("RSA decrypt failed. Error: %x data len: %zd key len: %zd\n", res * -1, len, keylen);
|
printf("RSA decrypt failed. Error: %x data len: %zu key len: %zu\n", res * -1, len, keylen);
|
||||||
free(result);
|
free(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -483,7 +483,7 @@ struct emv_pk *emv_pk_get_ca_pk(const unsigned char *rid, unsigned char idx) {
|
||||||
if (!pk)
|
if (!pk)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
printf("Verifying CA PK for %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx %zd bits...",
|
printf("Verifying CA PK for %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx %zu bits...",
|
||||||
pk->rid[0],
|
pk->rid[0],
|
||||||
pk->rid[1],
|
pk->rid[1],
|
||||||
pk->rid[2],
|
pk->rid[2],
|
||||||
|
|
|
@ -84,7 +84,7 @@ void print_mpi(const char *msg, int radix, const mbedtls_mpi *X) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
mbedtls_mpi_write_string(X, radix, Xchar, sizeof(Xchar), &len);
|
mbedtls_mpi_write_string(X, radix, Xchar, sizeof(Xchar), &len);
|
||||||
printf("%s[%ld] %s\n", msg, len, Xchar);
|
printf("%s[%zu] %s\n", msg, len, Xchar);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool emv_rocacheck(const unsigned char *buf, size_t buflen, bool verbose) {
|
bool emv_rocacheck(const unsigned char *buf, size_t buflen, bool verbose) {
|
||||||
|
|
|
@ -490,7 +490,7 @@ static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, F
|
||||||
doltag = emv_get_tag(&doltlv);
|
doltag = emv_get_tag(&doltlv);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PRINT_INDENT(level);
|
||||||
fprintf(f, "\tTag %4hx len %02zx ('%s')\n", doltlv.tag, doltlv.len, doltag->name);
|
fprintf(f, "\tTag %4x len %02zx ('%s')\n", doltlv.tag, doltlv.len, doltag->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *ta
|
||||||
|
|
||||||
static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) {
|
||||||
PRINT_INDENT(level);
|
PRINT_INDENT(level);
|
||||||
fprintf(f, "\tDate: 20%02ld.%ld.%ld\n",
|
fprintf(f, "\tDate: 20%02lu.%lu.%lu\n",
|
||||||
emv_value_numeric(tlv, 0, 2),
|
emv_value_numeric(tlv, 0, 2),
|
||||||
emv_value_numeric(tlv, 2, 4),
|
emv_value_numeric(tlv, 2, 4),
|
||||||
emv_value_numeric(tlv, 4, 6));
|
emv_value_numeric(tlv, 4, 6));
|
||||||
|
@ -667,9 +667,9 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t
|
||||||
Y = emv_get_binary(tlv->value + 4);
|
Y = emv_get_binary(tlv->value + 4);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PRINT_INDENT(level);
|
||||||
fprintf(f, "\tX: %d\n", X);
|
fprintf(f, "\tX: %u\n", X);
|
||||||
PRINT_INDENT(level);
|
PRINT_INDENT(level);
|
||||||
fprintf(f, "\tY: %d\n", Y);
|
fprintf(f, "\tY: %u\n", Y);
|
||||||
|
|
||||||
for (i = 8; i < tlv->len; i += 2) {
|
for (i = 8; i < tlv->len; i += 2) {
|
||||||
const char *method;
|
const char *method;
|
||||||
|
@ -773,7 +773,7 @@ bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) {
|
||||||
const struct emv_tag *tag = emv_get_tag(tlv);
|
const struct emv_tag *tag = emv_get_tag(tlv);
|
||||||
|
|
||||||
PRINT_INDENT(level);
|
PRINT_INDENT(level);
|
||||||
fprintf(f, "--%2hx[%02zx] '%s':", tlv->tag, tlv->len, tag->name);
|
fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name);
|
||||||
|
|
||||||
switch (tag->type) {
|
switch (tag->type) {
|
||||||
case EMV_TAG_GENERIC:
|
case EMV_TAG_GENERIC:
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
|
|
||||||
void cmd_debug(UsbCommand *c) {
|
void cmd_debug(UsbCommand *c) {
|
||||||
// Debug
|
// Debug
|
||||||
printf("UsbCommand length[len=%zd]\n", sizeof(UsbCommand));
|
printf("UsbCommand length[len=%zu]\n", sizeof(UsbCommand));
|
||||||
printf(" cmd[len=%zd]: %016" PRIx64"\n", sizeof(c->cmd), c->cmd);
|
printf(" cmd[len=%zu]: %016" PRIx64"\n", sizeof(c->cmd), c->cmd);
|
||||||
printf(" arg0[len=%zd]: %016" PRIx64"\n", sizeof(c->arg[0]), c->arg[0]);
|
printf(" arg0[len=%zu]: %016" PRIx64"\n", sizeof(c->arg[0]), c->arg[0]);
|
||||||
printf(" arg1[len=%zd]: %016" PRIx64"\n", sizeof(c->arg[1]), c->arg[1]);
|
printf(" arg1[len=%zu]: %016" PRIx64"\n", sizeof(c->arg[1]), c->arg[1]);
|
||||||
printf(" arg2[len=%zd]: %016" PRIx64"\n", sizeof(c->arg[2]), c->arg[2]);
|
printf(" arg2[len=%zu]: %016" PRIx64"\n", sizeof(c->arg[2]), c->arg[2]);
|
||||||
printf(" data[len=%zd]: ", sizeof(c->d.asBytes));
|
printf(" data[len=%zu]: ", sizeof(c->d.asBytes));
|
||||||
|
|
||||||
for (size_t i = 0; i < 16; i++)
|
for (size_t i = 0; i < 16; i++)
|
||||||
printf("%02x", c->d.asBytes[i]);
|
printf("%02x", c->d.asBytes[i]);
|
||||||
|
|
|
@ -98,12 +98,12 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardn
|
||||||
#if __WORDSIZE == 64
|
#if __WORDSIZE == 64
|
||||||
"Input file too big (> %" PRIu64 " bytes). This is probably not a hardnested bitflip state table.\n"
|
"Input file too big (> %" PRIu64 " bytes). This is probably not a hardnested bitflip state table.\n"
|
||||||
#else
|
#else
|
||||||
"Input file too big (> %lu bytes). This is probably not a hardnested bitflip state table.\n"
|
"Input file too big (> %li bytes). This is probably not a hardnested bitflip state table.\n"
|
||||||
#endif
|
#endif
|
||||||
, HARDNESTED_TABLE_SIZE);
|
, HARDNESTED_TABLE_SIZE);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Input files too big (total > %lu bytes). These are probably not PM3 FPGA config files.\n", num_infiles * FPGA_CONFIG_SIZE);
|
fprintf(stderr, "Input files too big (total > %li bytes). These are probably not PM3 FPGA config files.\n", num_infiles * FPGA_CONFIG_SIZE);
|
||||||
}
|
}
|
||||||
for (uint16_t j = 0; j < num_infiles; j++) {
|
for (uint16_t j = 0; j < num_infiles; j++) {
|
||||||
fclose(infile[j]);
|
fclose(infile[j]);
|
||||||
|
|
|
@ -180,7 +180,7 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) {
|
||||||
|
|
||||||
// Load an ELF file and prepare it for flashing
|
// Load an ELF file and prepare it for flashing
|
||||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) {
|
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl) {
|
||||||
FILE *fd = NULL;
|
FILE *fd;
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
Elf32_Phdr *phdrs = NULL;
|
Elf32_Phdr *phdrs = NULL;
|
||||||
int num_phdrs;
|
int num_phdrs;
|
||||||
|
@ -413,7 +413,7 @@ int flash_write(flash_file_t *ctx) {
|
||||||
uint32_t blocks = (length + BLOCK_SIZE - 1) / BLOCK_SIZE;
|
uint32_t blocks = (length + BLOCK_SIZE - 1) / BLOCK_SIZE;
|
||||||
uint32_t end = seg->start + length;
|
uint32_t end = seg->start + length;
|
||||||
|
|
||||||
fprintf(stderr, " 0x%08x..0x%08x [0x%x / %d blocks]",
|
fprintf(stderr, " 0x%08x..0x%08x [0x%x / %u blocks]",
|
||||||
seg->start, end - 1, length, blocks);
|
seg->start, end - 1, length, blocks);
|
||||||
|
|
||||||
int block = 0;
|
int block = 0;
|
||||||
|
@ -427,7 +427,7 @@ int flash_write(flash_file_t *ctx) {
|
||||||
|
|
||||||
if (write_block(baddr, data, block_size) < 0) {
|
if (write_block(baddr, data, block_size) < 0) {
|
||||||
fprintf(stderr, " ERROR\n");
|
fprintf(stderr, " ERROR\n");
|
||||||
fprintf(stderr, "Error writing block %d of %d\n", block, blocks);
|
fprintf(stderr, "Error writing block %d of %u\n", block, blocks);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ usb_dev_handle *findProxmark(int verbose, unsigned int *iface) {
|
||||||
|
|
||||||
usb_dev_handle *OpenProxmark(int verbose) {
|
usb_dev_handle *OpenProxmark(int verbose) {
|
||||||
int ret;
|
int ret;
|
||||||
usb_dev_handle *handle = NULL;
|
usb_dev_handle *handle;
|
||||||
unsigned int iface;
|
unsigned int iface;
|
||||||
|
|
||||||
handle = findProxmark(verbose, &iface);
|
handle = findProxmark(verbose, &iface);
|
||||||
|
|
|
@ -15,8 +15,6 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
uint32_t nt = 0, nr = 0, ar = 0;
|
uint32_t nt = 0, nr = 0, ar = 0;
|
||||||
uint64_t par_list = 0, ks_list = 0;
|
uint64_t par_list = 0, ks_list = 0;
|
||||||
uint64_t *keylist = NULL, *last_keylist = NULL;
|
uint64_t *keylist = NULL, *last_keylist = NULL;
|
||||||
uint32_t keycount = 0;
|
|
||||||
int16_t isOK = 0;
|
|
||||||
|
|
||||||
UsbCommand c = {CMD_READER_MIFARE, {true, blockno, key_type}};
|
UsbCommand c = {CMD_READER_MIFARE, {true, blockno, key_type}};
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||||
isOK = resp.arg[0];
|
int16_t isOK = resp.arg[0];
|
||||||
if (isOK < 0)
|
if (isOK < 0)
|
||||||
return isOK;
|
return isOK;
|
||||||
|
|
||||||
|
@ -69,7 +67,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
}
|
}
|
||||||
c.arg[0] = false;
|
c.arg[0] = false;
|
||||||
|
|
||||||
keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist);
|
uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist);
|
||||||
|
|
||||||
if (keycount == 0) {
|
if (keycount == 0) {
|
||||||
PrintAndLogEx(FAILED, "key not found (lfsr_common_prefix list is null). Nt=%08x", nt);
|
PrintAndLogEx(FAILED, "key not found (lfsr_common_prefix list is null). Nt=%08x", nt);
|
||||||
|
@ -502,14 +500,13 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_
|
||||||
|
|
||||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) {
|
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) {
|
||||||
|
|
||||||
uint8_t isOK = 0;
|
|
||||||
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}};
|
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}};
|
||||||
memcpy(c.d.asBytes, data, 16);
|
memcpy(c.d.asBytes, data, 16);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
isOK = resp.arg[0] & 0xff;
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
if (uid != NULL)
|
if (uid != NULL)
|
||||||
memcpy(uid, resp.d.asBytes, 4);
|
memcpy(uid, resp.d.asBytes, 4);
|
||||||
if (!isOK)
|
if (!isOK)
|
||||||
|
@ -522,13 +519,12 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
|
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
|
||||||
uint8_t isOK = 0;
|
|
||||||
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
|
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
isOK = resp.arg[0] & 0xff;
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
if (!isOK)
|
if (!isOK)
|
||||||
return 2;
|
return 2;
|
||||||
memcpy(data, resp.d.asBytes, 16);
|
memcpy(data, resp.d.asBytes, 16);
|
||||||
|
@ -555,15 +551,8 @@ static uint8_t traceCurKey = 0;
|
||||||
|
|
||||||
struct Crypto1State *traceCrypto1 = NULL;
|
struct Crypto1State *traceCrypto1 = NULL;
|
||||||
struct Crypto1State *revstate = NULL;
|
struct Crypto1State *revstate = NULL;
|
||||||
uint64_t key = 0;
|
|
||||||
uint32_t ks2 = 0;
|
|
||||||
uint32_t ks3 = 0;
|
|
||||||
|
|
||||||
uint32_t cuid = 0; // uid part used for crypto1.
|
uint32_t cuid = 0; // uid part used for crypto1.
|
||||||
uint32_t nt = 0; // tag challenge
|
|
||||||
uint32_t nr_enc = 0; // encrypted reader challenge
|
|
||||||
uint32_t ar_enc = 0; // encrypted reader response
|
|
||||||
uint32_t at_enc = 0; // encrypted tag response
|
|
||||||
|
|
||||||
int isTraceCardEmpty(void) {
|
int isTraceCardEmpty(void) {
|
||||||
return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0));
|
return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0));
|
||||||
|
@ -605,18 +594,14 @@ int loadTraceCard(uint8_t *tuid, uint8_t uidlen) {
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||||
PrintAndLogEx(FAILED, "No trace file found or reading error.");
|
PrintAndLogEx(FAILED, "No trace file found or reading error.");
|
||||||
if (f) {
|
fclose(f);
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(buf) < 32) {
|
if (strlen(buf) < 32) {
|
||||||
if (feof(f)) break;
|
if (feof(f)) break;
|
||||||
PrintAndLogEx(FAILED, "File content error. Block data must include 32 HEX symbols");
|
PrintAndLogEx(FAILED, "File content error. Block data must include 32 HEX symbols");
|
||||||
if (f) {
|
fclose(f);
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 32; i += 2) {
|
for (i = 0; i < 32; i += 2) {
|
||||||
|
@ -628,9 +613,7 @@ int loadTraceCard(uint8_t *tuid, uint8_t uidlen) {
|
||||||
|
|
||||||
blockNum++;
|
blockNum++;
|
||||||
}
|
}
|
||||||
if (f) {
|
fclose(f);
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,14 +660,11 @@ int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted) {
|
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted) {
|
||||||
uint8_t bt = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (len != 1) {
|
if (len != 1) {
|
||||||
for (i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
data[i] = crypto1_byte(pcs, 0x00, isEncrypted) ^ data[i];
|
data[i] = crypto1_byte(pcs, 0x00, isEncrypted) ^ data[i];
|
||||||
} else {
|
} else {
|
||||||
bt = 0;
|
uint8_t bt = 0;
|
||||||
bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 0)) << 0;
|
bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 0)) << 0;
|
||||||
bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 1)) << 1;
|
bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 1)) << 1;
|
||||||
bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 2)) << 2;
|
bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], 2)) << 2;
|
||||||
|
@ -694,7 +674,10 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
|
int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
|
||||||
|
uint32_t nt = 0; // tag challenge
|
||||||
|
uint32_t nr_enc = 0; // encrypted reader challenge
|
||||||
|
uint32_t ar_enc = 0; // encrypted reader response
|
||||||
|
uint32_t at_enc = 0; // encrypted tag response
|
||||||
if (traceState == TRACE_ERROR)
|
if (traceState == TRACE_ERROR)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -813,11 +796,13 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
|
||||||
case TRACE_AUTH_OK:
|
case TRACE_AUTH_OK:
|
||||||
if (len == 4) {
|
if (len == 4) {
|
||||||
traceState = TRACE_IDLE;
|
traceState = TRACE_IDLE;
|
||||||
|
// encrypted tag response
|
||||||
at_enc = bytes_to_num(data, 4);
|
at_enc = bytes_to_num(data, 4);
|
||||||
|
|
||||||
// mfkey64 recover key.
|
// mfkey64 recover key.
|
||||||
ks2 = ar_enc ^ prng_successor(nt, 64);
|
uint64_t key = 0;
|
||||||
ks3 = at_enc ^ prng_successor(nt, 96);
|
uint32_t ks2 = ar_enc ^ prng_successor(nt, 64);
|
||||||
|
uint32_t ks3 = at_enc ^ prng_successor(nt, 96);
|
||||||
revstate = lfsr_recovery64(ks2, ks3);
|
revstate = lfsr_recovery64(ks2, ks3);
|
||||||
lfsr_rollback_word(revstate, 0, 0);
|
lfsr_rollback_word(revstate, 0, 0);
|
||||||
lfsr_rollback_word(revstate, 0, 0);
|
lfsr_rollback_word(revstate, 0, 0);
|
||||||
|
@ -865,8 +850,8 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
|
||||||
int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len) {
|
int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len) {
|
||||||
PrintAndLogEx(SUCCESS, "\nencrypted data: [%s]", sprint_hex(data, len));
|
PrintAndLogEx(SUCCESS, "\nencrypted data: [%s]", sprint_hex(data, len));
|
||||||
struct Crypto1State *s;
|
struct Crypto1State *s;
|
||||||
ks2 = ar_enc ^ prng_successor(nt, 64);
|
uint32_t ks2 = ar_enc ^ prng_successor(nt, 64);
|
||||||
ks3 = at_enc ^ prng_successor(nt, 96);
|
uint32_t ks3 = at_enc ^ prng_successor(nt, 96);
|
||||||
s = lfsr_recovery64(ks2, ks3);
|
s = lfsr_recovery64(ks2, ks3);
|
||||||
mf_crypto1_decrypt(s, data, len, false);
|
mf_crypto1_decrypt(s, data, len, false);
|
||||||
PrintAndLogEx(SUCCESS, "decrypted data: [%s]", sprint_hex(data, len));
|
PrintAndLogEx(SUCCESS, "decrypted data: [%s]", sprint_hex(data, len));
|
||||||
|
|
|
@ -70,7 +70,7 @@ typedef struct {
|
||||||
extern char logHexFileName[FILE_PATH_SIZE];
|
extern char logHexFileName[FILE_PATH_SIZE];
|
||||||
|
|
||||||
extern int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key);
|
extern int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key);
|
||||||
extern int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *ResultKeys, bool calibrate);
|
extern int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKeys, bool calibrate);
|
||||||
extern int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key);
|
extern int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key);
|
||||||
extern int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
|
extern int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
|
||||||
uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory);
|
uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory);
|
||||||
|
|
|
@ -785,8 +785,7 @@ static int l_T55xx_readblock(lua_State *L) {
|
||||||
// arg 2 = use GB
|
// arg 2 = use GB
|
||||||
static int l_T55xx_detect(lua_State *L) {
|
static int l_T55xx_detect(lua_State *L) {
|
||||||
bool useGB = false, usepwd = false, isok;
|
bool useGB = false, usepwd = false, isok;
|
||||||
uint32_t password;
|
uint32_t gb, password = 0;
|
||||||
uint32_t gb;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
//Check number of arguments
|
//Check number of arguments
|
||||||
|
@ -798,7 +797,7 @@ static int l_T55xx_detect(lua_State *L) {
|
||||||
if (size != 1) return returnToLuaWithError(L, "Wrong size of useGB, got %d , expected 1", (int) size);
|
if (size != 1) return returnToLuaWithError(L, "Wrong size of useGB, got %d , expected 1", (int) size);
|
||||||
sscanf(p_gb, "%u", &gb);
|
sscanf(p_gb, "%u", &gb);
|
||||||
useGB = ( gb ) ? true : false;
|
useGB = ( gb ) ? true : false;
|
||||||
printf("p_gb size %u | %c \n", size, useGB ? 'Y':'N');
|
printf("p_gb size %zu | %c \n", size, useGB ? 'Y':'N');
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
const char *p_pwd = luaL_checklstring(L, 1, &size);
|
const char *p_pwd = luaL_checklstring(L, 1, &size);
|
||||||
|
|
|
@ -40,7 +40,9 @@ Arguments:
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||||
local DEBUG = true -- the debug flag
|
local DEBUG = false -- the debug flag
|
||||||
|
local total_tests = 0
|
||||||
|
local total_pass = 0
|
||||||
|
|
||||||
local data_blocks_cmds = {
|
local data_blocks_cmds = {
|
||||||
[1] = '00000000',
|
[1] = '00000000',
|
||||||
|
@ -89,23 +91,135 @@ local function exitMsg(msg)
|
||||||
print(msg)
|
print(msg)
|
||||||
print()
|
print()
|
||||||
end
|
end
|
||||||
|
---
|
||||||
|
-- ask/fsk/psk configuration blocks to test
|
||||||
|
local function GetConfigs( modulation )
|
||||||
|
|
||||||
|
local t = {}
|
||||||
|
|
||||||
|
t['PSK1'] = {
|
||||||
|
[1] = '00001040',
|
||||||
|
[2] = '00041040',
|
||||||
|
[3] = '00081040',
|
||||||
|
[4] = '000c1040',
|
||||||
|
[5] = '00101040',
|
||||||
|
[6] = '00141040',
|
||||||
|
[7] = '00181040',
|
||||||
|
[8] = '001c1040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['PSK2'] = {
|
||||||
|
[1] = '00002040',
|
||||||
|
[2] = '00042040',
|
||||||
|
[3] = '00082040',
|
||||||
|
[4] = '000c2040',
|
||||||
|
[5] = '00102040',
|
||||||
|
[6] = '00142040',
|
||||||
|
[7] = '00182040',
|
||||||
|
[8] = '001c2040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['PSK3'] = {
|
||||||
|
[1] = '00003040',
|
||||||
|
[2] = '00043040',
|
||||||
|
[3] = '00083040',
|
||||||
|
[4] = '000c3040',
|
||||||
|
[5] = '00103040',
|
||||||
|
[6] = '00143040',
|
||||||
|
[7] = '00183040',
|
||||||
|
[8] = '001c3040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['FSK1'] = {
|
||||||
|
[1] = '00004040',
|
||||||
|
[2] = '00004040',
|
||||||
|
[3] = '00044040',
|
||||||
|
[4] = '00084040',
|
||||||
|
[5] = '000c4040',
|
||||||
|
[6] = '00104040',
|
||||||
|
[7] = '00144040',
|
||||||
|
[8] = '00184040',
|
||||||
|
[9] = '001c4040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['FSK2'] = {
|
||||||
|
[1] = '00005040',
|
||||||
|
[2] = '00045040',
|
||||||
|
[3] = '00085040',
|
||||||
|
[4] = '000c5040',
|
||||||
|
[5] = '00105040',
|
||||||
|
[6] = '00145040',
|
||||||
|
[7] = '00185040',
|
||||||
|
[8] = '001c5040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['FSK1A'] = {
|
||||||
|
[1] = '00006040',
|
||||||
|
[2] = '00046040',
|
||||||
|
[3] = '00086040',
|
||||||
|
[4] = '000c6040',
|
||||||
|
[5] = '00106040',
|
||||||
|
[6] = '00146040',
|
||||||
|
[7] = '00186040',
|
||||||
|
[8] = '001c6040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['FSK2A'] = {
|
||||||
|
[1] = '00007040',
|
||||||
|
[2] = '00047040',
|
||||||
|
[3] = '00087040',
|
||||||
|
[4] = '000c7040',
|
||||||
|
[5] = '00107040',
|
||||||
|
[6] = '00147040',
|
||||||
|
[7] = '00187040',
|
||||||
|
[8] = '001c7040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['ASK'] = {
|
||||||
|
[1] = '00008040',
|
||||||
|
[2] = '00048040',
|
||||||
|
[3] = '00088040',
|
||||||
|
[4] = '000c8040',
|
||||||
|
[5] = '00108040',
|
||||||
|
[6] = '00148040',
|
||||||
|
[7] = '00188040',
|
||||||
|
[8] = '001c8040',
|
||||||
|
}
|
||||||
|
|
||||||
|
t['BI'] = {
|
||||||
|
[1] = '00010040',
|
||||||
|
[2] = '00050040',
|
||||||
|
[3] = '00090040',
|
||||||
|
[4] = '000d0040',
|
||||||
|
[5] = '00110040',
|
||||||
|
[6] = '00150040',
|
||||||
|
[7] = '00190040',
|
||||||
|
[8] = '001d0040',
|
||||||
|
}
|
||||||
|
|
||||||
|
return t[modulation:upper()]
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- lf t55xx wipe
|
||||||
local function WipeCard()
|
local function WipeCard()
|
||||||
|
|
||||||
local wipe_cmds = {
|
print('Wiping card')
|
||||||
[1] = 'lf t55xx wipe',
|
core.console('lf t55xx wipe')
|
||||||
[2] = 'lf t55xx detect',
|
|
||||||
}
|
|
||||||
for _ = 1, #wipe_cmds do
|
|
||||||
local c = wipe_cmds[_]
|
|
||||||
dbg(c); core.console(c)
|
|
||||||
end
|
|
||||||
|
|
||||||
local wipe_data_cmd = "lf t55xx write b %s d %s"
|
print('Detecting card')
|
||||||
for _ = 1, #data_blocks_cmds do
|
local res, msg = core.t55xx_detect()
|
||||||
local val = data_blocks_cmds[_]
|
if not res then
|
||||||
local c = string.format(wipe_data_cmd, _, val);
|
oops("Can't detect modulation. Test failed.")
|
||||||
core.console(c)
|
core.console("rem [ERR:DETECT:WIPED] Failed to detect after wipe")
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
local wipe_data_cmd = "lf t55xx write b %s d %s"
|
||||||
|
for _ = 1, #data_blocks_cmds do
|
||||||
|
local val = data_blocks_cmds[_]
|
||||||
|
local c = string.format(wipe_data_cmd, _, val)
|
||||||
|
core.console(c)
|
||||||
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
---
|
---
|
||||||
|
@ -120,26 +234,23 @@ local function CheckReadBlock(block)
|
||||||
return ('%08X'):format(data)
|
return ('%08X'):format(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function test()
|
local function test(modulation)
|
||||||
|
|
||||||
-- PSK1 Modulations to test. (2blocks)
|
local process_block0_cmds = {}
|
||||||
local process_block0_cmds = {
|
|
||||||
[1] = '00001040',
|
|
||||||
[2] = '00041040',
|
|
||||||
[3] = '00081040',
|
|
||||||
[4] = '000c1040',
|
|
||||||
[5] = '00101040',
|
|
||||||
[6] = '00141040',
|
|
||||||
[7] = '00181040',
|
|
||||||
[8] = '001c1040',
|
|
||||||
}
|
|
||||||
|
|
||||||
local y
|
local y
|
||||||
local block = "00"
|
local block = "00"
|
||||||
|
|
||||||
|
local s = ('Start test of %s'):format(modulation)
|
||||||
|
print(s)
|
||||||
|
|
||||||
|
process_block0_cmds = GetConfigs(modulation)
|
||||||
|
|
||||||
|
if process_block0_cmds == nil then return oops('Cant find modulation '..modulation) end
|
||||||
|
|
||||||
for _ = 1, #process_block0_cmds do
|
for _ = 1, #process_block0_cmds do
|
||||||
|
|
||||||
local p_config_cmd = process_block0_cmds[_]
|
local p_config_cmd = process_block0_cmds[_]
|
||||||
|
local errors = 0
|
||||||
core.clearCommandBuffer()
|
core.clearCommandBuffer()
|
||||||
|
|
||||||
-- Write Config block
|
-- Write Config block
|
||||||
|
@ -154,19 +265,30 @@ local function test()
|
||||||
local res, msg = core.t55xx_detect()
|
local res, msg = core.t55xx_detect()
|
||||||
if not res then
|
if not res then
|
||||||
print("can't detect modulation, skip to next config")
|
print("can't detect modulation, skip to next config")
|
||||||
|
core.console(format("rem [ERR:DETECT:%s] Failed to detect modulation", p_config_cmd))
|
||||||
|
core.console(format('rem [SUMMARY:%s] FAIL detection', p_config_cmd))
|
||||||
|
total_tests = total_tests + #data_blocks_cmds
|
||||||
else
|
else
|
||||||
-- Loop block1-2
|
-- Loop block1-2
|
||||||
for _ = 1, #data_blocks_cmds do
|
for _ = 1, #data_blocks_cmds do
|
||||||
|
total_tests = total_tests + 1
|
||||||
local val = data_blocks_cmds[_]
|
local val = data_blocks_cmds[_]
|
||||||
local blockdata, msg = CheckReadBlock(_)
|
local blockdata, msg = CheckReadBlock(_)
|
||||||
if blockdata ~= val then
|
if blockdata:lower() ~= val:lower() then
|
||||||
print( ('Test %s == %s Failed'):format(val, blockdata))
|
print( ('Test %s == %s Failed'):format(val, blockdata))
|
||||||
core.console( format('rem -- block %d value %s failed', _, val))
|
core.console( format('rem [ERR:READ:%s:%d] block %d: read %s instead of %s', p_config_cmd, _, _, blockdata, val))
|
||||||
|
errors = errors+1
|
||||||
else
|
else
|
||||||
print( ('Test %s == %s OK'):format(val, blockdata))
|
print( ('Test %s == %s OK'):format(val, blockdata))
|
||||||
|
total_pass = total_pass + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
if errors >0 then
|
||||||
|
core.console( format('rem [SUMMARY:%s] FAIL %d test%s', p_config_cmd, errors, errors > 1 and "s" or ""))
|
||||||
|
else
|
||||||
|
core.console( format('rem [SUMMARY:%s] PASS all tests', p_config_cmd))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -181,20 +303,25 @@ local function main(args)
|
||||||
end
|
end
|
||||||
|
|
||||||
core.clearCommandBuffer()
|
core.clearCommandBuffer()
|
||||||
|
local res
|
||||||
print('Starting test, wiping card')
|
|
||||||
WipeCard()
|
|
||||||
print('Detecting card')
|
|
||||||
local res, msg = core.t55xx_detect()
|
|
||||||
if res then
|
|
||||||
print('Starting test')
|
|
||||||
test()
|
|
||||||
else
|
|
||||||
print("can't detect modulation. Test failed. Ending.")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- test()
|
-- Adjust this table to set which configurations should be tested
|
||||||
|
-- local test_modes = { 'PSK1', 'PSK2', 'PSK3', 'FSK1', 'FSK2', 'FSK1A', 'FSK2A', 'ASK', 'BI' }
|
||||||
|
local test_modes = { 'ASK', 'PSK1' }
|
||||||
|
|
||||||
|
for _ = 1, #test_modes do
|
||||||
|
res = WipeCard()
|
||||||
|
if res then
|
||||||
|
print (test_modes[_])
|
||||||
|
test(test_modes[_])
|
||||||
|
else
|
||||||
|
exitMsg('Abort!')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
exitMsg('Tests finished')
|
exitMsg('Tests finished')
|
||||||
|
core.console( format('rem [SUMMARY] Success rate: %d/%d tests passed%s', total_pass, total_tests, total_pass < total_tests and ", help me improving that number!" or " \\o/"))
|
||||||
|
|
||||||
end
|
end
|
||||||
main(args)
|
main(args)
|
||||||
|
|
21
client/ui.c
21
client/ui.c
|
@ -21,6 +21,8 @@ bool showDemod = true;
|
||||||
pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static char *logfilename = "proxmark3.log";
|
static char *logfilename = "proxmark3.log";
|
||||||
|
|
||||||
|
float complex cexpf(float complex Z);
|
||||||
|
|
||||||
void PrintAndLogOptions(char *str[][2], size_t size, size_t space) {
|
void PrintAndLogOptions(char *str[][2], size_t size, size_t space) {
|
||||||
char buff[2000] = "Options:\n";
|
char buff[2000] = "Options:\n";
|
||||||
char format[2000] = "";
|
char format[2000] = "";
|
||||||
|
@ -53,7 +55,6 @@ void PrintAndLogEx(logLevel_t level, char *fmt, ...) {
|
||||||
char buffer[MAX_PRINT_BUFFER] = {0};
|
char buffer[MAX_PRINT_BUFFER] = {0};
|
||||||
char buffer2[MAX_PRINT_BUFFER + 20] = {0};
|
char buffer2[MAX_PRINT_BUFFER + 20] = {0};
|
||||||
char *token = NULL;
|
char *token = NULL;
|
||||||
int size = 0;
|
|
||||||
// {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG}
|
// {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG}
|
||||||
static char *prefixes[7] = { "", "[+] ", "[=] ", "[-] ", "[!] ", "[!!] ", "[#] "};
|
static char *prefixes[7] = { "", "[+] ", "[=] ", "[-] ", "[!] ", "[!!] ", "[#] "};
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ void PrintAndLogEx(logLevel_t level, char *fmt, ...) {
|
||||||
|
|
||||||
while (token != NULL) {
|
while (token != NULL) {
|
||||||
|
|
||||||
size = strlen(buffer2);
|
size_t size = strlen(buffer2);
|
||||||
|
|
||||||
if (strlen(token))
|
if (strlen(token))
|
||||||
snprintf(buffer2 + size, sizeof(buffer2) - size, "%s%s\n", prefix, token);
|
snprintf(buffer2 + size, sizeof(buffer2) - size, "%s%s\n", prefix, token);
|
||||||
|
@ -210,13 +211,11 @@ void iceIIR_Butterworth(int *data, const size_t len) {
|
||||||
float b[3] = {0.003621681514929, 0.007243363029857, 0.003621681514929};
|
float b[3] = {0.003621681514929, 0.007243363029857, 0.003621681514929};
|
||||||
float a[3] = {1.000000000000000, -1.822694925196308, 0.837181651256023};
|
float a[3] = {1.000000000000000, -1.822694925196308, 0.837181651256023};
|
||||||
|
|
||||||
float sample = 0; // input sample read from array
|
|
||||||
float complex x_prime = 1.0f; // save sample for estimating frequency
|
|
||||||
float complex x;
|
|
||||||
|
|
||||||
for (i = 0; i < adjustedLen; ++i) {
|
for (i = 0; i < adjustedLen; ++i) {
|
||||||
|
|
||||||
sample = data[i];
|
float sample = data[i]; // input sample read from array
|
||||||
|
float complex x_prime = 1.0f; // save sample for estimating frequency
|
||||||
|
float complex x;
|
||||||
|
|
||||||
// remove DC offset and mix to complex baseband
|
// remove DC offset and mix to complex baseband
|
||||||
x = (sample - 127.5f) * cexpf(_Complex_I * 2 * M_PI * fc * i);
|
x = (sample - 127.5f) * cexpf(_Complex_I * 2 * M_PI * fc * i);
|
||||||
|
@ -251,18 +250,14 @@ void iceSimple_Filter(int *data, const size_t len, uint8_t k) {
|
||||||
#define FILTER_SHIFT 4
|
#define FILTER_SHIFT 4
|
||||||
|
|
||||||
int32_t filter_reg = 0;
|
int32_t filter_reg = 0;
|
||||||
int16_t input, output;
|
|
||||||
int8_t shift = (k <= 8) ? k : FILTER_SHIFT;
|
int8_t shift = (k <= 8) ? k : FILTER_SHIFT;
|
||||||
|
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
|
|
||||||
input = data[i];
|
|
||||||
// Update filter with current sample
|
// Update filter with current sample
|
||||||
filter_reg = filter_reg - (filter_reg >> shift) + input;
|
filter_reg = filter_reg - (filter_reg >> shift) + data[i];
|
||||||
|
|
||||||
// Scale output for unity gain
|
// Scale output for unity gain
|
||||||
output = filter_reg >> shift;
|
data[i] = filter_reg >> shift;
|
||||||
data[i] = output;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
volatile unsigned long c;
|
volatile unsigned long c;
|
||||||
|
|
||||||
// 直接使用循环来延时,一个循环 6 条指令,48M, Delay=1 大概为 200kbps
|
// 直接使用循环来延时,一个循环 6 条指令,48M, Delay=1 大概为 200kbps
|
||||||
// timer.
|
// timer.
|
||||||
// I2CSpinDelayClk(4) = 12.31us
|
// I2CSpinDelayClk(4) = 12.31us
|
||||||
// I2CSpinDelayClk(1) = 3.07us
|
// I2CSpinDelayClk(1) = 3.07us
|
||||||
|
@ -467,8 +467,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
||||||
*data = (uint8_t)tmp & 0xFF;
|
*data = (uint8_t)tmp & 0xFF;
|
||||||
|
|
||||||
len--;
|
len--;
|
||||||
|
// 读取的第一个字节为后续长度
|
||||||
// 读取的第一个字节为后续长度
|
|
||||||
// The first byte in response is the message length
|
// The first byte in response is the message length
|
||||||
if (!readcount && (len > *data)) {
|
if (!readcount && (len > *data)) {
|
||||||
len = *data;
|
len = *data;
|
||||||
|
|
|
@ -445,11 +445,11 @@ int ManchesterEncode(uint8_t *bits, size_t size) {
|
||||||
|
|
||||||
// by marshmellow
|
// by marshmellow
|
||||||
// to detect a wave that has heavily clipped (clean) samples
|
// to detect a wave that has heavily clipped (clean) samples
|
||||||
// loop 512 samples, if 250 of them is deemed maxed out, we assume the wave is clipped.
|
// loop 1024 samples, if 250 of them is deemed maxed out, we assume the wave is clipped.
|
||||||
bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low) {
|
bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low) {
|
||||||
bool allArePeaks = true;
|
bool allArePeaks = true;
|
||||||
uint16_t cntPeaks = 0;
|
uint16_t cntPeaks = 0;
|
||||||
size_t loopEnd = 512 + 160;
|
size_t loopEnd = 1024 + 160;
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (loopEnd > size) loopEnd = size;
|
if (loopEnd > size) loopEnd = size;
|
||||||
|
@ -463,7 +463,8 @@ bool DetectCleanAskWave(uint8_t *dest, size_t size, uint8_t high, uint8_t low) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allArePeaks) {
|
if (!allArePeaks) {
|
||||||
if (cntPeaks > 250) return true;
|
if (g_debugMode == 2) prnt("DEBUG DetectCleanAskWave: peaks (200) %u", cntPeaks);
|
||||||
|
if (cntPeaks > 200) return true;
|
||||||
}
|
}
|
||||||
return allArePeaks;
|
return allArePeaks;
|
||||||
}
|
}
|
||||||
|
@ -520,12 +521,12 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
||||||
|
|
||||||
int foo = getClosestClock(minClk);
|
int foo = getClosestClock(minClk);
|
||||||
if (foo > 0) {
|
if (foo > 0) {
|
||||||
for (uint8_t i = 0; i < 10; i++) {
|
for (uint8_t j = 0; j < 10; j++) {
|
||||||
if (tmpclk[i][0] == foo) {
|
if (tmpclk[j][0] == foo) {
|
||||||
tmpclk[i][1]++;
|
tmpclk[j][1]++;
|
||||||
|
|
||||||
if (tmpclk[i][2] == 0) {
|
if (tmpclk[j][2] == 0) {
|
||||||
tmpclk[i][2] = shortestWaveIdx;
|
tmpclk[j][2] = shortestWaveIdx;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -535,18 +536,18 @@ int DetectStrongAskClock(uint8_t *dest, size_t size, int high, int low, int *clo
|
||||||
|
|
||||||
// find the clock with most hits and it the first index it was encountered.
|
// find the clock with most hits and it the first index it was encountered.
|
||||||
int max = 0;
|
int max = 0;
|
||||||
for (uint8_t i = 0; i < 10; i++) {
|
for (uint8_t j = 0; j < 10; j++) {
|
||||||
if (g_debugMode == 2) {
|
if (g_debugMode == 2) {
|
||||||
prnt("DEBUG, ASK, clocks %u | hits %u | idx %u"
|
prnt("DEBUG, ASK, clocks %u | hits %u | idx %u"
|
||||||
, tmpclk[i][0]
|
, tmpclk[j][0]
|
||||||
, tmpclk[i][1]
|
, tmpclk[j][1]
|
||||||
, tmpclk[i][2]
|
, tmpclk[j][2]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (max < tmpclk[i][1]) {
|
if (max < tmpclk[j][1]) {
|
||||||
*clock = tmpclk[i][0];
|
*clock = tmpclk[j][0];
|
||||||
shortestWaveIdx = tmpclk[i][2];
|
shortestWaveIdx = tmpclk[j][2];
|
||||||
max = tmpclk[i][1];
|
max = tmpclk[j][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ extern size_t removeParity(uint8_t *bits, size_t startIdx, uint8_t pLen, uint8
|
||||||
|
|
||||||
//tag specific
|
//tag specific
|
||||||
extern int detectAWID(uint8_t *dest, size_t *size, int *waveStartIdx);
|
extern int detectAWID(uint8_t *dest, size_t *size, int *waveStartIdx);
|
||||||
extern int Em410xDecode(uint8_t *dest, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
|
extern int Em410xDecode(uint8_t *bits, size_t *size, size_t *start_idx, uint32_t *hi, uint64_t *lo);
|
||||||
extern int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo, int *waveStartIdx);
|
extern int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo, int *waveStartIdx);
|
||||||
extern int detectIdteck(uint8_t *dest, size_t *size);
|
extern int detectIdteck(uint8_t *dest, size_t *size);
|
||||||
extern int detectIOProx(uint8_t *dest, size_t *size, int *waveStartIdx);
|
extern int detectIOProx(uint8_t *dest, size_t *size, int *waveStartIdx);
|
||||||
|
|
|
@ -72,20 +72,20 @@ size_t removeParity(uint8_t *bits, size_t startIdx, uint8_t pLen, uint8_t pType,
|
||||||
// Make sure *dest is long enough to store original sourceLen + #_of_parities_to_be_added
|
// Make sure *dest is long enough to store original sourceLen + #_of_parities_to_be_added
|
||||||
/*
|
/*
|
||||||
* @brief addParity
|
* @brief addParity
|
||||||
* @param bits pointer to the source bitstream of binary values
|
* @param src pointer to the source bitstream of binary values
|
||||||
* @param dest pointer to the destination where parities together with bits are added.
|
* @param dest pointer to the destination where parities together with bits are added.
|
||||||
* @param sourceLen number of
|
* @param sourceLen number of
|
||||||
* @param pLen length bits to be checked
|
* @param pLen length bits to be checked
|
||||||
* @param pType EVEN|ODD|2 (always 1's)|3 (always 0's)
|
* @param pType EVEN|ODD|2 (always 1's)|3 (always 0's)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
size_t addParity(uint8_t *bits, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType) {
|
size_t addParity(uint8_t *src, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType) {
|
||||||
uint32_t parityWd = 0;
|
uint32_t parityWd = 0;
|
||||||
size_t j = 0, bitCnt = 0;
|
size_t j = 0, bitCnt = 0;
|
||||||
for (int word = 0; word < sourceLen; word += pLen - 1) {
|
for (int word = 0; word < sourceLen; word += pLen - 1) {
|
||||||
for (int bit = 0; bit < pLen - 1; ++bit) {
|
for (int bit = 0; bit < pLen - 1; ++bit) {
|
||||||
parityWd = (parityWd << 1) | bits[word + bit];
|
parityWd = (parityWd << 1) | src[word + bit];
|
||||||
dest[j++] = (bits[word + bit]);
|
dest[j++] = (src[word + bit]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if parity fails then return 0
|
// if parity fails then return 0
|
||||||
|
|
|
@ -77,10 +77,9 @@ static void bucket_sort_intersect(uint32_t *const estart, uint32_t *const estop,
|
||||||
|
|
||||||
// write back intersecting buckets as sorted list.
|
// write back intersecting buckets as sorted list.
|
||||||
// fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.
|
// fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.
|
||||||
uint32_t nonempty_bucket;
|
|
||||||
for (uint32_t i = 0; i < 2; i++) {
|
for (uint32_t i = 0; i < 2; i++) {
|
||||||
p1 = start[i];
|
p1 = start[i];
|
||||||
nonempty_bucket = 0;
|
uint32_t nonempty_bucket = 0;
|
||||||
for (uint32_t j = 0x00; j <= 0xff; j++) {
|
for (uint32_t j = 0x00; j <= 0xff; j++) {
|
||||||
if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only
|
if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only
|
||||||
bucket_info->bucket_info[i][nonempty_bucket].head = p1;
|
bucket_info->bucket_info[i][nonempty_bucket].head = p1;
|
||||||
|
@ -146,13 +145,12 @@ static struct Crypto1State *
|
||||||
recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
|
recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
|
||||||
uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
|
uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
|
||||||
struct Crypto1State *sl, uint32_t in, bucket_array_t bucket) {
|
struct Crypto1State *sl, uint32_t in, bucket_array_t bucket) {
|
||||||
uint32_t *o, *e;
|
|
||||||
bucket_info_t bucket_info;
|
bucket_info_t bucket_info;
|
||||||
|
|
||||||
if (rem == -1) {
|
if (rem == -1) {
|
||||||
for (e = e_head; e <= e_tail; ++e) {
|
for (uint32_t *e = e_head; e <= e_tail; ++e) {
|
||||||
*e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);
|
*e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ (!!(in & 4));
|
||||||
for (o = o_head; o <= o_tail; ++o, ++sl) {
|
for (uint32_t *o = o_head; o <= o_tail; ++o, ++sl) {
|
||||||
sl->even = *o;
|
sl->even = *o;
|
||||||
sl->odd = *e ^ parity(*o & LF_POLY_ODD);
|
sl->odd = *e ^ parity(*o & LF_POLY_ODD);
|
||||||
sl[1].odd = sl[1].even = 0;
|
sl[1].odd = sl[1].even = 0;
|
||||||
|
@ -193,12 +191,11 @@ struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in) {
|
||||||
struct Crypto1State *statelist;
|
struct Crypto1State *statelist;
|
||||||
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
|
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
|
||||||
uint32_t *even_head = 0, *even_tail = 0, eks = 0;
|
uint32_t *even_head = 0, *even_tail = 0, eks = 0;
|
||||||
int i;
|
|
||||||
|
|
||||||
// split the keystream into an odd and even part
|
// split the keystream into an odd and even part
|
||||||
for (i = 31; i >= 0; i -= 2)
|
for (int i = 31; i >= 0; i -= 2)
|
||||||
oks = oks << 1 | BEBIT(ks2, i);
|
oks = oks << 1 | BEBIT(ks2, i);
|
||||||
for (i = 30; i >= 0; i -= 2)
|
for (int i = 30; i >= 0; i -= 2)
|
||||||
eks = eks << 1 | BEBIT(ks2, i);
|
eks = eks << 1 | BEBIT(ks2, i);
|
||||||
|
|
||||||
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
|
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
|
||||||
|
@ -225,7 +222,7 @@ struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream
|
// initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream
|
||||||
for (i = 1 << 20; i >= 0; --i) {
|
for (int i = 1 << 20; i >= 0; --i) {
|
||||||
if (filter(i) == (oks & 1))
|
if (filter(i) == (oks & 1))
|
||||||
*++odd_tail = i;
|
*++odd_tail = i;
|
||||||
if (filter(i) == (eks & 1))
|
if (filter(i) == (eks & 1))
|
||||||
|
@ -233,7 +230,7 @@ struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):
|
// extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):
|
||||||
for (i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);
|
extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);
|
||||||
extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
|
extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +359,7 @@ uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) {
|
||||||
out ^= LF_POLY_EVEN & (s->even >>= 1);
|
out ^= LF_POLY_EVEN & (s->even >>= 1);
|
||||||
out ^= LF_POLY_ODD & s->odd;
|
out ^= LF_POLY_ODD & s->odd;
|
||||||
out ^= !!in;
|
out ^= !!in;
|
||||||
out ^= (ret = filter(s->odd)) & !!fb;
|
out ^= (ret = filter(s->odd)) & (!!fb);
|
||||||
|
|
||||||
s->even |= parity(out) << 23;
|
s->even |= parity(out) << 23;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -498,21 +495,21 @@ uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) {
|
||||||
* helper function which eliminates possible secret states using parity bits
|
* helper function which eliminates possible secret states using parity bits
|
||||||
*/
|
*/
|
||||||
static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State *sl) {
|
static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State *sl) {
|
||||||
uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;
|
uint32_t good = 1;
|
||||||
|
|
||||||
for (c = 0; good && c < 8; ++c) {
|
for (uint32_t c = 0; good && c < 8; ++c) {
|
||||||
sl->odd = odd ^ fastfwd[1][c];
|
sl->odd = odd ^ fastfwd[1][c];
|
||||||
sl->even = even ^ fastfwd[0][c];
|
sl->even = even ^ fastfwd[0][c];
|
||||||
|
|
||||||
lfsr_rollback_bit(sl, 0, 0);
|
lfsr_rollback_bit(sl, 0, 0);
|
||||||
lfsr_rollback_bit(sl, 0, 0);
|
lfsr_rollback_bit(sl, 0, 0);
|
||||||
|
|
||||||
ks3 = lfsr_rollback_bit(sl, 0, 0);
|
uint32_t ks3 = lfsr_rollback_bit(sl, 0, 0);
|
||||||
ks2 = lfsr_rollback_word(sl, 0, 0);
|
uint32_t ks2 = lfsr_rollback_word(sl, 0, 0);
|
||||||
ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
|
uint32_t ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
|
||||||
|
|
||||||
nr = ks1 ^ (prefix | c << 5);
|
uint32_t nr = ks1 ^ (prefix | c << 5);
|
||||||
rr = ks2 ^ rresp;
|
uint32_t rr = ks2 ^ rresp;
|
||||||
|
|
||||||
good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
|
good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
|
||||||
good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
|
good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
|
||||||
|
|
|
@ -49,7 +49,7 @@ uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) {
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
uint8_t ret = filter(s->odd);
|
uint8_t ret = filter(s->odd);
|
||||||
|
|
||||||
feedin = ret & !!is_encrypted;
|
feedin = ret & (!!is_encrypted);
|
||||||
feedin ^= !!in;
|
feedin ^= !!in;
|
||||||
feedin ^= LF_POLY_ODD & s->odd;
|
feedin ^= LF_POLY_ODD & s->odd;
|
||||||
feedin ^= LF_POLY_EVEN & s->even;
|
feedin ^= LF_POLY_EVEN & s->even;
|
||||||
|
|
|
@ -206,7 +206,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("[=] UART Setting serial baudrate %i\n", speed);
|
printf("[=] UART Setting serial baudrate %u\n", speed);
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +231,6 @@ void uart_close(const serial_port sp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_receive(const serial_port sp, uint8_t *pbtRx, size_t pszMaxRxLen, size_t *pszRxLen) {
|
bool uart_receive(const serial_port sp, uint8_t *pbtRx, size_t pszMaxRxLen, size_t *pszRxLen) {
|
||||||
int res;
|
|
||||||
int byteCount;
|
int byteCount;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -244,7 +243,7 @@ bool uart_receive(const serial_port sp, uint8_t *pbtRx, size_t pszMaxRxLen, size
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(((serial_port_unix *)sp)->fd, &rfds);
|
FD_SET(((serial_port_unix *)sp)->fd, &rfds);
|
||||||
tv = timeout;
|
tv = timeout;
|
||||||
res = select(((serial_port_unix *)sp)->fd + 1, &rfds, NULL, NULL, &tv);
|
int res = select(((serial_port_unix *)sp)->fd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
|
||||||
// Read error
|
// Read error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -290,7 +289,6 @@ bool uart_receive(const serial_port sp, uint8_t *pbtRx, size_t pszMaxRxLen, size
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_send(const serial_port sp, const uint8_t *pbtTx, const size_t len) {
|
bool uart_send(const serial_port sp, const uint8_t *pbtTx, const size_t len) {
|
||||||
int32_t res;
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -300,7 +298,7 @@ bool uart_send(const serial_port sp, const uint8_t *pbtTx, const size_t len) {
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(((serial_port_unix *)sp)->fd, &rfds);
|
FD_SET(((serial_port_unix *)sp)->fd, &rfds);
|
||||||
tv = timeout;
|
tv = timeout;
|
||||||
res = select(((serial_port_unix *)sp)->fd + 1, NULL, &rfds, NULL, &tv);
|
int res = select(((serial_port_unix *)sp)->fd + 1, NULL, &rfds, NULL, &tv);
|
||||||
|
|
||||||
// Write error
|
// Write error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue