I'm finally getting to updating my disk editor iBored to handle APFS structures.
I am struggling with validating the checksum, which is at the first 8 bytes of many metadata blocks.
The APFS FAQ mentions the use of the fletcher checksum algorithm, and I assume that the entire block, bar the first 8 bytes containing the checksum, is used for the calculation.
I guess that it's a fletcher 64 checksum, i.e. adding up 32 bit values, thereby generating one 64 bit result. I've used this code to calculate it:
static uint64_t fletcher64 (const char *data, int byteCount)
{
uint64_t sum1 = 0;
uint64_t sum2 = 0;
int dwordCount = byteCount / 4;
for (int index = 0; index < dwordCount; index += 1) {
sum1 = (sum1 + ((uint32_t*)data)[index]) % 0xFFFFFFFF;
sum2 = (sum2 + sum1) % 0xFFFFFFFF;
}
return (sum2 << 32) | sum1;
}
However, the values only match half way: The upper 32 bit are always correct, but the lower 32 bit are not. This is odd because the upper 32 bit are made from "sum2", which is derived from "sum1" - so how can the former be correctly calculated if the latter is not?
Can someone shed some light on this?
I have an Xcode test project here, along with sample block data ("NXSB"):
--