Rollback Protection

Applies to the Jetson AGX Orin.

Overview

Rollback protection prevents a computing system from being downgraded (rolled back) from a later version to an earlier one.

NVIDIA® Jetson™ devices use an implementation of rollback protection called ratcheting.

Ratcheting is based on a common rollback architecture that uses a software version number (SWVN) and a hardware version number (HWVN). The SWVN is a binary value that is stored in a software component or a header associated with it, and its value represents the software component’s version number. The HWVN is a value stored in hardware, typically in a fuse whose bits can each be burned (changed by software from 0 to 1), but cannot be changed back to 0.

During the boot process, a Jetson device’s software performs several ratchet checks by comparing several SWVNs to the corresponding HWVNs.

  • If SWVN == HWVN, the device is loading the current version of the software component, and the boot process loads the component.

  • If SWVN > HWVN, the device is loading new versions of the software components. The boot process loads the component and performs a ratchet update by burning bits in the HWVN fuse to set it equal to the SWVN.

  • If SWVN < HWVN, the device is loading old versions of the software components, and the boot software aborts the boot process.

Typically ratchet-checked version numbers are incremented in single steps. Version 0 is always followed by version 1, and version 1 is always followed by version 2, and so on. For each successive version, the SWVN is incremented by 1, and one additional bit is burned in the HWVN.

An SWVN is ordinarily hard coded in the software component’s source code and becomes part of its compiled binary. You can also set the SWVN in your project build system and save it in a binary header, and this header is combined with the program binary before it is ready to be used.

In Jetson devices that use the T234 processor (the Jetson AGX Orin), a software component’s SWVN is stored in its code or in its Boot Component Header (BCH), which is an NVIDIA binary header that stores many types of information about boot components.

Rollback Protection for MB1-BCT, MB2, and Later Components

MB2 and later components, for example, UEFI, TrustedOS, and so on, do not have HWVNs stored in fuses because an NVIDIA® Jetson™ processor does not have enough fuses to support these components. Also, the number and identity of these components are subject to change by customers, so a fixed hardware fuse cannot be assigned to each component.

Instead, a copy of the HWVN for each of these components is stored in MB1-BCT and is used to ratchet-check the component’s actual SWVN. Each component’s actual SWVN is stored in the component’s BCH.

MB1-BCT has hardware fuses to store its HWVN. When MB1 boots up, it ratchet-checks MB1-BCT before loading other components. This way, the HWVNs stored in MB1-BCT can be trusted after MB1-BCT has passed the ratchet checking test.

MB1-BCT

In Jetson devices that use the T234 processor (the Jetson AGX Orin), the HWVN for MB1-BCT is stored in the following fuses:

  • FUSE_SYSTEM_FW_FIELD_RATCHET0_0

  • FUSE_SYSTEM_FW_FIELD_RATCHET1_0

  • FUSE_SYSTEM_FW_FIELD_RATCHET2_0

  • FUSE_SYSTEM_FW_FIELD_RATCHET3_0

These fuses have four-byte values with 32 programmable bits, so the number of times MB1-BCT can be ratchet-updated is 4×32 = 128.

MB1 ratchet-checks and loads MB1-BCT, and you can define the SWVN for MB1-BCT by updating the ratchet configuration file. Refer to MB2 and Later Components for more information. The SWVN from the ratchet configuration file is stored in the MB1-BCT BCH.

MB2 ratchet-updates the HWVN of MB1-BCT when the SWVN of MB1-BCT is greater than the HWVN. Unless an OPTIN fuse is burned, this feature is disabled by default:

  • FUSE_OPT_CUSTOMER_OPTIN_FUSE_0

This is an 1-bit fuse, and as long as the fuse is burned from 0 to 1, the ratchet-updating of MB1-BCT is enabled in MB2.

Note

When using the odmfuse.sh script and the fuse XML file to burn fuses, the name of this OPTIN fuse is: OptInEnable.

Note

Jetson Linux supports A/B slots for MB1-BCT. When this feature is enabled, there are two MB1-BCT binaries in the Jetson device. The small SWVN between these two MB1-BCT will determine whether the ratchet-updating of MB1-BCT should be completed.

MB2 and Later Components

The ratchet configuration file defines the HWVNs for MB2 and later components. The ratchet configuration file for the Jetson AGX Orin is:

  • Linux_for_Tegra/bootloader/t186ref/BCT/tegra234-mb1-bct-ratchet-p3701-0000.dts

Here are the initial contents of the ratchet configuration file for the Jetson AGX Orin:

/dts-v1/;

/ {
    ratchet {
        /* name = <index value> */
        mb1bct = <1 0>;
        membct = <2 0>;
        bpmp_fw_dtb = <3 0>;
        mb2rf = <4 0>;
        mb2 = <5 0>;
        /* index 6 and 7 are reserved */
        mb2_applet = <8 0>;
        fskp_fw = <9 0>;

        /* index 15 is reserved */
        spe = <16 0>;
        /* index 17 and 18 are reserved */
        sce = <19 0>;
        rce = <20 0>;
        ape = <21 0>;
        dce = <22 0>;
        atf = <23 0>;
        tos = <24 0>;
        /* index 25 is reserved */
        cpubl = <26 0>;
        cpubl_dtb = <27 0>;
    };
};

The first setting, mb1bct = <1 0>, defines the MB1-BCT SWVN. The settings follow a “Name = Value” syntax, where:

  • Name: the name of the boot component. The names in the ratchet configuration file are predefined and can not be changed.

  • Value: the value contains two numbers. The first number is the index of the boot component that is used internally by MB1 and MB2, and it can not be changed. The second number defines the version of the boot component that can be changed according to the requirements. During flashing time, the number will be injected into the BCH of the boot component and act as the SWVN of this component. Meanwhile, the number will be injected into MB1-BCT as well and act as the HWVN of this component.

The tool that flashes the Jetson device reads and parses the ratchet configuration file and incorporates its settings into the flashed image.

An Example

This section demonstrates an example that tries to downgrade UEFI from version 3 to version 1. When the device is flashed, version 3 is incorporated into UEFI’s BCH as its SWVN and into MB1-BCT as its HWVN. If you try to update UEFI with an earlier version, version checking will compare the SWVN of the earlier version in the UEFI BCH to the HWVN of version 3 in MB1-BCT and stop the booting process. MB1-BCT has been ratchet-checked against a valid HWVN, so its contents, including the UEFI HWVN, is reliable.

Here is an overview of this process:

  1. The first command changes the version of UEFI from 0 to 3.

  2. The second command flashes the Jetson device.

  3. The version of UEFI is changed to 1, and the new UEFI image is flashed into the A and B slots. Since MB1-BCT is not updated, the HWVN of UEFI that is stored in MB1-BCT is still 3.

  4. At the next system boot, ratchet-checking in MB2 finds the version mismatch between HWVN and SWVN of UEFI, and the system stops booting.

sudo sed -i "s/cpubl = <26 0>;/cpubl = <26 3>;/g" bootloader/t186ref/BCT/tegra234-mb1-bct-ratchet-p3701-0000.dts
sudo ./flash.sh jetson-agx-orin-devkit mmcblk0p1

sudo sed -i "s/cpubl = <26 3>;/cpubl = <26 1>;/g" bootloader/t186ref/BCT/tegra234-mb1-bct-ratchet-p3701-0000.dts
sudo ./flash.sh -r -k A_cpu-bootloader jetson-agx-orin-devkit mmcblk0p1
sudo ./flash.sh -r -k B_cpu-bootloader jetson-agx-orin-devkit mmcblk0p1

I> Partition name: B_cpu-bootloader
I> Size of partition: 3670016
I> Binary@ device:3/0 block-87808 (partition size: 0x380000), name: B_cpu-bootloader
E> Binary(43) version mismatch
E> Expected version: 3
E> Binary version: 1
C> Task 0x0 failed (err: 0x22228702)
E> Top caller module: LOADER, error module: LOADER, reason: 0x02,

Incrementing the Version Number of MB2 and Later Components

The HWVNs for MB2 and later components are stored in MB1-BCT, instead of in burnable fuses, so they cannot be ratchet-updated at runtime. To complete a ratchet-update, the boot software has to patch the binary for MB1-BCT, and because the software is typically signed by a PKC key, the update is not feasible.

To update one of these components and increment its version number:

  1. Increment its version number setting in the ratchet configuration file.

  2. To reflect that MB1-BCT contains a new HWVN for the updated component, increment the MB1-BCT version in the ratchet configuration file.

  3. Reflash the device or perform an Over-the-Air (OTA) update of the updated component and MB1-BCT.

  4. The HWVNs stored in MB1-BCT for MB2 and later components can be used to ratchet-check MB2 and later components.

If an updated component is updated later to an earlier version, it will fail the ratchet-check.