< All posts

Oct. 18, 2023, 12:35 p.m.

Installing NVIDIA GPU Drivers on Debian 12 GNU/Linux with Secure Boot Enabled

This guide will help you install the Nvidia Drivers to your Debian 12 GNU/Linux distribution with Secure Boot enabled Laptop or Deskop. You need root access to your device and internet connection.

A. Installation of Drivers

First, we need to identify which GPU we have by executing the following in a shell:

$ lspci -nn | egrep -i "3d|display|vga"

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA107M [GeForce RTX 3050 Ti Mobile] [10de:25a0] (rev a1)

To identify which driver we need, install and execute nvidia-detect first:

$ sudo apt update
$ sudo apt install nvidia-detect

Detected NVIDIA GPUs:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA107M [GeForce RTX 3050 Ti Mobile] [10de:25a0] (rev a1)

Checking card:  NVIDIA Corporation GA107M [GeForce RTX 3050 Ti Mobile] (rev a1)
Your card is supported by all driver versions.
Your card is also supported by the Tesla drivers series.
Your card is also supported by the Tesla 470 drivers series.
It is recommended to install the
    nvidia-driver
package.

Based on the output above, we just need to install the meta package nvidia-driver:

$ sudo apt install nvidia-driver
....
Building for 6.1.0-13-amd64
Building initial module for 6.1.0-13-amd64
Done.

nvidia-current.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/6.1.0-13-amd64/updates/dkms/

nvidia-current-modeset.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/6.1.0-13-amd64/updates/dkms/

nvidia-current-drm.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/6.1.0-13-amd64/updates/dkms/

nvidia-current-uvm.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/6.1.0-13-amd64/updates/dkms/

nvidia-current-peermem.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/6.1.0-13-amd64/updates/dkms/
depmod...
Setting up nvidia-driver (525.125.06-1~deb12u1) ...
Processing triggers for libc-bin (2.36-9+deb12u3) ...
Processing triggers for initramfs-tools (0.142) ...
update-initramfs: Generating /boot/initrd.img-6.1.0-13-amd64
Processing triggers for update-glx (1.2.2) ...
Processing triggers for glx-alternative-nvidia (1.2.2) ...
update-alternatives: using /usr/lib/nvidia to provide /usr/lib/glx (glx) in auto mode
Processing triggers for glx-alternative-mesa (1.2.2) ...
Processing triggers for libc-bin (2.36-9+deb12u3) ...
Processing triggers for initramfs-tools (0.142) ...
update-initramfs: Generating /boot/initrd.img-6.1.0-13-amd64

You may be asked to restart the system, since by default the free driver nouveau will be disabled from the system.
Before you restart, we need to sign the kernel modules of the driver for this to work under Secure Boot.
Alternatively, you may just disable Secure Boot whenever you want to boot to Linux and enable it again when using Windows (if you dual boot).
CAUTION: Disabling Secure Boot will trigger Bitlocker Policy Change and will require to enter the Bitlocker recovery key.

B. Signing the Nvidia kernel module with our own key

This assumes that we have Secure Boot enabled, by default the Nvidia driver will not work on a secure boot enabled machine. We need to sign the kernel module for it to work under Secure Boot (SB).

We can determine the current state of secure boot doing the following:

$ sudo mokutil --sb-state

SecureBoot enabled

To generate a new key, execute the commands below:

$ sudo apt install sbsigntool
$ sudo mkdir -p /var/lib/shim-signed/mok/
$ sudo cd /var/lib/shim-signed/mok/
$ sudo openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -days 36500 -subj "/CN=My Name Here/"

Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

$ sudo openssl x509 -inform der -in MOK.der -out MOK.pem

Be sure to specify and remember the pass phrase of the key.

Enrolling the generated key to our system:

$ sudo mokutil --import /var/lib/shim-signed/mok/MOK.der
$ sudo mokutil --test-key /var/lib/shim-signed/mok/MOK.der

/var/lib/shim-signed/mok/MOK.der is already in the enrollment request

For the dkms to sign kernel modules automatically, we need to add the configuration values to the file: /etc/dkms/framework.conf.

$ sudo nano /etc/dkms/framework.conf

mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
mok_certificate="/var/lib/shim-signed/mok/MOK.der"

If the dkms does appear not sign the modules, we need to append the following to the same file /etc/dkms/framework.conf:

$ sudo nano /etc/dkms/framework.conf

sign_tool="/etc/dkms/sign_helper.sh"

Now, create the sign_helper script file.

$ sudo nano /etc/dkms/sign_helper.sh

/lib/modules/"$1"/build/scripts/sign-file sha512 /root/.mok/client.priv /root/.mok/client.der "$2"

Set the file be executable:

$ sudo chmod +x /etc/dkms/sign_helper.sh

Setting the environment variables:

$ VERSION="$(uname -r)"
$ SHORT_VERSION="$(uname -r | cut -d . -f 1-2)"
$ MODULES_DIR=/lib/modules/$VERSION
$ KBUILD_DIR=/usr/lib/linux-kbuild-$SHORT_VERSION

Signing the NVIDIA modules:

$ cd "$MODULES_DIR/updates/dkms"
$ echo -n "Passphrase for the private key: "

$ read -s KBUILD_SIGN_PIN
$ export KBUILD_SIGN_PIN

$ find -name \*.ko | while read i; do sudo --preserve-env=KBUILD_SIGN_PIN "$KBUILD_DIR"/scripts/sign-file sha256 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der "$i" || break; done
$ sudo update-initramfs -k all -u

Signing the kernel:

$ sbsign --key MOK.priv --cert MOK.pem "/boot/vmlinuz-$VERSION" --output "/boot/vmlinuz-$VERSION.tmp"
$ sudo mv "/boot/vmlinuz-$VERSION.tmp" "/boot/vmlinuz-$VERSION"

To confirm that we have signed the module, execute the following on the dkms directory:

$ cd "$MODULES_DIR/updates/dkms"
$ sudo  modinfo nvidia-current.ko

...
filename:       /lib/modules/6.1.0-13-amd64/updates/dkms/nvidia-current.ko
firmware:       nvidia/525.125.06/gsp_tu10x.bin
firmware:       nvidia/525.125.06/gsp_ad10x.bin
alias:          char-major-195-*
version:        525.125.06
supported:      external
license:        NVIDIA
srcversion:     XXX
alias:          pci:z
alias:          pci:x
alias:          pci:y
depends:        drm
retpoline:      Y
name:           nvidia
vermagic:       6.1.0-13-amd64 SMP preempt mod_unload modversions
sig_id:         PKCS#7
signer:         r1bnc
sig_key:        XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
sig_hashalgo:   sha256

We can now restart the machine.

Upon restart we will be prompted to add the key that we set up earlier:

MOKMGMT_10182023_01.png

MOKMGMT_10182023_02.png

MOKMGMT_10182023_03.png

After the restart, we should now be able to use the NVIDIA GPU with Secure Boot on:

$ sudo nvidia-smi


Wed Oct 18 12:33:46 2023       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.125.06   Driver Version: 525.125.06   CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0  On |                  N/A |
| N/A   43C    P8     4W /  60W |     38MiB /  4096MiB |     18%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1166      G   /usr/lib/xorg/Xorg                 37MiB |
+-----------------------------------------------------------------------------+

References:

https://wiki.debian.org/NvidiaGraphicsDrivers
https://wiki.debian.org/SecureBoot#Secure_Boot_limitations

Except where otherwise noted, this work is licensed under Creative Commons Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0/).