Capsule Update + SecureBoot enabled

Hi,

I’d like to generate a capsule for updating on a fused + SecureBoot enabled Jetson Orin Nano.
I tried and created a capsule, the device performs some update operation on reboot, but does not succeed. So I assume the capsule is rejected.

This page explains to use l4t_generate_soc_capsule.sh.

The linked document mentions to use 3 different certificate files (signer private certificate, public certificate, and trusted public certificate), but does not explain this further.
In the source code, I see this:

// Test key/certs.
// ‘test’ keys/certs that are public in the edk2 source
// They are enabled in the uefi build.
def_signer_private_cert=“${build_capsule_dir}/Pkcs7Sign/TestCert.pem”
def_other_public_cert=“${build_capsule_dir}/Pkcs7Sign/TestSub.pub.pem”
def_trusted_public_cert=“${build_capsule_dir}/Pkcs7Sign/TestRoot.pub.pem”

However, neither the documentation nor the source code tells me which certificates (i.e. from which keys) to use on a secureboot-enabled device!

My questions:

  • I assume UEFI checks the signed capsule data against some keys in the EKB? If so, which key(s)? db Key?
  • How does that map to the signer/other/trusted certificates from above?
  • In other words if I know to use, e.g., the db key from the EKB, how to provide the correct certificate parameters to the script which generates the capsule?

hello business37,

may I double confirm the fuse types you’ve enabled, for example, what fuse variables you’ve fused.

they’re default keys, you may keep using default values if you don’t have UEFI secureboot enabled.

Yes, secureboot is definitively enabled. MB2 prints RSA PSS signature check: OK and before Linux boots, I see:

L4TLauncher: Attempting Kernel Boot
EFI stub: Booting Linux Kernel…
EFI stub: UEFI Secure Boot is enabled.

I fused using the following xml:

<genericfuse MagicId="0x45535546" version="1.0.0">
    <fuse name="PublicKeyHash" size="64" value="0x..."/>
    <fuse name="PkcPubkeyHash1" size="64" value="0x..."/>
    <fuse name="PkcPubkeyHash2" size="64" value="0x..."/>
    <fuse name="SecureBootKey" size="32" value="0x..."/>
    <fuse name="Kdk0" size="32"  value="0x..."/>
    <fuse name="OemK1" size="32" value="0x..."/>
    <fuse name="OemK2" size="32" value="0x..."/>
    <fuse name="PscOdmStatic" size="4" value="0x60"/>
    <fuse name="BootSecurityInfo" size="4" value="0x2A09"/>
    <fuse name="SecurityMode" size="4" value="0x1"/>
</genericfuse>

hello business37,

may I also confirm how you create bootloader and kernel payloads?
anyways, please share your complete steps for reference,
here’s an example, you should include PKC/SBK keys for running l4t_generate_soc_bup script,
for instance, $ sudo ./l4t_generate_soc_bup.sh -u PKC.key -v SBK.key -e t23x_3767_bl_spec t23x

I’m using Yocto to generate the payloads. Yes, I do use the correct SBK/PKC:

TEGRA_SIGNING_ARGS = '-u ${RECIPE_SYSROOT_NATIVE}${libdir}/testkeys/pkc.pem \
                      -v ${RECIPE_SYSROOT_NATIVE}${libdir}/testkeys/sbk.key'

Commenting this out, or exchanging a with a different key file leads to the image being rejected when trying to flash.

as you can see… Prerequisites Secure Boot.
it’s based-on an X86 host running Ubuntu 18.04 LTS, or 20.04 LTS.

I guess you answered the wrong post.

Your answer has nothing to do with my initial question:

  • How to correctly setup the keys/certificates to create signed capsules for updating a secure boot enabled Jetson Orin Nano?

I am using an X86 host and I burned PKC/SBK/KDK0, OEMK1/2 and so on as written above.
This is not about verifying whether this succeeded, it’s simply about missing documentation how to generate correctly signed capsules that are accepted by UEFI.

After running an update, I see this message on reboot:

Jetson UEFI firmware (version v35.5.0 built on 2024-02-26T13:44:31+00:00)
ESC to enter Setup.
F11 to enter Boot Manager Menu.
Enter to continue boot.

Update Progress - 100% **************************************************
[0000.079] I> MB1 (version: 1.4.0.1-t234-54845784-08e631ca)
[0000.084] I> t234-A01-1-Silicon (0x12347) Prod
[0000.088] I> Boot-mode : Coldboot
[0000.092] I> Entry timestamp: 0x00000000
[0000.095] I> last_boot_error: 0x0
[0000.098] I> BR-BCT: preprod_dev_sign: 0
[0000.102] I> rst_source: 0x17, rst_level: 0x1
[0000.106] I> Task: SE error check
[0000.110] I> Task: Bootchain select WAR set
[0000.114] I> Task: Enable SLCG
[0000.117] I> Task: CRC check
[0000.119] I> Task: Initialize MB2 params
[0000.124] I> MB2-params @ 0x40060000
[0000.127] I> Task: Crypto init
[0000.130] I> Task: Perform MB1 KAT tests
[0000.134] I> Task: NVRNG health check
[0000.137] I> NVRNG: Health check success
[0000.141] I> Task: MSS Bandwidth limiter settings for iGPU clients
[0000.147] I> Task: Enabling and initialization of Bandwidth limiter
[0000.153] I> No request to configure MBWT settings for any PC!
[0000.159] I> Task: Secure debug controls
[0000.163] I> Task: strap war set
[0000.166] I> Task: Initialize SOC Therm
[0000.170] I> Task: Program NV master stream id
[0000.174] I> Task: Verify boot mode
[0000.180] I> Task: Alias fuses
[0000.183] W> FUSE_ALIAS: Fuse alias on production fused part is not supported.
[0000.190] I> Task: Print SKU type
[0000.193] I> FUSE_OPT_CCPLEX_CLUSTER_DISABLE = 0x000001c8
[0000.198] I> FUSE_OPT_GPC_DISABLE = 0x00000001
[0000.202] I> FUSE_OPT_TPC_DISABLE = 0x0000000f
[0000.207] I> FUSE_OPT_DLA_DISABLE = 0x00000003
[0000.211] I> FUSE_OPT_PVA_DISABLE = 0x00000001
[0000.215] I> FUSE_OPT_NVENC_DISABLE = 0x00000001
[0000.220] I> FUSE_OPT_NVDEC_DISABLE = 0x00000000
[0000.224] I> FUSE_OPT_FSI_DISABLE = 0x00000001
[0000.228] I> FUSE_OPT_EMC_DISABLE = 0x0000000c
[0000.233] I> FUSE_BOOTROM_PATCH_VERSION = 0x7
[0000.237] I> FUSE_PSCROM_PATCH_VERSION = 0x7
[0000.241] I> FUSE_OPT_ADC_CAL_FUSE_REV = 0x2
[0000.245] I> FUSE_SKU_INFO_0 = 0xd5
[0000.248] I> FUSE_OPT_SAMPLE_TYPE_0 = 0x3 PS
[0000.252] I> FUSE_PACKAGE_INFO_0 = 0x2
[0000.256] I> SKU: Prod
[0000.258] I> Task: Boost clocks
[0000.261] I> Initializing PLLC2 for AXI_CBB.
[0000.265] I> AXI_CBB : src = 35, divisor = 0
[0000.270] I> Task: Voltage monitor
[0000.273] I> VMON: Vmon re-calibration and fine tuning done
[0000.278] I> Task: UPHY init
[0000.283] I> HSIO UPHY init done
[0000.286] W> Skipping GBE UPHY config
[0000.290] I> Task: Boot device init
[0000.293] I> Boot_device: QSPI_FLASH instance: 0
[0000.298] I> Qspi clock source : pllc_out0
[0000.302] I> QSPI Flash: Macronix 64MB
[0000.305] I> QSPI-0l initialized successfully
[0000.310] I> Task: TSC init
[0000.312] I> Task: Load membct
[0000.315] I> RAM_CODE 0x4000021
[0000.318] I> Loading MEMBCT
[0000.321] I> Slot: 0

But, as one can see in the last line, the machine does afterwards not switch from boot slot 0 to slot1. When I check with nvbootctrl dump-slots-info, slot 1 is marked as “non-bootable”. That’s why I assume signing the capsule with the test keys is not correct on a secure boot enabled device.

hello business37,

we’ve tested capsule update on fused device.
please refer to below for the steps.

[Host PC]
$ sudo ./l4t_generate_soc_bup.sh -u PKC.pem -v sbk.key -e t23x_3767_bl_spec t23x
$ ./generate_capsule/l4t_generate_soc_capsule.sh -i bootloader/payloads_t23x/bl_only_payload -o ./TEGRA_BL.Cap t234
$ scp TEGRA_BL.Cap nvidia@<IP address>:/home/nvidia/.

[Target-Fused Orin-Nano]
$ ll /dev/disk/by-partlabel/esp
lrwxrwxrwx 1 root root 16 Jan 1 1970 /dev/disk/by-partlabel/esp -> ../../nvme0n1p11
$ sudo mount /dev/nvme0n1p11 /mnt/
$ cd /mnt/EFI
$ sudo su
# mkdir UpdateCapsule
# cd UpdateCapsule/
# cp /home/nvidia/TEGRA_BL.Cap .
# cd /sys/firmware/efi/efivars/
# printf "\x07\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00" > /tmp/var_tmp.bin
# sudo dd if=/tmp/var_tmp.bin of=OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c bs=12
1+0 records in
1+0 records out
12 bytes copied, 0.00512237 s, 2.3 kB/s
# reboot

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.