// decode externally sniffed PWM BOOL q5_decode_pwm(unsigned long pulses[], unsigned long gaps[], unsigned int count) { unsigned int i, j; BOOL decoded= FALSE; BYTE out[65]; // max response from hitag2 is 64 bits j= 0; while(j < count) { i= generic_decode_pwm(out, &pulses[j], 10, 512, &gaps[j], 20, 500, count - j); if(i) { decoded= TRUE; UserMessage("\r\n%s", out); j += i; } else break; } UserMessage("%s", "\r\n"); return decoded; }
// decode externally sniffed PWM BOOL hitag2_decode_pwm(unsigned long pulses[], unsigned long gaps[], unsigned int count) { unsigned int i, j; BOOL decoded= FALSE, encrypted= FALSE, auth= FALSE; BYTE out[65], tmp[33], x; // max response from hitag2 is 64 bits j= 0; while(j < count) { i= generic_decode_pwm(out, &pulses[j], 10, 256, &gaps[j], 10, 80, count - j); if(i) { // there are only 4 message sizes, so decode accordingly switch(strlen(out)) { // start_auth case 5: auth= FALSE; if(memcmp(out, HITAG2_START_AUTH, 5) == 0) { UserMessage("\r\n%s, START_AUTH", out); auth= TRUE; } else UserMessage("\r\n%s, ?INVALID?", out); encrypted= FALSE; break; // read/write/halt case 10: auth= FALSE; if(encrypted) { UserMessage("\r\n%s, CMD_ENCRYPTED", out); break; } if(memcmp(out, HITAG2_HALT, 2) == 0) { UserMessage("\r\n%s, HALT", out); break; } if(memcmp(out, HITAG2_READ_PAGE, 2) == 0) UserMessage("\r\n%s, READ_PAGE:", out); if(memcmp(out, HITAG2_READ_PAGE_INVERTED, 2) == 0) UserMessage("\r\n%s, READ_PAGE_INVERTED:", out); if(memcmp(out, HITAG2_WRITE_PAGE, 2) == 0) UserMessage("\r\n%s, WRITE_PAGE:", out); binstringtobyte(&x, &out[2], 3); UserMessageNum("%d", x); break; // password or data case 32: if(auth) UserMessage("\r\n%s, PWD:", out); else UserMessage("\r\n%s, DATA:", out); binstringtohex(out, out); UserMessage("%s", out); auth= FALSE; break; // crypto handshake case 64: UserMessage("\r\n%s, PRN:", out); memcpy(tmp, out, 32); tmp[32]= '\0'; binstringtohex(out, tmp); UserMessage("%s: SECRET:", out); binstringtohex(out, out + 32); UserMessage("%s", out); encrypted= TRUE; auth= FALSE; break; default: UserMessage("\r\n%s,?INVALID?", out); } decoded= TRUE; j += i; } else break; } UserMessage("%s", "\r\n"); return decoded; }
// decode externally sniffed PWM BOOL hitag1_decode_pwm(unsigned long pulses[], unsigned long gaps[], unsigned int count) { unsigned int i, j; BOOL decoded= FALSE; BYTE out[46], tmp[9], x; // max command from hitag1 is 5 bit command plus 32 bits + 8 bit crc == 45 j= 0; while(j < count) { i= generic_decode_pwm(out, &pulses[j], 10, 256, &gaps[j], 10, 80, count - j); if(i) { // there are only 5 message sizes, so decode accordingly switch(strlen(out)) { // halt case 4: if(memcmp(out, HITAG1_HALT, 4) == 0) UserMessage("\r\n%s, HALT", out); else UserMessage("\r\n%s, ?INVALID?", out); break; // get UID case 5: if(memcmp(out, HITAG1_SET_CC, 5) == 0) UserMessage("\r\n%s, SET_CC", out); else UserMessage("\r\n%s, ?INVALID?", out); break; // read/write case 20: if(memcmp(out, HITAG1_RDPPAGE, 4) == 0) UserMessage("\r\n%s, READ_PLAINTEXT_PAGE:", out); else if(memcmp(out, HITAG1_WRPPAGE, 4) == 0) UserMessage("\r\n%s, WRITE_PLAINTEXT_PAGE:", out); else { UserMessage("\r\n%s, ?INVALID?", out); break; } out[20]= '\0'; binstringtohex(tmp, out + 4); // page UserMessage("%.2s:", tmp); // crc UserMessage("%s", tmp + 2); break; // data case 40: UserMessage("\r\n%s, DATA:", out); out[40]= '\0'; binstringtohex(tmp, out); // DATA UserMessage("%.8s:", tmp); // CRC UserMessage("%s", tmp + 8); break; // select case 45: if(memcmp(out, HITAG1_SELECT, 5) == 0) { UserMessage("\r\n%s, SELECT:", out); out[45]= '\0'; binstringtohex(tmp, out + 5); // UID UserMessage("%.8s:", tmp); // CRC UserMessage("%s", tmp + 8); } else UserMessage("\r\n%s, ?INVALID?", out); break; default: UserMessage("\r\n%s,?INVALID?", out); } decoded= TRUE; j += i; } else break; } UserMessage("%s", "\r\n"); return decoded; }