Re: CRC32 check for IDAT chunks
Cosmin Truta <[email protected]> Wed, 30 Jan 2019 23:44:24 -0500
| Newsgroups | gmane.comp.graphics.png.devel |
|---|---|
| Message-ID | <CAAoVtZzbaTb5FGLL3-i06Ux5AytYc+s9J-zgJO4xxAyi_-gURg@mail.gmail.com> |
On Wed, 30 Jan 2019 at 13:16, Nicolas Badoux <[email protected]> wrote: > I'm looking at the code of libpng and was wondering why there is not always a check to verify the CRC32 value when reading IDAT chunks. CRC is always checked. An incorrect CRC causes a benign error for an ancillary chunk, or a severe error for a critical chunk. > If I'm correct, the CRC is calculated at line 4193 of pngrutil.c (lbpng-1.6.36). The call to inflate on line 4225 can happen without that the CRC value was checked against the value in the file. CRC is independent of inflate. To the CRC calculation, the compressed deflate stream is just raw data. The validity of inflate is checksum'ed by Adler32. What you're seeing is merely an update of the CRC. Specifically, an update to png_ptr->crc. See the function png_calculate_crc(). > Is this done willingly to spare time as inflate will likely fail anyway? That's not what's happening. You may verify that by creating a PNG file with an incorrect CRC (or taking a correct PNG file and altering the CRC in a hex editor, for example), and then seeing the CRC error being raised by libpng. But Bob is right. An attacker can purposely corrupt an image and update the CRC accordingly, and nobody would notice. An attacker can even keep the same CRC and create a corrupt image that matches the original CRC, by the means of a computational trial-and-error process, with trivial effort. A CRC is not a secure checksum (like SHA-1, for example), nor is it intended to be. For securing your image, you may use an external digest program (sha1sum, sha256sum, b2sum, etc.) or, in theory, an internal PNG dSIG chunk. I say "in theory" because dSIG is an officially registered PNG extension, and yet I don't know what software (if any) recognizes it. > If I got something wrong, can you point me to the line where the CRC value of IDAT chunks are checked? You can see png_ptr->crc being updated in png_calculate_crc(), and checked in png_crc_error(). Sincerely, Cosmin