title: Trying to reverse engineer a packet checksum/CRC/hash
body: <p>I have an old, no longer manufactured electronic device with a serial port. I am trying to reverse engineer the data packet CRC/checksum/hash used in this device.</p>
  
  <p>Anyone with keen eyes, sharp math skills out there who might be able to crack this thing ?</p>
  
  <p>Here is what I know so far ...</p>
  
  <ul>
  <li>Every packet is always 21 bytes. 19 bytes of data plus 2 bytes at end for CRC/checksum/hash</li>
  <li>Hence, there are here are no length or header bytes. All 19 bytes are involved in the hash calculation.</li>
  <li>I have ability to generate certain amounts of data packets with the device</li>
  <li>My first thoughts is that the data packets have some sort of CRC-16 calculation</li>
  <li>So I followed reversing hints in <a href="http://www.cosc.canterbury.ac.nz/greg.ewing/essays/CRC-Reverse-Engineering.html">www.cosc.canterbury.ac.nz/greg.ewing/essays/CRC-Reverse-Engineering.html</a></li>
  <li><p>Verified that my data packet samples observed the "superposition principle" outlined in above web link. This indicates that they have a mathematical XOR relationship.</p></li>
  <li><p>Started to feel good ... but then stumped after that. Have not been able to determine a CRC-16 polynomial. There is a strong possibility that these data packets hashes are not CRC-related, but rather some home brew scheme.</p></li>
  <li><p>Read thru “A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS” by Ross N. Williams</p></li>
  <li>See <a href="http://www.ross.net/crc/download/crc_v3.txt">http://www.ross.net/crc/download/crc_v3.txt</a></li>
  <li>Also used application: CRC Reveng – a reverse engineering application</li>
  <li>See reveng.sourceforge.net</li>
  <li>Still no luck ...</li>
  <li><p>Unfortunately, I do not have access to any of the devices source/binary code</p></li>
  <li><p>Also ran tests to see if used other hashes such as Fletcher's checksum</p></li>
  </ul>
  
  <p>Here are various samples of my data packets.</p>
  
  <blockquote>
    <p>0x47366B2EE00000000000751CEB5F3469543B585E2D<br>
    0x47366B2ED00000000000751CEB5F3469543B582A2C<br>
    0x47366B2EC80000000000751CEB5F3469543B580B2B<br>
    0x47366B2EC40000000000751CEB5F3469543B58BB2A<br>
    0x47366B2EC20040000000751CEB5F3469543B58DFE7<br>
    0x47366B2EC10000000000751CEB5F3469543B58A328<br>
    0x47366B2EC08000000000751CEB5F3469543B584127<br>
    0x47366B2EC04000000000751CEB5F3469543B588126<br>
    0x47366B2EC02000000000751CEB5F3469543B580525<br>
    0x47366B2EC01000000000751CEB5F3469543B580124</p>
  </blockquote>
  
  <p>Please note the following about these data packets ...</p>
  
  <ul>
  <li>CRC is found on the last 2 bytes of the data packet.</li>
  <li>If I look at the bits on a logic analyzer, I have expressed the bytes as MSB-first</li>
  <li>Hence, packet 0x47366B2EE00000000000751CEB5F3469543B585E2D is seen in binary as:</li>
  <li>01000111 .............................................................00101101</li>
  <li><p>(0x47).....................................................................(0x2D)</p></li>
  <li><p>I do not know if my system is big or little endian, but quite certain bytes are LSB-first</p></li>
  <li>Note that for the above 10 data packet samples, each packet differs by 1 bit shifting thru 10 bit positions. Except for 5th packet, where I had to change 2 bits</li>
  <li><p>See data bytes that follows 0x47366B2E portion of the data packet.</p></li>
  <li><p>Only pattern I see that emerged is the last byte decrements by one (2D, 2C, ...) on each data packet. (Except the 5th packet, where I had to change 2 bits)</p></li>
  <li>This last byte is NOT some sort of sequence number, since I can generate them at any time with same value.</li>
  <li>But it possibly gives a hint on the mathematical hash used.</li>
  </ul>
  
  <p>Any help is appreciated !</p>