You are not logged in.

#1 2019-08-30 19:06:20

sinatosk
Member
Registered: 2010-11-28
Posts: 107

[SOLVED] Loading signed kernel modules using public keys from UEFI

I've been reading on here about kernel module signing

I have UEFI secure boot setup with my own keys, however I'm not sure how I can get the kernel to use the public keys stored in my UEFI firmware

it does says on the link I provided earlier that

Further, the architecture code may take public keys from a hardware store and add those in also (e.g. from the UEFI key database).

and searching around I see some documentation/articles about how Red Hat Enterprise can do this

Do I have to do something specfic to the kernel or something to use the keys from UEFI firmware. I don't see any information on this

and pointers/advice?

thanks

Last edited by sinatosk (2019-08-31 10:54:42)

Offline

#2 2019-08-30 19:42:47

merlock
Member
Registered: 2018-10-30
Posts: 158

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

While I did not get any farther into this than signing modules/dkms modules (in Manjaro), these should help you.


https://wiki.archlinux.org/index.php/Secure_Boot

http://chrisarges.net/2016/03/25/signed … y-key.html

https://www.rodsbooks.com/efi-bootloade … ng-sb.html


It's a big club...and you ain't in it -- George Carlin
Eenie meenie, chili beanie, the spirits are about to speak -- Bullwinkle J. Moose
Registered Linux user #149839
perl -e 'print$i=pack(c5,(41*2),sqrt(7056),(unpack(c,H)-2),oct(115),10); '

Offline

#3 2019-08-30 19:53:13

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

none of these helped this is not related to what I want

I want the kernel to read the public keys from UEFI firmware and use those

Offline

#4 2019-08-30 19:57:48

loqs
Member
Registered: 2014-03-06
Posts: 13,008

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

Is the key you added to the EFI not in the .system_keying?

https://access.redhat.com/documentation … -key-rings

Offline

#5 2019-08-30 20:00:59

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

no and when I run the command using sudo or loggin in as root via "su" command

# keyctl list %:.system_keyring

it says

Can't find 'keyring:.system_keyring'

ofcourse that keyring doesn't exist but I thought the kernel automatically created this or I'm missing something?

Last edited by sinatosk (2019-08-30 20:02:29)

Offline

#6 2019-08-30 20:06:13

loqs
Member
Registered: 2014-03-06
Posts: 13,008

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

# keyctl list %:.builtin_trusted_keys

If you are using the linux package from the repositories the randomly generated key embedded in the kernel should be listed.
Edit:
keyring names were changed in 4.7 https://github.com/torvalds/linux/commi … 3d161d01c9
and the in kernel documentation fixed in 4.17 https://github.com/torvalds/linux/commi … 3b55613dcb

Last edited by loqs (2019-08-30 20:13:50)

Offline

#7 2019-08-30 20:13:11

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

yeah, thats in there but thats the auto generated during kernel compile/build

I would like the kernel to read the public keys from UEFI firmware too and I'm under the impression that it can based on the documentation I read from kernel.org and red hat website

Offline

#8 2019-08-30 20:19:06

loqs
Member
Registered: 2014-03-06
Posts: 13,008

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

I agree with your understanding provided the system is booting in EFI mode with secure boot enabled then the EFI keys should be added to the keyring by the kernel.

Offline

#9 2019-08-30 20:21:54

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

loqs wrote:
# keyctl list %:.builtin_trusted_keys

If you are using the linux package from the repositories the randomly generated key embedded in the kernel should be listed.
Edit:
keyring names were changed in 4.7 https://github.com/torvalds/linux/commi … 3d161d01c9
and the in kernel documentation fixed in 4.17 https://github.com/torvalds/linux/commi … 3b55613dcb

if I understand this correctly

my system is in EFI mode and secure boot enabled and using my custom public/private key on the kernel

and doing a

zcat /proc/config.gz | grep CONFIG_SECONDARY_TRUSTED_KEYRING

which returns

CONFIG_SECONDARY_TRUSTED_KEYRING=y

that means my UEFI public keys should show in "builtin_trusted_keys", but... they ain't... hmmm

edit: thanks for digging this up by the way, great stuff

Last edited by sinatosk (2019-08-30 20:24:15)

Offline

#10 2019-08-30 20:39:17

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

looking in arch linux kernel config I'm seeing this

#
# Certificates for signature checking
#
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_SYSTEM_TRUSTED_KEYS=""
# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set
CONFIG_SECONDARY_TRUSTED_KEYRING=y
CONFIG_SYSTEM_BLACKLIST_KEYRING=y
CONFIG_SYSTEM_BLACKLIST_HASH_LIST=""
# end of Certificates for signature checking

and this looks correct to me as I should be seeing my keys, but I ain't... and I don't know why

Offline

#11 2019-08-30 22:42:25

progandy
Member
Registered: 2012-05-17
Posts: 4,143

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

The kernel detects that secure boot is enabled?

dmesg | grep -i secure

Edit: I think the kernel has changed handling of platform keys again. Now you probably need CONFIG_INTEGRITY_PLATFORM_KEYRING, but that only works for kexec images. Modules can only be verified against the secondary keyring, not the platform keyring. Keys can only be added to the secondary keyring by root if those keys are signed by a key the kernel already trusts in the primary or secondary keyring. I don't know if a patch would be accepted to allow platform keys as module signatures.

https://github.com/torvalds/linux/blob/ … ning.c#L81
https://github.com/torvalds/linux/blob/ … ing.c#L204
https://github.com/torvalds/linux/blob/ … y/digsig.c
https://github.com/torvalds/linux/blob/ … efi.c#L118
https://github.com/torvalds/linux/blob/ … ity.h#L237

Last edited by progandy (2019-08-30 23:17:29)


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#12 2019-08-31 05:10:10

loqs
Member
Registered: 2014-03-06
Posts: 13,008

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

Offline

#13 2019-08-31 07:03:04

progandy
Member
Registered: 2012-05-17
Posts: 4,143

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

This will never be upstream, so there is currently no way to add signed modules without recompiling the kernel I think. Or is there a way to add a key to an already compiled kernel?
https://lore.kernel.org/lkml/1556221605 … rship.com/

Last edited by progandy (2019-08-31 07:17:34)


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#14 2019-08-31 07:12:28

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

Just woke up

I would prefer it to use just KEK, db and dbx keys

I'm also assuming that it will at the dbx keys to the blacklist and ofcourse linux will refuse those that are part of the blacklist

edit: just looking at the links provided by progandy

Last edited by sinatosk (2019-08-31 07:19:38)

Offline

#15 2019-08-31 07:24:38

progandy
Member
Registered: 2012-05-17
Posts: 4,143

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

Without recompiling the kernel with the patch mentioned by loqs you cannot do that.


You could ask for the arch kernel to reserve some space in the system keyring where you can insert your own key into the kernel binary itself without recompiling. It doesn't do that, yet.
https://github.com/torvalds/linux/commi … 6e5bbde772

Last edited by progandy (2019-08-31 07:25:21)


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#16 2019-08-31 08:32:44

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

I might be wrong but after looking at some of the links you've provided on post 11

I eventually found CONFIG_LOAD_UEFI_KEYS here which depends on a kernel module "integrity" which is not included in the arch linux kernel

I'll recompile the kernel ( I normally do anyway ) to include the module and see if that works

Offline

#17 2019-08-31 10:10:04

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

ok, while I havn't tried signing any modules yet the public keys are now showing from UEFI variable "db" and the contents from "dbx" are stored in linux kernel blacklist

this is what I set in my kernel config

CONFIG_INTEGRITY=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
CONFIG_INTEGRITY_TRUSTED_KEYRING=y
CONFIG_INTEGRITY_PLATFORM_KEYRING=y
CONFIG_LOAD_UEFI_KEYS=y
CONFIG_INTEGRITY_AUDIT=y
# CONFIG_IMA is not set
# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set
# CONFIG_EVM is not set
CONFIG_SIGNATURE=y

to get them to show

thanks for your pointers progandy and loqs

Last edited by sinatosk (2019-08-31 10:54:14)

Offline

#18 2019-08-31 20:48:49

sinatosk
Member
Registered: 2010-11-28
Posts: 107

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

While not related to this post but was my next step after this post

progandy, I've been unable to get the kernel to use platforms key against the modules and everything you said in post 11 is true after looking through the code...

I've tried linking the keys using keyctl but failed due to permission problems ( denied )

I don't know why they changed it like this

the patch that loqs posted on post 12 ( I've not tried this yet ) seems like the only way I can get the modules verified by my platform keys

I wonder what red hat will do here in the future

Offline

#19 2019-08-31 21:12:21

progandy
Member
Registered: 2012-05-17
Posts: 4,143

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

If the kernel is compiled with SYSTEM_EXTRA_CERTIFICATE, then it is possible to embed one certificate into the builtin keyring of an already compiled kernel with the program linked in #15. Then you can use keyctl to add additional keys to the secondary keyring if they are signed with this "extra certificate". I believe you could add your uefi owner certificate here (not the private key!) with insert-sys-cert and then import the signed db keys with keyctl, but I don't know if those key and signature formats are easily compatible.

As for why they changed it, that is mentioned in the link in post #13.

Last edited by progandy (2019-08-31 21:17:57)


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#20 2020-04-26 11:51:44

singeinfini
Member
Registered: 2020-04-11
Posts: 4

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

Thanks to your replies I was able to successfully load signed modules using a certificate of my own, like the one containing my EFI public key. Since this could be useful to someone else, here are the steps I followed:

1. Build an ABS kernel with CONFIG_SYSTEM_TRUSTED_KEYS set to your X.509 PEM-encoded certificate:

$ sed -i '/^CONFIG_SYSTEM_TRUSTED_KEYS/{s#=.*#="/path/to/your/pub.crt"#}' config
$ updpkgsums

$ makepkg -s (this will take long!)

2. Install the newly created kernel package, along with the kernel headers package.

3. Configure DKMS so it can handle the signature process as part of the module installation. Here I use the following configuration (based on https://wiki.archlinux.org/index.php/Si … el_modules):

/etc/dkms/signature.conf
POST_BUILD=../../../../../../etc/dkms/module-sign.sh
/etc/dkms/module-sign.sh
#!/bin/bash
cd "../${kernelver}/${arch}/module/" || exit 1
SIGN="/usr/lib/modules/${kernelver}/build/scripts/sign-file"
if [ -f "${SIGN}" ]; then
  [ ! -d ./tmp ] && mkdir ./tmp
  shopt -s nullglob
  for mod in ./*.ko ./*.ko.xz; do
    mod_tmp="./tmp/${mod#./}"
    cp -a "${mod}" "${mod_tmp}"
    if [ "${mod##*.}" = "xz" ]; then
      xz -f --decompress "${mod_tmp}"
      isxz=1
      mod_tmp="${mod_tmp%*.xz}"
    fi
    if grep -Eq "^signature:" < <(modinfo "${mod_tmp}"); then
      echo "Removing old sig"
      strip "${mod_tmp}"
    fi
    echo "DKMS: Signing kernel (${kernelver}) module: ${mod}"
    $SIGN sha512 /path/to/your/private.key /path/to/your/pub.crt "${mod_tmp}"
    if test -v isxz; then
      xz -f ${mod_tmp} 
      mod_tmp="${mod_tmp}.xz"
    fi
    mv "${mod_tmp}" "${mod}"
  done
fi

4. Use dkms along with the DKMS variant of the modules packages you need, so they can be recompiled and signed for your new kernel. To do so, for each module package, make a soft link to the configuration file:

# cd /etc/dkms
# ln -s signature.conf package_name.conf

then execute:

# dkms install -m module_name -v module_version -k kernel_version

5. Reboot to your new kernel.
The command keyctl show -x %:.builtin_trusted_keys should display the public key you added in the kernel trusted keyring.

Then you would be able to use modules.sig_enforce=1 in your kernel command line, kernel lockdown features as well smile

PS: sorry for my bad english
PS2: post edited as I realized that CONFIG_SYSTEM_EXTRA_CERTIFICATE would not be necessary in this situation.

Last edited by singeinfini (2020-04-26 21:51:05)

Offline

#21 2021-01-09 19:26:07

CyrIng
Member
From: France
Registered: 2010-07-17
Posts: 90
Website

Re: [SOLVED] Loading signed kernel modules using public keys from UEFI

Thank you for your explanation.

So you mean that all kernel modules have to be unsigned first, then signed again with personal key, and put back in the kernel directories tree ?

I believe your whole procedure has to be applied even for a single out of tree module, isn't it ?

singeinfini wrote:

Thanks to your replies I was able to successfully load signed modules using a certificate of my own, like the one containing my EFI public key. Since this could be useful to someone else, here are the steps I followed:

1. Build an ABS kernel with CONFIG_SYSTEM_TRUSTED_KEYS set to your X.509 PEM-encoded certificate:

$ sed -i '/^CONFIG_SYSTEM_TRUSTED_KEYS/{s#=.*#="/path/to/your/pub.crt"#}' config
$ updpkgsums

$ makepkg -s (this will take long!)

2. Install the newly created kernel package, along with the kernel headers package.

3. Configure DKMS so it can handle the signature process as part of the module installation. Here I use the following configuration (based on https://wiki.archlinux.org/index.php/Si … el_modules):

/etc/dkms/signature.conf
POST_BUILD=../../../../../../etc/dkms/module-sign.sh
/etc/dkms/module-sign.sh
#!/bin/bash
cd "../${kernelver}/${arch}/module/" || exit 1
SIGN="/usr/lib/modules/${kernelver}/build/scripts/sign-file"
if [ -f "${SIGN}" ]; then
  [ ! -d ./tmp ] && mkdir ./tmp
  shopt -s nullglob
  for mod in ./*.ko ./*.ko.xz; do
    mod_tmp="./tmp/${mod#./}"
    cp -a "${mod}" "${mod_tmp}"
    if [ "${mod##*.}" = "xz" ]; then
      xz -f --decompress "${mod_tmp}"
      isxz=1
      mod_tmp="${mod_tmp%*.xz}"
    fi
    if grep -Eq "^signature:" < <(modinfo "${mod_tmp}"); then
      echo "Removing old sig"
      strip "${mod_tmp}"
    fi
    echo "DKMS: Signing kernel (${kernelver}) module: ${mod}"
    $SIGN sha512 /path/to/your/private.key /path/to/your/pub.crt "${mod_tmp}"
    if test -v isxz; then
      xz -f ${mod_tmp} 
      mod_tmp="${mod_tmp}.xz"
    fi
    mv "${mod_tmp}" "${mod}"
  done
fi

4. Use dkms along with the DKMS variant of the modules packages you need, so they can be recompiled and signed for your new kernel. To do so, for each module package, make a soft link to the configuration file:

# cd /etc/dkms
# ln -s signature.conf package_name.conf

then execute:

# dkms install -m module_name -v module_version -k kernel_version

5. Reboot to your new kernel.
The command keyctl show -x %:.builtin_trusted_keys should display the public key you added in the kernel trusted keyring.

Then you would be able to use modules.sig_enforce=1 in your kernel command line, kernel lockdown features as well smile

PS: sorry for my bad english
PS2: post edited as I realized that CONFIG_SYSTEM_EXTRA_CERTIFICATE would not be necessary in this situation.

Offline

Board footer

Powered by FluxBB