I have a device that is exchanging messages on a CAN bus. I am trying to reverse engineer the protocol being used.
I can decode the protocol (or most of it), but I am struggling to reverse engineer the checksum/CRC being used (without it, the device does not accept it as a valid message). This CRC is at the "application" layer, CAN has its own CRC, but this is the data/payload transmitted by CAN (17 * 8 byte messages, for a total of 136 bytes).
An example message:
07 55 AA AA 00 AA 12 94
37 5A 00 00 2E 02 5C 03
3A 02 0A 78 00 60 22 26
02 00 00 00 00 DC 00 50
4B 64 B8 0B E0 2E 70 17
84 25 08 78 1E 0A 78 00
8C AF B4 69 00 54 24 D4
24 0A 70 10 19 00 00 06
CC 0C E8 03 B0 04 51 44
14 2C 01 88 13 28 00 0A
00 C0 00 C0 80 C8 0B C0
25 C0 11 C3 00 C0 00 58
00 00 C0 0F C0 8A C0 09
C2 10 C1 07 C2 00 C0 92
CB 00 3A C7 0F DF 52 14
00 00 00 00 51 00 D2 05
00 00 00 ED 6D 00 00 00
More messages here: https://pastebin.com/uPsMNfyq
The CRC? seems to quite obviously be 'ED 6D' in the last 8 bytes. I don't know where the message starts or ends, the first 8 bytes seem to be some sort of preamble, but they do change sometimes. The same for line 16 - it seems to be some sort of trailing header, but it does change sometime. So the checksum/CRC (assuming this is what it is) could cover some part of the message.
I tried several tools, among which:
None of which yielded any results.
Any help/ideas would be highly appreciated.
Update: Based on the comments here, I crafted two more messages where the parts modified are the earliest (byte 14) and the latest (byte 119) bytes I'm aware how to modify: here.
I reversed the crc (6DED) I also ran delsum trying algo = 0x1021, different start/stop bytes and different init values. I got a few results that look good (still running), but unfortunately none of these seem to verify other messages CRC.
Those two bytes are indeed a 16-bit CRC. It is a forward (not reflected) CRC with the polynomial 0x1021
, and the CRC is stored at the end in little-endian order.
It is a little odd to store a forward CRC in little-endian order. Normally that would be in big-endian order, so that a CRC calculation including the CRC bytes would be a constant for messages with a correct CRC. That may be why it's not being found by the other tools you tried.
It is not possible just from the examples you provided to determine where exactly the CRC computation starts or ends, since the only the 41st, 59th, and 64th bytes in the messages vary. Those only bound the bytes that participate, so definitely those from the 41st to just before the CRC are part of it, but likely many before the 41st.
It is also not possible to determine the initial value and final exclusive-or without knowing those bounds, and even if you knew the bounds, you could not determine both of those parameters since all of the messages are all of the same length.
Though you mention that this is on a CAN bus, this is not a CAN CRC, since those CRCs are 15 bits, 17 bits, and 21 bits.
For the provided examples, it is possible for the CRC calculation to start at any of the offsets 0..40. For each of those offsets, there exists an initial CRC value, with a final exclusive-or of zero, that will give the correct CRC. Here are those initial values:
0 -> 0x5188
1 -> 0xb233
2 -> 0xbec9
3 -> 0x9bb5
4 -> 0x9372
5 -> 0xc1da
6 -> 0x07cd
7 -> 0x8f94
8 -> 0x375a
9 -> 0x5a00
10 -> 0x0000
11 -> 0x0000
12 -> 0x0000
13 -> 0xc5ac
14 -> 0x05ab
15 -> 0x60dc
16 -> 0x80c5
17 -> 0xc391
18 -> 0x586d
19 -> 0x17b7
20 -> 0x2a49
21 -> 0xcc28
22 -> 0x5c66
23 -> 0xf959
24 -> 0x6392
25 -> 0xee87
26 -> 0x9be0
27 -> 0xd2d2
28 -> 0x393f
29 -> 0x987a
30 -> 0x7240
31 -> 0x1ed5
32 -> 0x7c0a
33 -> 0x4cb4
34 -> 0x116a
35 -> 0x4ec3
36 -> 0xdb61
37 -> 0xe638
38 -> 0x6044
39 -> 0x5631
40 -> 0x69e5
It may be interesting that the initial value would be zero for offsets 10, 11, and 12. Those cannot be distinguished, since the examples all have zeros at offset 10 and 11, and since a zero does not change a CRC with an initial value of zero. So if we assume that the initial and final values should be "nice" somehow, then 10, 11, and 12 may be good candidates, as their initial values and final exclusive-or's are zero.
Though no one can promise that the world will be nice.
One could also pick a different final exclusive-or value and get another, different set of initial values. All of the combinations generated, starting at their associated offsets, will give the CRC in the message for all of the example messages.