[Guide] Fedora 36+: Hibernation with enabled secure boot and full disk encryption (fde) decrypting over tpm2

I’m having problems with pesign. Here are the error messages.

During the final steps of command time rpmbuild -bb --with baseonly --without debuginfo --target=$arch kernel.spec | tee ~/build-kernel.log:

/usr/bin/pesign-client -t ‘OpenSC Card (Fedora Signer)’ -c framework -s -i arch/x86/boot/bzImage -o vmlinuz.tmp
pesign-client: could not get response from server: Connection reset by peer
error: Bad exit status from /var/tmp/rpm-tmp.1nHlOb (%build)
Bad exit status from /var/tmp/rpm-tmp.1nHlOb (%build)

output of journalctl -xeu pesign:
Jan 17 15:27:25 framework pesign[115605]: searching for command 7
Jan 17 15:27:25 framework pesign[115605]: cmd-version: found command “sign-attached-with-file-type” version 0
Jan 17 15:27:25 framework pesign[115605]: unlock-token: invalid data
Jan 17 15:27:25 framework pesign[115605]: possible exploit attempt. closing.
Jan 17 15:27:25 framework pesign[115605]: unlock-token: invalid data
Jan 17 15:27:25 framework pesign[115605]: possible exploit attempt. closing.
Jan 17 15:27:25 framework pesign[115605]: attempting to sign with key “OpenSC Card (Fedora Signer):framework”
Jan 17 15:27:25 framework pesign[115605]: cms_common.c:find_certificate:625: Could not find token “OpenSC Card (Fedora Signer)”: Failure to load dynamic library

output of modutil -dbdir /etc/pki/pesign -list:

Listing of PKCS #11 Modules

  1. NSS Internal PKCS #11 Module
    uri: pkcs11:library-manufacturer=Mozilla%20Foundation;library-description=NSS%20Internal%20Crypto%20Services;library-version=3.87
    slots: 2 slots attached
    status: loaded

    slot: NSS Internal Cryptographic Services
    token: NSS Generic Crypto Services
    uri: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

    slot: NSS User Private Key and Certificate Services
    token: NSS Certificate DB
    uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

  2. p11-kit-proxy
    library name: p11-kit-proxy.so
    uri: pkcs11:library-manufacturer=PKCS%2311%20Kit;library-description=PKCS%2311%20Kit%20Proxy%20Module;library-version=1.1
    slots: There are no slots attached to this module
    status: loaded

#List of modules in pesign database:
certutil -d /etc/pki/pesign -U

slot: NSS User Private Key and Certificate Services

token: NSS Certificate DB
uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

slot: NSS Internal Cryptographic Services

token: NSS Generic Crypto Services
uri: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

After reading Fedora_RPM_pesign.md · GitHub

I modified the rpmbuild command to:

time rpmbuild -bb -D ‘pe_signing_token NSS Certificate DB’ -D ‘pe_signing_cert framework’ --with baseonly --without debuginfo --target=$arch kernel.spec | tee ~/build-kernel.log

It worked. I don’t know why rpmbuild defaults to token ‘OpenSC Card (Fedora Signer)’ though.

I’m curious how you got to level 3 in security. My default fedora install with secure boot stops at level 0 because Intel ME is disabled.

I have one other question. Since your’e using TPM to handle luks encryption, what happens if the device breaks? Can you backup the decryption keys so you can remount the drive in another device and recover the data?

How?

You can set up a recovery key using systemd-cryptenroll or choose not to wipe the passcode set when LUKS encrypted the drive. The man page has more details

1 Like

At least on (some) 11th gen models (not sure about 11th gen 1185g7), ME firmware needs to be upgraded with a BIOS update. Beyond that, only vPRO models can handle encrypted RAM/etc for level 3 afaik

1 Like

This is fantastic, thank you so much! :cowboy_hat_face:

One question: Given you have to patch the kernel, what do you do when a new version is available? Do you just avoid updating the kernel, or is there a streamlined approach to make the patch persist between upgrades?

No, not yet. I just recompile the kernel with the patch and install it. Actually, I just run these commands. With my streamlined kernel configuration, the compiling takes about half an hour on an 12th generation board.

### Set variables
export arch=x86_64
export ver=6.1
export minrel=7
export pkgrel=200
export subver=$minrel-$pkgrel
export fedver=fc37
export name=$(hostname)

### Setup build system
rpmdev-setuptree
koji download-build --arch=src kernel-$ver.$subver.$fedver
rpm -Uvh kernel-$ver.$subver.$fedver.src.rpm
cd ~/rpmbuild/SPECS

### Apply patches and customize kernel configuration
# Get patch to enable hibernate in lockdown mode (secure boot)
wget https://gist.githubusercontent.com/kelvie/917d456cb572325aae8e3bd94a9c1350/raw/74516829883c7ee7b2216938550d55ebcb7be609/0001-Add-a-lockdown_hibernate-parameter.patch -O ~/rpmbuild/SOURCES/0001-Add-a-lockdown_hibernate-parameter.patch
# Define patch in kernel.spec for building the rpms
# Patch2: 0001-Add-a-lockdown_hibernate-parameter.patch
sed -i '/^Patch999999/i Patch2: 0001-Add-a-lockdown_hibernate-parameter.patch' kernel.spec
# Add patch as ApplyOptionalPatch
sed -i '/^ApplyOptionalPatch linux-kernel-test.patch/i ApplyOptionalPatch 0001-Add-a-lockdown_hibernate-parameter.patch' kernel.spec
sed -i "s/# define buildid .local/%define buildid .$name/g" kernel.spec
sed -i "s/.$name/.$name\n%define pe_signing_cert $name/g" kernel.spec
# Copy currently running, customized and streamlined configuration (see first post how to customize)
cp /boot/config-$(uname -r) ~/rpmbuild/SOURCES/kernel-local
# Remove build infos from custom config
sed -i '0,/^#\ General\ setup$/d' ~/rpmbuild/SOURCES/kernel-local
sed -i '1i # x86_64' ~/rpmbuild/SOURCES/kernel-local

### Compile kernel
cd ~/rpmbuild/SPECS
time rpmbuild -bb --with baseonly --without debuginfo --target=$arch kernel.spec | tee ~/build-kernel.log

### Install kernel
cd ~/rpmbuild/RPMS/$arch/
sudo dnf install *.rpm

The needed patch worked with kernel version 6.0 and still works with 6.1. I hope, the author will adapt it when needed so, otherwise I’ll probably just adapt it myself (and post it here).

1 Like

This is great! Thank you so much for all this documentation. I’m going to try setting this up this weekend.

I updated my personal kernel configuration (version 6.1.9). Now it takes about fifteen minutes to compile the kernel. Check out my streamlined kernel configuration for frame.work. Copy this file to ~/rpmbuild/SOURCES/kernel-local to get a streamlined kernel for the frame.work notebook. You probably want to customize/enable more device drivers depending your needs …

Amazing work ! Thank you so much for your time !
Are we going to have to perform these steps on every kernel version or is the fedora project going to add/work on these to the next kernel version ?

@Raining-characters I don’t think they are going to work on it at all. This is all a hack to circumvent kernel lockdown. As far as Fedora is concerned, the lack of working hibernation means everything is working as intended.

1 Like

Hey everyone, I’m the person that wrote the hibernation / lockdown mode patch for the kernel (did not know anyone else knew about it, I’ve only posted it to an obscure question in stack exchange), and have been using it by modifying the linux pkgbuild on arch for quite some time now.

It looks like it’s not just me that wants this, maybe we should take it up with the kernel devs on their mailing list?

5 Likes

@Kelvie - Thanks for your solution. It would be awesome if that feature would take place in a kernel! Just to know it, how would that work? ; )
But found a reddit post that describes why it shouldn’t be an activated feature for all:
https://www.reddit.com/r/Fedora/comments/r4a4so/interesting_fedora_does_not_support_hibernation/

2 Likes

@Kelvie, it would be awesome to have the patch in the official kernel, but I don’t know the way how to get it there but I have I slight doubt if it will get accepted looking at the effort it needs to get it “working”.

At least some of these points shouldn’t matter anymore if you enabled encrypted ram which is possible with frame.work.

Btw, the patch is still working with kernel version 6.3.8! :raised_hands:

Yes, you are right. I mean it more in that way, that adding those kernel features, seems unlikely, cause they deliver to all devices.

Maybe git repo, with a pipeline that add’s needed stuff and bundle the kernel could be a good solution to run over time?

Just mention it, cause it could be a little bit annoying to recompile and reconfigure hibernation from time to time…
PS.: At least my setup seems to need my attention again after the last patches… ; )

As an addition, check out this nice write-up for tpm2 decription: https://community.frame.work/t/guide-setup-tpm2-autodecrypt

Just in case, I adapted the kernel patch to be compatible with kernel version 6.7.x: Enable hibernate during lockdown · GitHub

I’m a fedora noob and would appreciate some help. I’m running into issues applying the patch to my current kernel (6.7.4-200). After finishing the wget, then sed lines and trying to run rpmbuild it seems there are some errors introduced.
I get:

sam@fedora:~/rpmbuild/SPECS$ time rpmbuild -bb --with baseonly --without debuginfo --target=$arch kernel.spec | tee ~/build-kernel.log
error: parse error in expression:  0%{.fedora
error:                              ^
error: /home/sam/rpmbuild/SPECS/kernel.spec:99: bad %if condition:  0%{.fedora
Building target platforms: x86_64
Building for target x86_64

real	0m0.021s
user	0m0.011s
sys	0m0.011s

Looking at the original spec file it looks like alot of the 0%{?fedora} lines are being mangled changed but I’m not knowledgeable enough to go through the whole spec and fix them myself. Am I doing something wrong?