UEFI secure boot is canceled when Capsule Update from R35.4.1 to R35.6.0

Hi,
We have Jetson Orin NX on Jetson Xavier NX Developer Kit Carrier Board installed with Jetson Linux R35.4.1 and enabled UEFI Secure Boot.

When we created BUP in Jetson Linux R35.6.0 environment and executed Capsule Update, UEFI Secure Boot was disabled and the UEFI variables we had set, such as PK, KEK, and DB, were cleared.

  • When Capsule Update was executed using BUP created with R35.4.1 after installing R35.4.1, UEFI Secure Boot was not disabled.
  • When Capsule Update was executed using BUP created with R35.6.0 after installing R35.6.0, UEFI Secure Boot was not disabled.

When Capsule Update was executed using BUP created with R35.6.0 after installing R35.4.1, is it expected that UEFI Secure Boot and UEFI variables are initialized?

The steps we took are listed below.

  1. Write R35.4.1 with l4t_initrd_flash.sh
  2. Enable UEFI Secure Boot with the attached script
    enable_uefi-secureboot.zip (4.8 KB)
$ sudo apt update
$ unzip enable_uefi-secureboot.zip
$ cd enable_uefi-secureboot
$ ./enable-secureboot.sh
$ sudo reboot
  1. After rebooting, check that UEFI Secure Boot is enabled with efivar
$ efivar -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-SecureBoot
GUID: 8be4df61-93ca-11d2-aa0d-00e098032b8c
Name: "SecureBoot"
Attributes:
	Boot Service Access
	Runtime Service Access
Value:
00000000  01   
$ efivar -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-PK
GUID: 8be4df61-93ca-11d2-aa0d-00e098032b8c
Name: "PK"
Attributes:
        Non-Volatile
        Boot Service Access
        Runtime Service Access
        Time-Based Authenticated Write Access
Value:
00000000  ...
$ efivar -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-KEK
GUID: 8be4df61-93ca-11d2-aa0d-00e098032b8c
Name: "KEK"
Attributes:
        Non-Volatile
        Boot Service Access 
        Runtime Service Access 
        Time-Based Authenticated Write Access
Value:
00000000  ...
$ efivar -n d719b2cb-3d3a-4596-a3bc-dad00e67656f-db
GUID: d719b2cb-3d3a-4596-a3bc-dad00e67656f
Name: "db"
Attributes:
        Non-Volatile
        Boot Service Access 
        Runtime Service Access 
        Time-Based Authenticated Write Access
Value:
00000000  ...

  1. Create UEFI variables for testing with efivar
$ printf "\x07\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x01" | sudo dd of=/sys/firmware/efi/efivars/Test-39b68c46-f7fb-441b-b6ec-16b0f69821f3 bs=12;sync
$ efivar -n 39b68c46-f7fb-441b-b6ec-16b0f69821f3-Test
GUID: 39b68c46-f7fb-441b-b6ec-16b0f69821f3
Name: "Test"
Attributes:
	Non-Volatile
	Boot Service Access
	Runtime Service Access
Value:
00000000  04 00 00 00 00 00 00 01                           |........        |
  1. Create BUP with R35.6.0*

*: Replace eks_t234.img with Linux_for_Tegra/bootloader in the file attached below. This eks_t234.img is a fix for the problem of UEFI Secure Boot failing in R35.6.0.
new_eks.zip (504 Bytes)

$ cd Linux_for_Tegra
$ sudo FAB=000 BOARDID=3767 FUSELEVEL=fuselevel_production BOARDSKU=0000 ./build_l4t_bup.sh --bup-type bl p3509-a02+p3767-0000 internal
$ ./generate_capsule/l4t_generate_soc_capsule.sh -i bootloader/payloads_t23x/bl_only_payload -o ./TEGRA_BL.Cap t234
  1. Replace BOOTAA64.efi and executed CapsuleUpdate using TEGRA_BL.Cap with R35.6.0 using the attached script
$ ls
BOOTAA64.efi  TEGRA_BL.Cap  enable_uefi-secureboot  enable_uefi-secureboot.zip  setup_update.zip
$ unzip setup_update.zip
$ cd setup_update/
$ ./setup-update.sh
$ sudo reboot
  1. After rebooting, confirm that CapsuleUpdate is executed using BUP

Image of Capsule Update:

Check results after reboot:

$ sudo nvbootctrl dump-slots-info
[sudo] password for jetson:
Current version: 35.6.0
Capsule update status: 0
Current bootloader slot: B
Active bootloader slot: B
num_slots: 2
slot: 0,             status: normal
slot: 1,             status: normal
  1. Confirm that UEFI Secure Boot is disabled with efivar
$ efivar -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-SecureBoot
GUID: 8be4df61-93ca-11d2-aa0d-00e098032b8c
Name: "SecureBoot"
Attributes:
	Boot Service Access
	Runtime Service Access
Value:
00000000  00   
$ efivar -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-PK
efivar: show variable: No such file or directory
$ efivar -n 8be4df61-93ca-11d2-aa0d-00e098032b8c-KEK
efivar: show variable: No such file or directory
$ efivar -n d719b2cb-3d3a-4596-a3bc-dad00e67656f-db
efivar: show variable: No such file or directory
  1. Confirm that the UEFI variables for testing have been deleted
$ efivar -n 39b68c46-f7fb-441b-b6ec-16b0f69821f3-Test
efivar: show variable: No such file or directory

FYI: Execute enable-secureboot.sh again to enable UEFI Secure Boot.

$ cd enable_uefi-secureboot/
$ rm BOOTAA64.efi*
$ ./enable-secureboot.sh
$ sudo reboot

hello hisanori.kawaura,

that’s expected when OTA from r35.4.1 to r35.6.0
it’s due to r35.4.1 does not have UEFI variable protection, while it’s supported starting from r35.5.0.


here’re several ways to resolve this.
for instance,
(1) you may enable UEFI secure boot by DTBO at flashing time. please see-also Enabling UEFI Secureboot at Flashing Time.
To use the DTBO way to enable UEFI secure boot for production, and use the runtime enable UEFI secure boot way for development.

(2) If that’s a request to runtime enable UEFI secure boot, please moving forward to the latest r35.6.0 release version, or the version support variable protection (i.e. r35.5.0 and later) as base version.

(3) If that’s a must to OTA from r35.4.1 to r35.6.0 with UEFI secure boot.
please give it a try to put the UEFI secure boot keys to the UefiDefaultSecurityKeys.dtbo and generate the BUP with the DTBO.
you may refer to Generate UefiDefaultSecurityKeys.dtbo and the Auth Files to generate the UefiDefaultSecurityKeys.dtbo, and add the ADDITIONAL_DTB_OVERLAY="UefiDefaultSecurityKeys.dtbo" to the command that generate BUP (the DTBO file should be in the Linux_for_Tegra/bootloader directory),
for example,
sudo FAB=000 BOARDID=3767 FUSELEVEL=fuselevel_production BOARDSKU=0000 ADDITIONAL_DTB_OVERLAY="UefiDefaultSecurityKeys.dtbo" ./build_l4t_bup.sh --bup-type bl p3509-a02+p3767-0000 internal

Thank you for your answer.

I understand that when we execute Capsule Update from R35.4.1 to R35.6.0, the UEFI variables are initialized.I also understand that this is a function of UEFI variable protection.

I understand that after Capsule Update from R35.4.1 to R35.6.0, the way to enable UEFI Secure Boot is to include the UefiDefaultSecurityKeys.dtbo in the BUP.

However, we have another problem.

When we update the system, we update the A_kernel partition by booting the recovery partition. (By the way, our system does not have a B_kernel partition.)
In order to boot from the recovery partition, we set the UEFI variable L4TDefaultBootMode from 0x01 to 0x03, but before that, we also prepare for the Capsule Update, so the recovery partition boot after Capsule Update.

This time, when we execute Capsule Update from R35.4.1 to R35.6.0, the variables are initialized, and the L4TDefaultBootMode that was set to 0x03 reverts to 0x01, causing the recovery partition to not boot. Is there any way to prevent the value of the UEFI variable L4TDefaultBootMode from changing even after Capsule Update?

We are already in production using Linux r35.4.1, so we don’t want to change the update sequence.

hello hisanori.kawaura,

did you meant you’ve a customize partition layout?
Bootloader redundancy is enabled by default, please refer to Update and Redundancy.

Yes, B_kernel partition deletion is already customized

Our problem is that when we execute Capsule Update from R35.4.1 to R35.6.0, the L4TDefaultBootMode that we changed in advance is automatically changed from 0x03 to 0x01.

Does UEFI variable protection change values?
I would like to know the specifications of UEFI variable protection.

here’re variables defined by NVIDIA UEFI, i.e. VariableList · NVIDIA/edk2-nvidia Wiki · GitHub

Thanks for the information.

Does this mean that all UEFI variables are deleted by UEFI variable protection and then UEFI sets the initial values ​​of the UEF variables?
Are there any UEFI variables that will be retained after a Capsule Update?

hello hisanori.kawaura,

as mentioned by previous comment #4, that’s due to r35.4.1 does not have UEFI variable protection.
please moving forward to the r35.5.0 or later for development.

We have already started selling products using R35.4.1, so we have to use OTA to update to R35.6.0 at our customers’ sites.
We need to find a workaround so that the UEFI variables do not disappear when using R35.6.0.

Can you give us a good workaround?

hello hisanori.kawaura,

I’ve already given some solutions based-on r35.4.1 as mentioned by previous comment #4.

When OTA updating from R35.4.1 to R35.6.0, I think (3) is the appropriate method based on what you have suggested.

The UEFI variable we want to set to an arbitrary value is L4TDefaultBootMode.
Is this possible, just like the UEFI variable for UEFI Secure Boot?

you may refer to Boot Mode Selection to Customizing the Default Boot Mode in the Configuration File after you moving to r35.6.0

Thank you for your answer.

We generated the BUP with L4TConfiguration.dtbo, which changed the value of UEFI variable L4TDefaultBootMode to 0x03, and were able to achieve the same update sequence as before.

We will try this method.

For example
sudo FAB=000 BOARDID=3767 FUSELEVEL=fuselevel_production BOARDSKU=0000 ADDITIONAL_DTB_OVERLAY="UefiDefaultSecurityKeys.dtbo, L4TConfiguration.dtbo" ./build_l4t_bup.sh --bup-type bl p3509-a02+p3767-0000 internal

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