Re: CRC32 check for IDAT chunks

Nicolas Badoux <[email protected]> Thu, 31 Jan 2019 12:12:20 +0100
Newsgroups gmane.comp.graphics.png.devel
Message-ID <CAMJ5jhsJZRV=-K-HYEFvrQkM0DSb=VN5HaUpD9V6bZt-Cy3eCA@mail.gmail.com>
>
> CRC is always checked. An incorrect CRC causes a benign error for an
> ancillary chunk, or a severe error for a critical chunk.


Where exactly is it checked ? From what I understand,  pnc_read_IDAT_data
call pnc_crc_read. png_crc_read in itself doesn't check the crc. It just
calls pnc_calculate_crc which doesn't check the crc either.
crc is checked in png_crc_error which is only called by pnc_crc_finish
and png_handle_PLTE.

png_crc_finish is only called by pnc_read_IDAT once, if the IDAT size if 0
(which is usually not the case).

From my own test, when IDAT data is corrupted, it results in a zlib error
and not in a checksum error.

Best,

Nicolas

On Thu, 31 Jan 2019 at 05:44, Cosmin Truta <[email protected]> wrote:

> 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
>
>
> _______________________________________________
> png-mng-implement mailing list
> png-mng-implement-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/png-mng-implement
>

_______________________________________________
png-mng-implement mailing list
png-mng-implement-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/png-mng-implement