Hi all,

On Wed, Oct 23, 2019 at 09:24:50AM +0200, Tomas Janousek wrote:
> And there's something horribly wrong with the Debian build of modules, it
> seems. I wonder what else is broken on this system because of a badly signed
> module... :-/

I tried to investigate what's wrong with the module signature with some help
from https://unix.stackexchange.com/a/496800/11549:

preparation (extract signing public key):

$ /tmp/modules-5.3
$ /usr/src/linux-2.6/scripts/extract-vmlinux /boot/vmlinuz-5.3.0-1-amd64 
>vmlinux-5.3.0-1-amd64
$ /usr/src/linux-2.6/scripts/extract-sys-certs.pl -s 
/boot/System.map-5.3.0-1-amd64 /tmp/modules-5.3/vmlinux-5.3.0-1-amd64 cert.x509
$ dd if=cert.x509 bs=1 skip=$(openssl asn1parse -inform der -in cert.x509 | 
grep ':d=0' | tail +2 | cut -d: -f1 | xargs) of=cert2.x509

test if ./checkmodsig.pl works:

$ ./checkmodsig.pl /tmp/modules-5.3/cert2.x509 
/lib/modules/5.3.0-1-amd64/kernel/sound/pci/hda/snd-hda-intel.ko
OK /lib/modules/5.3.0-1-amd64/kernel/sound/pci/hda/snd-hda-intel.ko
$ ./checkmodsig.pl /tmp/modules-5.3/cert2.x509 
/lib/modules/5.3.0-1-amd64/kernel/sound/pci/hda/snd-hda-codec-hdmi.ko
RSA operation error
139736462386368:error:0407008A:rsa 
routines:RSA_padding_check_PKCS1_type_1:invalid 
padding:../crypto/rsa/rsa_pk1.c:66:
139736462386368:error:04067072:rsa routines:rsa_ossl_public_decrypt:padding 
check failed:../crypto/rsa/rsa_ossl.c:588:
status 256 at ./checkmodsig.pl line 12, <GEN6> line 1.

verify signatures manually so that we can experiment more later:

$ /usr/src/linux-2.6/scripts/extract-module-sig.pl -s 
/lib/modules/5.3.0-1-amd64/kernel/sound/pci/hda/snd-hda-intel.ko 
>snd-hda-intel.sig
Read 100988 bytes from module file
Found magic number at 100988
Found PKCS#7/CMS encapsulation
Found 396 bytes of signature [3082018806092a864886f70d010702a0]
$ openssl asn1parse -inform der -in snd-hda-intel.sig | tail -1
  136:d=5  hl=4 l= 256 prim: OCTET STRING      [HEX 
DUMP]:8DA6777C21575F4535E64F559B1B6399CFF0627D77CA5001D0B3124AA8435F2E767B4631DA842F989C57057F11EA0B51C65FCAEA032353520D5E3476EC1A7AF32D83D39F1652401AA5EC5B8EEE7DD663DFB4365EF9DE2C4109AE94378C3D5877AE9046DE5C54F572827403A3D7677C5DABB661789F4453F396D5D647C7233FEA3F4C21E14B7663E2D0D41564D5D220168BD3AFABC90CC451D3B1BE0F9E012B24282C52FCEB97501A42F776D4CFBDBDE8E9837DFCA380CCBD423B73522AD6C256FD91342760B71140A04BABC32E1D05EF77A1A4F031CB8A4131C0DE87AAEA2E653EBF6AE9373AC76694FD42CB622DAEDD6E4061FB865F49C94CBB22C003047F67
$ openssl asn1parse -inform der -in snd-hda-intel.sig | perl -ne '/\[HEX 
DUMP\]:(.*)/ && print $1' | xxd -r -p | openssl rsautl -verify -pubin -inkey 
pubkey2.pem -asn1parse
    0:d=0  hl=2 l=  49 cons: SEQUENCE
    2:d=1  hl=2 l=  13 cons:  SEQUENCE
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha256
   15:d=2  hl=2 l=   0 prim:   NULL
   17:d=1  hl=2 l=  32 prim:  OCTET STRING
      0000 - f2 da 77 a3 32 76 18 2b-66 a8 20 2c 07 a2 81 fb   ..w.2v.+f. ,....
      0010 - 28 a9 9e 17 c6 87 f3 d7-c1 21 f7 8a bb f0 ee 2e   (........!......

(let's skip the hash comparison, that's useless now)

same thing with snd-hda-codec-hdmi

$ /usr/src/linux-2.6/scripts/extract-module-sig.pl -s 
/lib/modules/5.3.0-1-amd64/kernel/sound/pci/hda/snd-hda-codec-hdmi.ko 
>snd-hda-codec-hdmi.sig
Read 133153 bytes from module file
Found magic number at 133153
Found PKCS#7/CMS encapsulation
Found 393 bytes of signature [3082018506092a864886f70d010702a0]
$ openssl asn1parse -inform der -in snd-hda-codec-hdmi.sig | tail -1
  136:d=5  hl=3 l= 254 prim: OCTET STRING      [HEX 
DUMP]:8204A68D4EDDC44A0FB89998D7D0FF2A37351C3E9A76D42C015BD868E7A579F95F95C145D61C73F3EC54B314A297DA7E9AE9CACFBD01C0E489E35A3D05F882B01FCEA25754D704F83672841416B69C52760C758A60AF2A38B5706FC02CBEA8AAB1D6F4E82B3C9F0E163B41C0F06E9DFDC166531BBB25BECBFCD3F01097C4ABD32D90A84F3F07DDE5C508F6CCD56CA5BB5467C4D70BB5AC64D432478C4454654F4D77F9DB6EC957F3A70CF818268643F84C64E49DE88624D588B6ED6CCFF2AE8DBF1D8D724BE5EBFCFCAB96E0E47B7B70553268A5BAAC41CBA8AFA8E4A65B5F229038283D99CD2A2D13931D891DF911EF298F8BDC9488E4D07A29AD810330

it's just 254 bytes, that's weird, but it's a valid asn1 and the magic string
in .ko is after that, so it's not like the .ko was trimmed or anything, it's
the actual signature that's short... let's try to verify it

$ openssl asn1parse -inform der -in snd-hda-codec-hdmi.sig | perl -ne '/\[HEX 
DUMP\]:(.*)/ && print $1' | xxd -r -p | openssl rsautl -verify -pubin -inkey 
pubkey2.pem
RSA operation error
139750929511616:error:0407008A:rsa 
routines:RSA_padding_check_PKCS1_type_1:invalid 
padding:../crypto/rsa/rsa_pk1.c:66:
139750929511616:error:04067072:rsa routines:rsa_ossl_public_decrypt:padding 
check failed:../crypto/rsa/rsa_ossl.c:588:

nope. okay, let's disable padding...

$ openssl asn1parse -inform der -in snd-hda-intel.sig | perl -ne '/\[HEX 
DUMP\]:(.*)/ && print $1' | xxd -r -p | openssl rsautl -verify -pubin -inkey 
pubkey2.pem -raw | xxd
00000000: 0001 ffff ffff ffff ffff ffff ffff ffff  ................
00000010: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000020: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000030: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000040: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000050: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000060: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000070: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000080: ffff ffff ffff ffff ffff ffff ffff ffff  ................
00000090: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000a0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000b0: ffff ffff ffff ffff ffff ffff ffff ffff  ................
000000c0: ffff ffff ffff ffff ffff ffff 0030 3130  .............010
000000d0: 0d06 0960 8648 0165 0304 0201 0500 0420  ...`.H.e.......
000000e0: f2da 77a3 3276 182b 66a8 202c 07a2 81fb  ..w.2v.+f. ,....
000000f0: 28a9 9e17 c687 f3d7 c121 f78a bbf0 ee2e  (........!......

this is pkcs#1 padding and then valid asn1, now snd-hda-codec-hdmi:

$ openssl asn1parse -inform der -in snd-hda-codec-hdmi.sig | perl -ne '/\[HEX 
DUMP\]:(.*)/ && print $1' | xxd -r -p | openssl rsautl -verify -pubin -inkey 
pubkey2.pem -raw | xxd
00000000: b146 76ac 5776 8650 048c ed44 6805 7e06  .Fv.Wv.P...Dh.~.
00000010: 39cb bc02 ddf1 20a3 fa6a 8b7c 9a39 f40a  9..... ..j.|.9..
00000020: 20c5 667d bb7b 29b4 560c c8f2 08dd e483   .f}.{).V.......
00000030: 6759 9e52 c5b7 7e9a ef61 08de 57e9 a001  gY.R..~..a..W...
00000040: 774b 8fb5 e501 9a72 9ff0 ebc2 48f2 9c9b  wK.....r....H...
00000050: 8682 e2dc d0a0 2b6f c26a 06cc 87ac 03db  ......+o.j......
00000060: 5b68 5b79 5daa c4e1 891c 5ae1 d67d d1c4  [h[y].....Z..}..
00000070: 4b3c 07b9 ae0c c9bf 9b07 fdcd d4ab cb1c  K<..............
00000080: fab7 ca91 e6b2 7215 5f3d 4806 266b 6f38  ......r._=H.&ko8
00000090: 76dd 600a e4bd 665c 88c0 64a9 7a00 9d1f  v.`...f\..d.z...
000000a0: c680 90fe e979 fcce 100b 43f2 690d 8f27  .....y....C.i..'
000000b0: e17e 12ab db62 2d86 2bf4 a468 b75d 914d  .~...b-.+..h.].M
000000c0: 0b7c 6a1d d45a 9df7 9f3f 7972 8d05 873c  .|j..Z...?yr...<
000000d0: c0e9 e5b2 65ad f818 2cdb 942b 317d 3c89  ....e...,..+1}<.
000000e0: 5e67 2676 e7fe 8419 a464 9cbb b890 8d20  ^g&v.....d.....
000000f0: 63ad e66e 4b31 18ea 1dee 9d86 ccfc fc9b  c..nK1..........

random encrypted whatever :-(
but it was 2 bytes shorter, so maybe if we pad it with zeros from either side
it'll be fine... or let's just try all possible 2 byte paddings from either
side:

$ openssl asn1parse -inform der -in snd-hda-codec-hdmi.sig | perl -ne '/\[HEX 
DUMP\]:(.*)/ && print $1' | xxd -r -p >snd-hda-codec-hdmi.sig2
$ for i in $(seq 0 65535); do (printf "%0.4x\n" $i | xxd -r -p; cat 
snd-hda-codec-hdmi.sig2; ) | openssl rsautl -verify -raw -pubin -inkey 
pubkey2.pem | xxd -p; done | grep ffffffff
$ for i in $(seq 0 65535); do (cat snd-hda-codec-hdmi.sig2; printf "%0.4x\n" $i 
| xxd -r -p; ) | openssl rsautl -verify -raw -pubin -inkey pubkey2.pem | xxd 
-p; done | grep ffffffff

nope, that's not it

At this point I'm out of ideas. It doesn't seem to be a padding issue, and I
don't how to investigate this further. The signature, however, does seem to be
deterministic (there's no salt, just sha256 in asn1, pkcs#1 padding and the
result is encrypted using RSA), so if someone has access to the Debian Secure
Boot Signer private key, they should be able to replicate the output.

Oh and one last thing: I checked all modules in
/lib/modules/5.3.0-1-amd64/kernel using ./checkmodsig.pl and
snd-hda-codec-hdmi is the only one affected.

In /lib/modules/5.2.0-3-amd64/kernel/ everything's okay.

Uff. :-)

-- 
Tomáš Janoušek, a.k.a. Pivník, a.k.a. Liskni_si, http://work.lisk.in/

Reply via email to