foundriesio / meta-lmp

Linux microPlatform Meta OpenEmbedded Layer
MIT License
38 stars 37 forks source link

meta-tegra use of TEGRA_UEFI_DB_* does not create signatures allowing UEFI to load syslinux.cfg #1203

Open mmitchel opened 1 year ago

mmitchel commented 1 year ago

Following a flashing with the TEGRA_UEFI_DB* variables set, it appears that the built edk2-firmware-tegra refuses to load syslinux.cfg due to a missing signature. UEFI_SIGN_ENABLE being set in local.conf does not produce a detached signature either. Relevant to local.conf:

UEFI_SIGN_ENABLE = "1"
TEGRA_UEFI_DB_KEY = "${UEFI_SIGN_KEYDIR}/DB.key"
TEGRA_UEFI_DB_CERT = "${UEFI_SIGN_KEYDIR}/DB.crt"

Output from the boot console:

L4TLauncher: Attempting Direct Boot
OpenAndReadUntrustedFileToBuffer: Failed to open boot\loader\syslinux.cfg.sig: Not Found
ProcessExtLinuxConfig:sds Failed to Authenticate boot\loader\syslinux.cfg (Not Found)
L4TLauncher: Unable to process extlinux config: Not Found
L4TLauncher: Attempting Kernel Boot
Header not seen at either offset 0 or offset 0x1000
Failed to boot kernel:0 partition

generation of dtbo for UEFI with tegra-uefi-keys-dtb.bbappend

require recipes-bsp/tegra-binaries/tegra-binaries-35.3.1.inc
require recipes-bsp/tegra-binaries/tegra-shared-binaries.inc

PV = "${L4T_VERSION}"
PR = "r0"

DEPENDS = "dtc-native efitools-native python3-native tegra-binaries util-linux-native"

do_configure () {
    [[ -n "${UEFI_SIGN_KEYDIR}" ]] || bbfatal "UEFI_SIGN_KEYDIR is not set"
    [[ -n "${TEGRA_UEFI_DB_KEY}" ]] || bbfatal "TEGRA_UEFI_DB_KEY is not set"
    [[ -n "${TEGRA_UEFI_DB_CERT}" ]] || bbfatal "TEGRA_UEFI_DB_CERT is not set"
    install -t ${B} \
        ${UEFI_SIGN_KEYDIR}/PK.key ${UEFI_SIGN_KEYDIR}/PK.crt \
        ${UEFI_SIGN_KEYDIR}/KEK.key ${UEFI_SIGN_KEYDIR}/KEK.crt \
        ${UEFI_SIGN_KEYDIR}/DB.key ${UEFI_SIGN_KEYDIR}/DB.crt
}

do_compile () {
    cat > ${B}/uefi_keys.conf <<EOF
UEFI_PK_KEY_FILE="PK.key";
UEFI_PK_CERT_FILE="PK.crt";
UEFI_KEK_KEY_FILE="KEK.key";
UEFI_KEK_CERT_FILE="KEK.crt";
UEFI_DB_1_KEY_FILE="DB.key";
UEFI_DB_1_CERT_FILE="DB.crt";
EOF
    ${S}/tools/gen_uefi_default_keys_dts.sh ${B}/uefi_keys.conf
}

do_install[noexec] = "1"

do_deploy () {
    install -d ${DEPLOYDIR}
    install -m 0644 -t ${DEPLOYDIR} ${B}/UefiDefaultSecurityKeys.dtbo
}
ricardosalveti commented 1 year ago

Yeah, this is an issue by the way nvidia is performing secure boot in UEFI, which requires signed files for all the used components, including syslinux.cfg, which won't work out of the box with ostree.

This is just because ostree itself is the one creating and updating that file when a deployment is made, so for this file to be signed and updated the keys would also need to be available at runtime, which is not really a solution.

My thinking here (and something meta-tegra folks also raised in the past) is that we should instead move to something more standard here, relying on systemd-boot + unified kernel images instead, but that still requires integration work.

So for now, if you want to be able to load signed kernel/initrd following the tegra progress my suggestion would be to disable the syslinux.cfg check in the L4TLauncher application, until a better solution can be integrated.

mmitchel commented 1 year ago

So essentially, would it be possible to generate the signature following whatever the ostree layer does? I am slightly lost in the lmp layers where syslinux.cfg is actually created. In the meta-tegra, they have a recipe that puts it together, and drops it into the bootloader directory of Linux_for_Tegra. The signing tool picks it up from there.

Actually, I was thinking about attempting a patch on libostree in the syslinux bootloader to just look for extlinux.conf in the usual space. It would be signed and picked up by the tegra tools.

Maybe you could answer this quick question about systemd-boot: Won’t it have the same limitations of needing properly signed files before UEFI will allow access to them if they are in the ESP?

Sent from Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 for Windows

From: Ricardo @.> Sent: Thursday, June 29, 2023 10:15 AM To: @.> Cc: Michael @.>; @.> Subject: Re: [foundriesio/meta-lmp] meta-tegra use of TEGRA_UEFIDB* does not create signatures allowing UEFI to load syslinux.cfg (Issue #1203)

Yeah, this is an issue by the way nvidia is performing secure boot in UEFI, which requires signed files for all the used components, including syslinux.cfg, which won't work out of the box with ostree.

This is just because ostree itself is the one creating and updating that file when a deployment is made, so for this file to be signed and updated the keys would also need to be available at runtime, which is not really a solution.

My thinking here (and something meta-tegra folks also raised in the past) is that we should instead move to something more standard here, relying on systemd-boot + unified kernel images instead, but that still requires integration work.

So for now, if you want to be able to load signed kernel/initrd following the tegra progress my suggestion would be to disable the syslinux.cfg check in the L4TLauncher application, until a better solution can be integrated.

— Reply to this email directly, view it on GitHubhttps://github.com/foundriesio/meta-lmp/issues/1203#issuecomment-1613364154, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAA6QI3OBXJQHIPSV5UV6XTXNWLZZANCNFSM6AAAAAAZYNSKGI. You are receiving this because you authored the thread.Message ID: @.***>

ricardosalveti commented 1 year ago

So essentially, would it be possible to generate the signature following whatever the ostree layer does? I am slightly lost in the lmp layers where syslinux.cfg is actually created.

That's because libostree is the one creating it when the deployment is made out of the rootfs build process.

https://github.com/uptane/meta-updater/blob/master/classes/image_types_ota.bbclass#L24 is needed as a way to "configure" ostree to generate a syslinux.cfg file (they support syslinux as a standard, and not extlinux), and you can inspect that file by doing:

rsalveti@evatuf:~/build/lmp/build-lmp$ bitbake -f -c image_ota lmp-mini-image
rsalveti@evatuf:~/build/lmp/build-lmp$ cat tmp-lmp/work/jetson_agx_xavier_devkit-lmp-linux/lmp-mini-image/1.0-r0/ota-sysroot/boot/loader/syslinux.cfg
DEFAULT Linux-microPlatform 4.0.11 (ostree:0)
LABEL Linux-microPlatform 4.0.11 (ostree:0)
        KERNEL /boot/ostree/lmp-1b46ae782fedf29a546ce8d442893be0e8573d94f249b2ae87e32a9bb772887c/vmlinuz-5.10.104-l4t-r35.3.ga+g26cfd067b911
        INITRD /boot/ostree/lmp-1b46ae782fedf29a546ce8d442893be0e8573d94f249b2ae87e32a9bb772887c/initramfs-5.10.104-l4t-r35.3.ga+g26cfd067b911.img
        DEVICETREE /boot/ostree/lmp-1b46ae782fedf29a546ce8d442893be0e8573d94f249b2ae87e32a9bb772887c/devicetree-5.10.104-l4t-r35.3.ga+g26cfd067b911
        APPEND ${cbootargs} root=LABEL=otaroot rootwait rootfstype=ext4 mminit_loglevel=4 console=tty0 console=ttyTCU0,115200 fbcon=map:0 video=efifb:off sdhci_tegra.en_boot_part_access=1 shell ostree=/ostree/boot.1/lmp/1b46ae782fedf29a546ce8d442893be0e8573d94f249b2ae87e32a9bb772887c/0

And the main problem here is that while we can sign this file during the OE build process, as soon you do an ostree update, ostree will need to update the file with the new entries and it won't be able to sign it automatically without access to the keys (as it needs to be created at deploy time and not at build time).

In the meta-tegra, they have a recipe that puts it together, and drops it into the bootloader directory of Linux_for_Tegra. The signing tool picks it up from there. Actually, I was thinking about attempting a patch on libostree in the syslinux bootloader to just look for extlinux.conf in the usual space. It would be signed and picked up by the tegra tools.

Would only work for the initial file, won't work with OTAs.

Maybe you could answer this quick question about systemd-boot: Won’t it have the same limitations of needing properly signed files before UEFI will allow access to them if they are in the ESP?

You can boot a signed systemd-boot from ESP which later boots a signed unified kernel image that has everything that is needed there. Ostree does have an issue atm with the way the kernel command line is managed (since at least the hash needs to be decided at deploy time), but there is currently being discussed upstream.

ricardosalveti commented 1 year ago

Upstream thread covering UKI support: https://github.com/ostreedev/ostree/issues/2753