EDIT: might still be correct, but i just realized, that i used a compressed sample firmware to evaluate the results. Please wait for more information. I used a partially compressed firmware from SG to test it - but I am not sure if it gets uncompressed before the checksum is calculated. The nano firmwares are completely compressed, so they need to be unpacked before calulation
I was able to recreate the checksum algorithm in c:
Code:
uint16_t calc_checksum(uint16_t data[], uint32_t length) {
uint32_t pos = 0;
uint16_t checksum = 0;
while(pos < length) {
checksum += pos + data[pos];
pos++;
}
return checksum;
}
BUT: There is one problem with the algorithm: It's off by a constant - well not really a constant.
This constant depends on the model/maybe chipset.
Example:
For StreetGuardian the "key" is 0x10000. I checked it for many SG9665GC firmwares
For nanoQ 0903 the "key" is 0x17BB4. Also works for various 0903 firmwares.
I couldnt find the "key" inside the firmware binary, so probably the bootloader knows it. Maybe it's some kind of identifier to make sure you cant crossflash firmwares from different models. Or it depends on the hardware. chipset x1 has key1, chipset x2 has key2, ...
TLDR: To get the correct checksum, first calculate the checksum with the algorithm above and then subtract it from the "key". (real_checksum = (KEY-calc_checksum(...))&0xFFFF)
Possibly I just made things more complicated than they are, if you have any suggestions or improvements, let me know!
The attached file calculates the checksum for you. usage: ntk_chksm.exe firmware.bin