On 6/7/19 10:48 PM, H. Peter Anvin via Syslinux wrote:> On 6/7/19 10:34 PM, H. Peter Anvin via Syslinux wrote: >> On 6/7/19 10:25 PM, H. Peter Anvin via Syslinux wrote: >>>> >>>> However, the CRC polynomial for zlib and the Linux kernel should both be the >>>> same: 0x04c11db7. >>> >>> I just double-checked, and the CRC tables are indeed identical. I was pretty >>> sure, because I wrote that code a long time ago... >>> >> >> Ah, it seems that zlib's CRC32 returns the binary inverse of the CRC32 (i.e. >> crc32 ^ 0xffffffff); so unless the Linux code is broken (and the spec needs to >> be corrected, since that error would go back many years) using the zlib code >> one would have to look for 0xffffffff == UINT32_MAX instead of 0. >> > > Just double-checked: the spec is correct. So the zlib crc32() routine should > return UINT32_MAX == ~(uint32_t)0 == (uint32_t)-1 for a correctly loaded kernel. >And just to double check: gzip -9 bzImage gzip -l -v bzImage.gz method crc date time compressed uncompressed ratio uncompressed_name defla ffffffff Jun 7 22:53 728000 881200 17.4% bzImage ^^^^^^^^ -hpa
H. Peter Anvin wrote:> On 6/7/19 10:48 PM, H. Peter Anvin via Syslinux wrote: > > On 6/7/19 10:34 PM, H. Peter Anvin via Syslinux wrote: > >> On 6/7/19 10:25 PM, H. Peter Anvin via Syslinux wrote: > >>>> > >>>> However, the CRC polynomial for zlib and the Linux kernel should > >>>> both be the same: 0x04c11db7. > >>> > >>> I just double-checked, and the CRC tables are indeed identical. I > >>> was pretty sure, because I wrote that code a long time ago... > >>> > >> > >> Ah, it seems that zlib's CRC32 returns the binary inverse of the > >> CRC32 (i.e. crc32 ^ 0xffffffff); so unless the Linux code is > >> broken (and the spec needs to be corrected, since that error would > >> go back many years) using the zlib code one would have to look for > >> 0xffffffff == UINT32_MAX instead of 0. > > > > Just double-checked: the spec is correct. So the zlib crc32() > > routine should return UINT32_MAX == ~(uint32_t)0 == (uint32_t)-1 > > for a correctly loaded kernel. > > And just to double check: > > > gzip -9 bzImage > gzip -l -v bzImage.gz > method crc date time compressed uncompressed ratio > uncompressed_name defla ffffffff Jun 7 22:53 728000 > 881200 17.4% bzImage ^^^^^^^^ > > -hpaUnfortunately you have to account for kernel signing. Let's check this kernel distributed by openSUSE: gzip vmlinuz-5.2.0-rc1-2.gb225e5a-default gzip -l -v vmlinuz-5.2.0-rc1-2.gb225e5a-default.gz method crc date time compressed uncompressed ratio uncompressed_name defla a420c7b4 Jun 9 20:17 8121642 8486816 4.3% vmlinuz-5.2.0-rc1-2.gb225e5a-default If the certificate is stripped and the PE Certification Table wiped: gzip vmlinuz-5.2.0-rc1-2.gb225e5a-default-nosig-fixed gzip -l -v vmlinuz-5.2.0-rc1-2.gb225e5a-default-nosig-fixed.gz method crc date time compressed uncompressed ratio uncompressed_name defla ffffffff Jun 9 20:30 8120363 8485248 4.3% vmlinuz-5.2.0-rc1-2.gb225e5a-default-nosig-fixed So we need to 1. Check for CONFIG_EFI_STUB 2. Check if kernel ever contained certificates (PE Certificate Table) 3. Get offset from PE Certificate Table 4. crc32 kernel until offset and skip PE Certificate Table 5. Compare checksum Sebastian
On June 9, 2019 12:38:46 PM PDT, Sebastian Herbszt <herbszt at gmx.de> wrote:>H. Peter Anvin wrote: >> On 6/7/19 10:48 PM, H. Peter Anvin via Syslinux wrote: >> > On 6/7/19 10:34 PM, H. Peter Anvin via Syslinux wrote: >> >> On 6/7/19 10:25 PM, H. Peter Anvin via Syslinux wrote: >> >>>> >> >>>> However, the CRC polynomial for zlib and the Linux kernel should >> >>>> both be the same: 0x04c11db7. >> >>> >> >>> I just double-checked, and the CRC tables are indeed identical. I >> >>> was pretty sure, because I wrote that code a long time ago... >> >>> >> >> >> >> Ah, it seems that zlib's CRC32 returns the binary inverse of the >> >> CRC32 (i.e. crc32 ^ 0xffffffff); so unless the Linux code is >> >> broken (and the spec needs to be corrected, since that error would >> >> go back many years) using the zlib code one would have to look for >> >> 0xffffffff == UINT32_MAX instead of 0. >> > >> > Just double-checked: the spec is correct. So the zlib crc32() >> > routine should return UINT32_MAX == ~(uint32_t)0 == (uint32_t)-1 >> > for a correctly loaded kernel. >> >> And just to double check: >> >> >> gzip -9 bzImage >> gzip -l -v bzImage.gz >> method crc date time compressed uncompressed ratio >> uncompressed_name defla ffffffff Jun 7 22:53 728000 >> 881200 17.4% bzImage ^^^^^^^^ >> >> -hpa > >Unfortunately you have to account for kernel signing. >Let's check this kernel distributed by openSUSE: > >gzip vmlinuz-5.2.0-rc1-2.gb225e5a-default >gzip -l -v vmlinuz-5.2.0-rc1-2.gb225e5a-default.gz >method crc date time compressed uncompressed >ratio uncompressed_name >defla a420c7b4 Jun 9 20:17 8121642 8486816 >4.3% vmlinuz-5.2.0-rc1-2.gb225e5a-default > >If the certificate is stripped and the PE Certification Table wiped: > >gzip vmlinuz-5.2.0-rc1-2.gb225e5a-default-nosig-fixed >gzip -l -v vmlinuz-5.2.0-rc1-2.gb225e5a-default-nosig-fixed.gz >method crc date time compressed uncompressed >ratio uncompressed_name >defla ffffffff Jun 9 20:30 8120363 8485248 >4.3% vmlinuz-5.2.0-rc1-2.gb225e5a-default-nosig-fixed > >So we need to > >1. Check for CONFIG_EFI_STUB >2. Check if kernel ever contained certificates (PE Certificate Table) >3. Get offset from PE Certificate Table >4. crc32 kernel until offset and skip PE Certificate Table >5. Compare checksum > >SebastianSigh. Of course something had to be broken somewhere. The CRC should have been applied after the signature, not before. -- Sent from my Android device with K-9 Mail. Please excuse my brevity.