Skip to content

Instantly share code, notes, and snippets.

@jandryuk
Created September 25, 2020 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jandryuk/62f18d802eb705f5ecf4ecd866318f3a to your computer and use it in GitHub Desktop.
Save jandryuk/62f18d802eb705f5ecf4ecd866318f3a to your computer and use it in GitHub Desktop.
mod-sig-chk.sh is a script to check the kernel modules signatures against a cert. mod-sig-chk.py is a helper, called by mod-sig-chk.sh, to extract the actual signature data for verification. mod-sig-chk.py should be in the user's home (~/) directory.
#!/usr/bin/env python
import struct
import sys
magic = "~Module signature appended~\n"
magic_len = len(magic)
PKEY_ID_PKCS7 = 2
mod_name = sys.argv[1]
f = open(mod_name, 'rb')
mod = f.read()
f.close()
mod_len = len(mod)
magic_idx = mod.find(magic)
if magic_idx == -1:
print "Module is not signed?"
sys.exit(1)
if mod[-magic_len:] != magic:
print "Module magic not at end of file?"
sys.exit(1)
mod_sig_len = 12
mod_sig_idx = magic_idx - mod_sig_len
module_signature = struct.unpack(">BBBBB3BL", mod[mod_sig_idx:magic_idx])
for i in [0,1,3,4,5,6,7]:
if module_signature[i] != 0:
print "module_signature[i] doesn't match %d != 0" % module_signature[i]
if module_signature[2] != PKEY_ID_PKCS7:
print "module_signature[2] doesn't match %d != PKEY_ID_PKCS7(2)" % module_signature[2]
sig_len = module_signature[8]
sig_idx = mod_sig_idx - sig_len
#print "%06x %06x %06x %06x %s" % ( sig_idx, mod_sig_idx, magic_idx, mod_len, mod_name)
#sig = mod[sig_idx:sig_idx+sig_len]
f = open(mod_name+".sigdata", "wb")
f.write(mod[sig_idx:sig_idx+sig_len])
f.close()
#data = mod[:sig_idx]
f = open(mod_name+".data", "wb")
f.write(mod[:sig_idx])
f.close()
#!/bin/bash -ue
# To check all kernel modules in a directory:
# find .../rootfs -name "*.ko" | xargs -n1 $0 .../$cert
verbose=
if [ "${1:-}" = "-v" ]; then
verbose=1
shift
fi
cert=${1:-}
mod=${2:-}
if [ ! -r "$cert" ] || [ ! -r "$mod" ] ; then
echo "Usage: $0 signing_key module.ko"
echo " maybe \`find .../rootfs/lib/modules -name '*.ko' | xargs -n1 $0 .../\$cert\`"
echo " to check all kernel modules in an image."
exit 1
fi
~/mod-sig-chk.py "${mod}"
data="${mod}.data"
sigdata="${mod}.sigdata"
keyform=DER
grep -q -- "-----BEGIN CERTIFICATE-----" $cert && keyform=PEM
#openssl asn1parse -inform der -in ${sigdata}
hash=$( openssl asn1parse -inform der -in ${sigdata} | tail -n 1 )
hash=$( echo ${hash} | awk -F prim: '{ print $1 }' )
offset=$( echo ${hash} | cut -d: -f1 )
hdr_len=$( echo ${hash} | sed -e 's/.*hl=//' -e 's/ .*//' )
sig_size=$( echo ${hash} | sed -e 's/.*l=//' -e 's/ //g' )
sig_hash=$( dd if=${sigdata} bs=1 skip=$(( offset + hdr_len )) count=${sig_size} status=none |
openssl rsautl -verify -certin -keyform $keyform -inkey ${cert} |
openssl asn1parse -inform der |
tail -n 1 |
sed -e 's/.*HEX DUMP.://' |
tr 'A-F' 'a-f' )
data_hash=$( sha384sum ${data} | awk '{ print $1 }' )
if [ "${sig_hash}" != "${data_hash}" ] ; then
echo "hash mismatch - $( basename $mod )"
echo "${sig_hash} signature value"
echo "${data_hash} data value"
else
[ -n "$verbose" ] && echo "${sig_hash} hashes match"
fi
rm ${data}
rm ${sigdata}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment