2

We're having a hard time figuring out how the checksum/CRC is calculated for this serial communication protocol we're required to reverse engineer. This is a communication protocol used back in the 1990 (at least). It is used by embedded code for communication between display units. So far, we have noticed some things, but nothing of any relevance to understanding the CRC. Here are a couple of message we collected:

Some messages are quite short. We think it is some sort of acknowledgement. 2 versions exists:

  • 7F 25 64 12 78 21 44 7F 7F
  • 7F 25 64 12 79 31 65 7F 7F

These are some timing messages, as far as we can tell. Notice how byte number 27 changes by an increment of 5:

  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 10 38 17 30 00 3D 79 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 15 38 17 30 00 1E 2E 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 1A 38 17 30 00 7B 57 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 1F 38 17 30 00 58 00 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 24 38 17 30 00 38 11 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 29 38 17 30 00 19 6B 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 2E 38 17 30 00 7E 3F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 33 38 17 30 00 5B 1F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 38 38 17 30 00 37 60 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 3D 38 17 30 00 14 37 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 42 38 17 30 00 6C 48 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 47 38 17 30 00 4F 1F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 4C 38 17 30 00 23 60 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 51 38 17 30 00 06 40 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 56 38 17 30 00 61 14 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 5B 38 17 30 00 40 6E 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 60 38 17 30 00 20 7F 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 65 38 17 30 00 03 28 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 6A 38 17 30 00 66 51 7F 7F

Some of these messages change by only one bit (except for the checksum at the end):

  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 71 38 17 30 00 2C 24 7F 7F
  • 7F 25 4E 62 01 00 00 67 50 04 10 28 73 7A 2D 31 77 2F 03 21 33 00 27 13 7C 7F 73 38 17 30 00 4B 70 7F 7F

So, what we managed to figure out:

  1. Obviously, 7F25 is the start of the message, 7F7F is the end (this is constant over all messages).
  2. bytes number N-2 and N-3 act as some sort of checksum/CRC.
  3. No byte is higher than 7F anywhere. Never.
  4. Looking at some messages, it appears that a single bit change untroduce large variations of the checksum bytes. This pointed us in the dirrection of a CRC algorithm.
  5. We've been told that the company that created the protocol likely used some variation of CRC16-CCITT. We have been unable to confirm/verify that.

We are at lost. Any help in solving this riddle would be greatly appreciated.

Thanks.

EDIT 1

I tried a lot of different CRC variations, with lots of different parts of the messages. Nothing came up interesting. Except this...

If you look at the 2 very short messages, you can see that after removing the start message bytes and the end message bytes, we are left with a message of only 3 bytes + 2 checksum bytes. Only one of the message bytes changes, the last one. The difference between the 2 messages (0x78 becomes a 0x79 on last position) results in only the last bit of the message changing. This results in a change in the 2 checksum bytes (0x21 becomes 0x31 and 0x44 becomes 0x65). Translating this information in bit, 01111000 becomes 01111001 (a change of only the last bit -> 00000001) which results in 00100001 becoming 00110001 for the first checksum byte (a change of 00010000) and 01000100 becoming 01100101 for the first checksum byte (a change of 00100001). (By a change, I mean a XOR operation)

Now, the interesting part, if I apply variations of the CRC16-CCITT (XModem, Kermit, 0xFFFF, etc.), the result (the XOR operation I have to apply to the checksum bytes to go from the 0x78 terminated message to the 0x79 terminated message) is the same!! The result is not (the checksum bytes are not what is expected) but the impact changing the single last byte has on the checksum is indeed the same. This points me in the direction of the CCITT CRC, only with a starting value different than the obvious. I did try all the possibilities of the message (only the last byte, then the last 2, etc.). There is a very limited amount of possibilities with only 3 bytes!

All this might only be a (very intreging) coincidence, but I think there is a much more simple/elegent (aka mathematical) explanation. I just lack the mathematical skills to see the obvious...

EDIT 2

The "No byte is higher than 7F" part is of course very easy to explain: there is only 7 bits of data for this protocol over serial communication. Dah! But it implies that if the check is a crc, it will yield larger than 7F checksum, which will then have to be "mod 7F" to be transmitted over the serial communication.

Trying not to "left any stone unturned".

  • If I understand correctly your first edit, you're saying that it's basically a CRC16-CCITT with only a constant value added to it? – Dillinur Nov 12 '15 at 21:35
  • Hum... I'm not stating anything, I just noticed this interresting fact. I still can't prouve that it's any type of crc. I think it might have to do with the XOR operations done during the crc. If the mathematical operations were very different, would they yield an identical transformation? Maybe it's just that the message is so small... – Philippe Richer Nov 12 '15 at 22:05
  • Either I get something wrong, or "this interesting fact" allows you to solve your problem. Identical transformation means that you just have a constant offset between the two values, it would basically never happens randomly, especially considered the properties of the CRC. If this offset is the same for all messages, that's it you can compute the checksum. – Dillinur Nov 13 '15 at 10:26
  • It might just be an XOR of a constant applied to the final CRC value. (You can test this by first XORing the message crc value with the one you calculated then trying to this value on the calculation from other packets.) – Ian Cook Nov 14 '15 at 8:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.