Hello,

>From the link you've provided the checksum generation function appears to 
>work, but I'm not sure if checksum verification works properly (however I 
>might be doing something wrong). I've taken a look on how `APFS` from 
>`APFS.framework` does it, and it seems it performs something in the lines of:

    // This implementation doesn't properly handle unaligned data sizes.
    uint64_t calc_fletcher64(const uint8_t* data, size_t dataSize,
        uint64_t initialValue) {
    
        uint64_t val1 = initialValue & UINT_MAX;
        uint64_t val2 = (initialValue >> 32) & UINT_MAX;
    
        for(size_t i = 0, len = dataSize / 4; i < len; ++i) {
            uint32_t dataChunk = ((uint32_t*) data)[i];
    
            val1 += dataChunk;
            val1 %= UINT_MAX;
            val2 += val1;
            val2 %= UINT_MAX;
        }
    
        return val1 | (val2 << 32);
    }
    
    uint64_t check_block(const uint8_t* blockptr, size_t blocksize) {
        uint64_t ret = calc_fletcher64(&blockptr[8], blocksize - 8, 0);
        ret = calc_fletcher64(&blockptr[0], 8, ret);
        return ret;
    }

If the `check_block(...)` function returns 0, the checksum is OK. If it will 
return something else than zero, the return value contains information about 
the place of the corruption (I think) as well as the difference between a valid 
block and an invalid block (at least it looks like it).

Complete code: 
    https://gist.github.com/antekone/a611dd4f2f9e22200fa8e9498cf36277

Compilation/testing:       
    g++ apfs_check.c -o apfs_check && ./apfs_check

Regards,
Grzegorz Antoniak

On niedziela, 30 kwietnia 2017 13:47:32 CEST Thomas Tempelmann wrote:
> Nevermind - someone figured it out: https://blog.cugu.eu/post/apfs/#checksum
> 
> My code was missing the extra (optional) "check bytes" after the sums
> calculation.
> 
> I've updated my code accordingly:
> http://files.tempel.org/tmp/apfs-fletcher-test.zip
> 
> It now also contains versions for fletcher-16 and -32, as well as an
> optimized form that avoids the use of the modulo operator (though, with
> modern desktop CPUs, I wonder if that even still makes a difference or if
> the MOD instruction is just as fast as an AND and a SHIFT instruction
> together).
> 
> (As Quinn says) Enjoy,
>   Thomas
> 
> 
> 
> On Sun, Apr 30, 2017 at 1:47 AM, Toby Thain <t...@telegraphics.com.au>
> wrote:
> 
> > On 2017-04-29 7:42 PM, Thomas Tempelmann wrote:
> >
> >> On Sun, Apr 30, 2017 at 1:37 AM, Toby Thain <t...@telegraphics.com.au
> >> <mailto:t...@telegraphics.com.au>> wrote:
> >>
> >>     Seems you have % instead of & ? And watch out for sign extension on
> >>     those literal 0xFFFFFFFF's. You probably want an unsigned and long
> >>     long suffix on them.
> >>
> >>
> >> Nope, both are correct, at least for standard fletcher algorithm. It's
> >> always modulo (%) MAXINT-1.
> >>
> >
> > Ah, OK. Thanks for clarifying!
> >
> >
> > > And 0xFFFFFFFF's gets properly expanded to
> >
> >> unsigned 64 bit, as it should. I double checked using uint64_t variable
> >> all the way, and it didn't change the outcome.

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Filesystem-dev mailing list      (Filesystem-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/filesystem-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to