chg: 'lf nexwatch demod' - correct parity calc

This commit is contained in:
iceman1001 2020-05-11 01:13:58 +02:00
commit 280b7d9c46

View file

@ -53,6 +53,16 @@ static int usage_lf_nexwatch_sim(void) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static inline uint32_t bitcount(uint32_t a) {
#if defined __GNUC__
return __builtin_popcountl(a);
#else
a = a - ((a >> 1) & 0x55555555);
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24;
#endif
}
int demodNexWatch(void) { int demodNexWatch(void) {
if (PSKDemod("", false) != PM3_SUCCESS) { if (PSKDemod("", false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal"); PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal");
@ -106,13 +116,14 @@ int demodNexWatch(void) {
32bit UID: 00100100011001000011111100010010 32bit UID: 00100100011001000011111100010010
bits numbered from left (MSB): bits numbered from left (MSB):
1234567890 1234567890 1234567890 12 1234 5678 9012 34567 8901234567890 12
0010 0100 0110 0100 00111111000100 10
descramble: descramble:
b1 b5 b9 b13 b17 b21 b25 b29 b2 b6 b10 b14 b18 b22 b26 b30 b3 b7 b11 b15 b19 b23 b27 b31 b4 b8 b12 b16 b20 b24 b28 b32 b1 b5 b9 b13 b17 b21 b25 b29 b2 b6 b10 b14 b18 b22 b26 b30 b3 b7 b11 b15 b19 b23 b27 b31 b4 b8 b12 b16 b20 b24 b28 b32
00000100011101001010110100001100 = 74755340 gives:
0000 0100 0111 0100 1010 1101 0000 1110 = 74755342
*/ */
// Since the description is not zero indexed we adjust. // Since the description is not zero indexed we adjust.
@ -167,18 +178,24 @@ int demodNexWatch(void) {
d_id |= DemodBuffer[DOFFSET + 24] << 2; d_id |= DemodBuffer[DOFFSET + 24] << 2;
d_id |= DemodBuffer[DOFFSET + 28] << 1; d_id |= DemodBuffer[DOFFSET + 28] << 1;
d_id |= DemodBuffer[DOFFSET + 32]; d_id |= DemodBuffer[DOFFSET + 32];
uint8_t mode = bytebits_to_byte(DemodBuffer + 72, 4);
// parity check // parity check
// from 8 preamble, 32 zeros, 32 id, 4 mode, comes EOEO parity. // from 32 hex id, 4 mode, descramble par (1234) -> (4231)
/* uint8_t xor_par = 0;
uint8_t even; for (uint8_t i = 40; i < 76; i +=4) {
for (uint8_t p=0; p < 76; p++) { xor_par ^= bytebits_to_byte(DemodBuffer + i, 4);
even = (DemodBuffer[p] == 1);
} }
uint8_t calc_parity = (!even << 3 | even << 2 | !even << 1 | even); uint8_t calc_parity ;
calc_parity = (((xor_par >> 3 ) & 1) );
calc_parity |= (((xor_par >> 1 ) & 1) << 1);
calc_parity |= (((xor_par >> 2 ) & 1) << 2);
calc_parity |= ((xor_par & 1) << 3);
uint8_t parity = bytebits_to_byte(DemodBuffer + 76, 4); uint8_t parity = bytebits_to_byte(DemodBuffer + 76, 4);
*/
/* /*
Checksum::: Checksum:::
1. Subtract every byte from ID field using an unsigned, one byte register: 1. Subtract every byte from ID field using an unsigned, one byte register:
@ -207,9 +224,7 @@ int demodNexWatch(void) {
PrintAndLogEx(NORMAL, "Sum: 0x%02x", calc); PrintAndLogEx(NORMAL, "Sum: 0x%02x", calc);
uint8_t revpar = (even << 3 | !even << 2 | even << 1 | !even); uint8_t a[] = {0xbe, 0xbc, 0x88, 0x86 };
uint8_t a[] = {0xbe, 0xbc, 0x88, 0x86 };
for (uint8_t c=0; c < ARRAYLEN(a); c++) { for (uint8_t c=0; c < ARRAYLEN(a); c++) {
uint8_t b = calc; uint8_t b = calc;
b -= a[c]; b -= a[c];
@ -227,19 +242,18 @@ int demodNexWatch(void) {
*/ */
// uint8_t chk = bytebits_to_byte(DemodBuffer + 80, 8); // uint8_t chk = bytebits_to_byte(DemodBuffer + 80, 8);
uint8_t mode = bytebits_to_byte(DemodBuffer + 72, 4);
// output // output
PrintAndLogEx(SUCCESS, " NexWatch raw id : " _YELLOW_("0x%"PRIx32) , rawid); PrintAndLogEx(SUCCESS, " NexWatch raw id : " _YELLOW_("0x%"PRIx32) , rawid);
PrintAndLogEx(SUCCESS, " descrambled id : " _YELLOW_("%"PRIu32) " " _YELLOW_("0x%"PRIx32), d_id, d_id); PrintAndLogEx(SUCCESS, " 88bit id : " _YELLOW_("%"PRIu32) " " _YELLOW_("0x%"PRIx32), d_id, d_id);
PrintAndLogEx(SUCCESS, " mode : %x", mode); PrintAndLogEx(SUCCESS, " mode : %x", mode);
// PrintAndLogEx(SUCCESS, " parity : %s [%X == %X]", (parity == calc_parity) ? _GREEN_("ok") : _RED_("fail"), parity, calc_parity); PrintAndLogEx(SUCCESS, " parity : %s [%X == %X]", (parity == calc_parity) ? _GREEN_("ok") : _RED_("fail"), parity, calc_parity);
// PrintAndLogEx(NORMAL, " checksum : %02x == %02x", calc, chk); // PrintAndLogEx(NORMAL, " checksum : %02x == %02x", calc, chk);
// bits to hex (output used for SIM/CLONE cmd) // bits to hex (output used for SIM/CLONE cmd)
CmdPrintDemodBuff("x"); CmdPrintDemodBuff("x");
// PrintAndLogEx(INFO, "Raw: %s", sprint_hex_inrow(DemodBuffer, size)); // PrintAndLogEx(INFO, "Raw: %s", sprint_hex_inrow(DemodBuffer, size));
//binarraytohex(char *target, const size_t targetlen, (char *)DemodBuffer, size);
return PM3_SUCCESS; return PM3_SUCCESS;
} }