Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mmitchel opened this issue Jun 29, 2023 · 4 comments

Comments

@mmitchel
Copy link

mmitchel commented Jun 29, 2023

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
Copy link
Member

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
Copy link
Author

mmitchel commented Jun 29, 2023 via email

@ricardosalveti
Copy link
Member

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
Copy link
Member

Upstream thread covering UKI support: ostreedev/ostree#2753

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants