2

I am trying to boot a Linux kernel with efi stub enabled using Red Hat's Shim https://github.com/rhboot/shim.

I can boot the system if I enroll the hash of my efi stub (selecting GRUBX64.EFI), but shim says the system is compromised when i enroll its certificate. I'd like to use a certificate so I can update without having to re-enroll.

Error message on boot:

EFI stub: UEFI Secure Boot is enabled.
Bootloader has not verified loaded image.
System is compromised.  halting.

Shim version: 15.8-3, extracted from Fedora rpm (signed by Microsoft).

Compiling Linux 6.9.7 (Buildroot) with EFI_STUB=y. Outputs bzImage.

Adding SBAT using script from https://github.com/rhboot/shim/issues/376#issuecomment-1628004034:

pe-add-sections.py -s .sbat sbat.csv -z .sbat -i bzImage -o bzImage.sbat

where sbat.csv:

sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
rescue,1,ABC,rescue,1,https://example.com

Signing:

openssl req \
        -new -x509 -newkey rsa:2048 \
        -nodes -days 36500 -outform DER \
        -keyout "mok.priv" \
        -out "mok.der" \
        -subj "/CN=Rescue/"

openssl x509 -in mok.der -inform DER -outform PEM -out mok.pem

sbsign --key mok.priv --cert mok.pem --output bzImage.signed bzImage.sbat

Then using genimage (https://github.com/pengutronix/genimage) to create img:

# file genimage.cfg

image efi-part.vfat {
    vfat {
        file EFI/BOOT/BOOTX64.EFI {
            image = "shimx64.efi"
        }

        file EFI/BOOT/MMX64.EFI {
            image = "mmx64.efi"
        }

        file EFI/BOOT/GRUBX64.EFI {
            image = "bzImage.signed"
        }

        file MOK.DER {
            image = "mok.der"
        }
    }
    size = 16M
}

image disk.img {
    hdimage {
        partition-table-type = "gpt"
    }

    partition boot {
        image = "efi-part.vfat"
        partition-type-uuid = U
        offset = 32K
        bootable = true
    }
}
genimage -c genimage.cfg # Outputs disk.img

I have verified that GRUBX64.EFI isn't changed by genimage with sbverify --cert mok.pem GRUBX64.EFI

Tested by writing to USB (dd ...) and booting on Surface Go 2, and in the following vm, with the same results:

#!/bin/bash

set -Eeuxo pipefail

MACHINE_NAME="test"
SSH_PORT="5555"
OVMF_CODE="/usr/share/OVMF/OVMF_CODE_4M.ms.fd"
OVMF_VARS_ORIG="/usr/share/OVMF/OVMF_VARS_4M.ms.fd"
OVMF_VARS="$(basename "${OVMF_VARS_ORIG}")"

if [ ! -e "${OVMF_VARS}" ]; then
        cp "${OVMF_VARS_ORIG}" "${OVMF_VARS}"
fi

qemu-system-x86_64 \
        -enable-kvm \
        -cpu host -smp cores=1,threads=1 -m 4096 \
        -object rng-random,filename=/dev/urandom,id=rng0 \
        -device virtio-rng-pci,rng=rng0 \
        -name "${MACHINE_NAME}" \
    -drive format=raw,file="disk.img" \
        -net nic,model=virtio -net user,hostfwd=tcp::${SSH_PORT}-:22 \
        -vga virtio \
        -machine q35,smm=on \
        -drive if=pflash,format=raw,unit=0,file="${OVMF_CODE}",readonly=on \
        -drive if=pflash,format=raw,unit=1,file="${OVMF_VARS}" \
        -global driver=cfi.pflash01,property=secure,value=on \
        $@

I have tried signing with pesign, but it didn't make a difference:

#!/usr/bin/env bash

mkdir db
certutil -d db -N --empty-password

efikeygen -d db \
  --self-sign \
  --nickname='Rescue' \
  --common-name='CN=Rescue,OU=xxx,O=xxx,C=US'

certutil -d db -L -n "Rescue" -r > mok.der
pesign --force -s -n db -c "Rescue" -i bzImage.sbat -o bzImage.signed

What am I doing wrong?

1 Answer 1

1

Got it. There seem to be a special case for hash-enrolled stuff. Creating the image with ukify worked - almost - like a charm. Now I just need to deal with the warning: "Overlapping PE sections detected. Boot may fail due to image memory corruption!".

Edit: And that was solved by using the latest linuxx64.efi.stub. Now everything works!

#!/bin/bash

LINUX=bzImage
[email protected]
SB_PRIV_KEY=mok.priv
SB_PUB_KEY=mok.pem

ukify build \
        --linux "$LINUX" \
        --sbat "$SBAT" \
        --sign-kernel \
        --secureboot-private-key "$SB_PRIV_KEY" \
        --secureboot-certificate "$SB_PUB_KEY"

this creates bzImage.efi and that is bootable by Shim with an enrolled certificate.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.