What's new

CRC16 Help

BGNG

New member
I have an anonymous file that may or may not be related to ROMs and may or may not have anything to do with Nintendo DS. In said file, there is a header with three fields for checksums. The checksums are calculated with the CRC16 algorithm, or so I believe.

The first checksum is calculated on data later in the file, but the second checksum is calculated off of the header; including the pre-calculated value of the first checksum. For example:

File size: 10 bytes
Checksum 1: Bytes 8 to 10 -> Store in bytes 2 to 3
Checksum 2: Bytes 1 to 6

As you can see, Checksum 2 is calculated using the checksum previously calculated for Checksum 1.
__________

Thing is, though... I can calculate Checksum 2 correctly, which is based off of the values of Checksum 1, but I can't calculate Checksum 1 correctly.

The documentation I have says that bytes 0x4000 to 0x7FFF are used for Checksum 1, but I can't seem to get it to work. The same algorithm, however, correctly calculates Checksum 2 and Checksum 3.

I've attached the region of the anonymous file from 0x4000 to 0x7FFF. The checksum in the file's header is 0xCAC3, but when I calculate it, I keep getting 0x8582.

Anyone able to help?
 

Cyberman

Moderator
Moderator
First.. a CRC is not a checksum.

Second you have to know the SEED/Initial Value and the polynomial for a CRC to be calculated correctly.

It's possible to compute the CRC value with those two things.

Knowing the data that the CRC is computed over is helpful of course but not too helpful if you don't know the seed and polynomial value.

CRC's are used to detect bit errors, and are much more stringent a test than a checksum. The probability of two checksums being the same over a large number of characters is too high so they created the CRC.

Code:
#define SEED 0xFFFF
#define POLYNOMIAL 0xA001
unsigned short CRC16(void *Src, int Length)
{
 char *Data = (char *)Src;
 unsigned short CRC, Temp;
 int ShiftCnt;

 CRC = SEED & 0xFFFF; /// seed the CRC value
 while(Length--)
 {
  ShiftCnt = 8;
  while(ShiftCnt--)
  {
   CRC ^= ((unsigned short)*Data & 0x00FF);
   if(CRC & 0x0001)
   {
    CRC>>=1;
    CRC ^= POLYNOMIAL;
   }
   else
    CRC>>=1;
  }
  Data++;
 }
 return CRC;
}
And that's how you calculate a 16 bit CRC. You can compute ones as large as you want also.


Cyb
 
Last edited:
OP
BGNG

BGNG

New member
CRC, Checksum (Courtesy of Wikipedia)

The initial value for all three CRC16 fields in this file header is 0xFFFF. And, as I mentioned, I can get two of them calculated correctly with the code I'm currently using; it's the other one that's giving me troubles.

A likely cause for this is the cartridge encryption implemented by the DS. It's possible that the data I have is non-executable, encrypted program data, so the CRC algorithm is being performed on data that's technically not there. If this is so, then there's no way I can correctly calculate the value (unless there's a tell-tale signifier that will allow proper decryption of the ROM files given only the ROM data)
 

euphoria

Emutalk Member
It's not that big of a deal to program it to go through all the poly's in 16-bit CRC. If the initial value isn't 0xFFFF then it just takes more time ;) You should try it first with 0xFFFF and 0x0000.
 

Cyberman

Moderator
Moderator
BGNG said:
The initial value for all three CRC16 fields in this file header is 0xFFFF. And, as I mentioned, I can get two of them calculated correctly with the code I'm currently using; it's the other one that's giving me troubles.
It might not be a checksum or CRC have you considered MD5?

BGNG said:
A likely cause for this is the cartridge encryption implemented by the DS. It's possible that the data I have is non-executable, encrypted program data, so the CRC algorithm is being performed on data that's technically not there. If this is so, then there's no way I can correctly calculate the value (unless there's a tell-tale signifier that will allow proper decryption of the ROM files given only the ROM data)
Depends on the encryption algo, which is as a varied as a CRC polynomial and CRC can be. If you are looking at program data, it's likely encrypted howsumever. Also data is likely to be encrypted as well. Need the key and algo for either of those to compute what you want.

Cyb
 
OP
BGNG

BGNG

New member
The DS has a hardware encryption that is based off of the real-time clock, so every byte read from it will be encrypted in some way, which is yet to be discovered. Every time you dump a ROM from a DS card, the dump will be different because of this. That being said, running a CRC16 checksum calculation on the encrypted data will prove insufficient even if the algorithm is correct.
 

Top