Installing Realtek 8821ce driver on system with SecureBoot enabled

I decided to get a new laptop in response to the current pandemic situation, with the intent to work from home. WiFi is a nice feature to have on a laptop, unfortunately only drivers for Windows are readily available for the built-in Realtek wireless chip. There is no upstream kernel module available in Fedora 31 (Linux 5.5.10), but there is an out of tree project implementing the driver. Because of this we need a locally signed kernel module if we wish to keep SecureBoot enabled, something I'd prefer to maintain.

With SecureBoot enabled, loading a kernel module will require Dynamic Kernel Module Signing, since we're in lockdown (this isn't easily bypassable anymore) and unsigned module loading is restricted. This guide will explain how to get, install, sign and load the Realtek 8821ce Linux kernel module.

Hardware

Asus TUF FX505DT (AMD Ryzen 5, Realtek rtl8821ce wireless)

OS

  • Fedora 31
  • Windows 10 (Dualboot)

Valuable docs

Fedora Sysadmin Guide

This reddit post

Prerequisites

Root access
Most things in this guide, except git checkout, requires root privileges.

Needed packages

  • openssl - Provided by package: openssl
  • sign-file - Provided by package: kernel-devel
  • mokutil - Provided by package: mokutil
  • keyctl - Provided by package: keyutils
  • make - Provided by package: make
  • dkms - provided by package: dkms
  • kernel-devel - provided by package: kernel-devel
  • gcc - provided by package: gcc
  • git - provided by package: git
Install all of it
$ dnf install dkms gcc git kernel-devel keyutils make mokutil openssl

Steps

Get root
$ sudo -i
Check if SecureBoot is enabled
$ mokutil --sb-state
SecureBoot enabled
Get the driver
$ git clone https://github.com/tomaspinho/rtl8821ce
Install the driver
$ cd rtl8821ce
$ bash ./dkms-install.sh
$ make
$ make install
Generate an X.509 Key Pair
Use openssl to generate a key pair for kernel module signing in Fedora:

Create a configuration file for key generation

$ cat << EOF > configuration_file.config
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts

[ req_distinguished_name ]
O = Organization
CN = Organization signing key
emailAddress = E-mail address

[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
EOF
Generate the key pair
$ openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 -batch -config configuration_file.config -outform DER -out public_key.der -keyout private_key.priv
Enrol the public key
Manually add public key to MOK List
$ mokutil --import public_key.der

You will be asked to enter and confirm a password for this MOK enrolment request. I suggest that you do not go ham on special chars, as MokManager.efi defaults to English keyboard layout, separate from the Fedora settings.

Reboot the machine
$ reboot

This should open MokManager.efi before booting into Fedora again. Complete the enrolment, which will include entering the previously set password

Verify that the key is on the system key ring
$ keyctl list %:.builtin_trusted_keys
Sign the kernel module with your private key

Assuming you're in the directory where you generated your keys:

$ /usr/src/kernels/$(uname -r)/scripts/sign-file sha256 private_key.priv public_key.der /lib/modules/$(uname -r)/kernel/drivers/net/wireless/8821ce.ko

(Use the absolute path at least for the .ko file, if you're not in the directory with the keys you will obviously need to specify their path more thoroughly)

Load the now signed Kernel Module
Load the kernel module
$ modprobe -v 8821ce

If you're failing to load the module, it's reasonable to suspect a failure to sign the module. Check the output of dmesg:

$ dmesg
[ 5880.506791] Lockdown: modprobe: unsigned module loading is restricted; see man kernel_lockdown.7

Fedora should recognise the wireless card and present you with WiFi settings.

Enjoy a less isolated quarantine!

Release v3.30

Release v3.29

Release v3.28