Secure Boot

Secure boot:
  • Must be implemented and enabled during manufacturing.
  • Cannot be enabled over OTA or in the field.
  • Defines a chain of trust.
  • Is supported by hardware from power on to BootROM and PSC-ROM (Platform Security Control ROM) to boot loader.
  • Must be implemented by the boot loader.

Signing Authorities

Signing authority for Orin shall consist of NVIDIA authority and OEM authority. Since the Root of Trust (ROT) resides within the silicon, NVIDIA shall enforce our authority in the Chain of Trust (COT) by baking it into the ROM. Orin shall have two ROM software running under BPMP and PSC that will establish ROT for NVIDIA. OEMs also may assert their signing authority on top of NVIDIA authority.

NVIDIA Authority

NVIDIA authority is implemented in such a way that its crypto information cannot be overwritten by the OEM. Thus, a KROM region is dedicated to keeping NVIDIA keys safe within the chip. NVIDIA keys are only readable in the encrypted form by PSC-ROM.

NVIDIA has settled on one single algorithm for each type of binary for authentication. 3072-bit RSA shall be used for all NV authentication purposes. AES-GCM (256b) shall be used for all NV authenticated encryption purposes.

  • BPMP BootROM (BPMP-BR in short)

  • PSC BootROM (PSC-ROM in short)

Both ROM software shall work with each other to establish the ROT and load/authenticate/decrypt secondary boot software (MB1) from the storage device. NVIDIA signing authority shall extend all the way to CCPLEX ARM-Core boot for T23x.

OEM Authority

OEM authority is FUSE based. FUSE is OTP entity in the chip that the OEM shall take control of during the manufacturing process of their product. OEM has the choice of enabling the different secure boot options also through the BOOT_SECURITY_INFO fuse by selecting the enablement of Secure Boot. OEM must choose a method of authentication to enable secure boot once SECURITY_MODE FUSE is burnt.

Signing Algorithms

NVIDIA authority only uses RSA3K for signing with SHA2-512 as the digest algorithm.

OEM authority has a choice of signing algorithm to choose from as stated above. The combination of signing algorithm and digest algorithm is the following:

  • 3072-bit RSA (Public Exponent fixed at 0x10001) – SHA2-512 and RSAPSS encoding

  • Ed25519 DSA (RFC 8032) – SHA2-512

Boot firmware signing is facilitated through Boot Component Header (BCH). The actual binaries are not signed, but their digests are included in the BCH. BCH acting like a certificate is then signed. During verification, the signature of the BCH is verified, and then the digest of the firmware within BCH is verified. Detail of BCH and verification mechanism is found in the BCH section.

For NVIDIA authority, there are signature verification public keys for each different firmware component, all the public keys reside in KROM.

For OEM authority, there are three public key hashes (PKC hash) in FUSE that the OEM can use to provision. The PKC hash is a SHA2-512 digest of a specific structure defined in SW. More detail about this is also available in the BCH section.

The FUSE_BOOT_SECURITY_INFO on NVIDIA DRIVE devices determines which sequence is used. The information in the FUSE_BOOT_SECURITY_INFO bits is as follows:

Bit[2:0]: authentication scheme:

  • 001b: PKC-protected boot sequence with RSA 3K key pairs

  • 100b: PKC-protected boot sequence with Ed25519 DSA key

Secure Boot with Test Keys

The overall process to test secure boot with test keys is:
  1. Generate a test key pair to use for secure boot testing. Either use your HSM to generate a test key pair, or use a utility like OpenSSL. Example command:
    openssl genrsa -out rsa_priv.pem 3072

    For more information, refer to Generating a PKC Key Pair Using OpenSSL.

  2. Create a fuse configuration XML file to burn the fuses. Your fuse XML file must include these lines:
    <!-- Public Key Hash of the test public key. Replace with your key hash. -->
    <fuse name="PublicKeyHash" size=“64" value="0x0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF”
    <!-- Boot Security Information.
           Bit [1:0] - Authentication Scheme - 3072 bit RSA in this example.
           Bit [9] - OEM Key Valid flag. Required to be burned to 1 to enable Secure Boot or SPI-NOR.
    -->
    <fuse name="BootSecurityInfo" size="4" value="0x201"/>
    <fuse name="SecurityMode" size="4" value="0x1"/>
    

    For more information, refer to Format of the Fuse Configuration File.

  3. Do a test run of fuse burning with the -t option, which validates things but does not actually burn any fuses. Correct any errors. Only burn the fuses after a successful test run, and use the exact command line that worked with –t but change -t to -b. Example command for a test run:
    ./fskp_fuseburn.py -f <fuse_config> -i 63 -k fskp.test.key -c 0x23 --fskpcfg <fskp_cfg>  -B <board> -t
    
    Where:
    • <fuse_config> is your fuse XML file from step 2.
    • <fskp_cfg> is an optional file specifying the derivation strings you want to use. If the default derivation strings are desired, then this argument should be omitted. For testing it is fine to use the defaults. For production you should generate your own derivation strings to strengthen security.

    For more information, refer to the FSKP Fuse Burn Script chapter in the NVIDIA DRIVE OS PDK Developer Guide.

  4. Burn the fuses using the FSKP test key and index 63. Example command to burn fuses:
    ./fskp_fuseburn.py -f <fuse_config> -i 63 -k fskp.test.key -c 0x23 --fskpcfg <fskp_cfg>  -B <board> -b
    
    Where:
    • <fuse_config> is your fuse XML file from step 2.
    • <fskp_cfg> is an optional file specifying the derivation strings you want to use. If the default derivation strings are desired, then this argument should be omitted. For testing it is fine to use the defaults. For production you should generate your own derivation strings to strengthen security.

    For more information, refer to the FSKP Fuse Burn Script chapter in the NVIDIA DRIVE OS PDK Developer Guide.

  5. Generate the signed BSP image. Example command:
    ./create_bsp_images.py --customer-data customer_data.json nv_customer_data_schema.json -p <pkc_file> -b <board> -r 02 -g ./flashing_images
    
    Where:
    • <pkc_file> is your public key which is the file named rsa_priv.pem if you used OpenSSL in step 1.
    • <board> is your board name. For example: 3710.

    For more information, refer to the Generating Flashing Binaries Offline section in the NVIDIA DRIVE OS SDK Developer Guide.

  6. Flash the signed BSP image. Example command:
    ./flash_bsp_images.py --customer-data customer_data.json -b <board> -P 
    ./flashing_images/940-ORIN-2200-000_VD*
    
    Where:
    • <board> is your board name.

    For more information, refer to the Usage section under Flashing Preprocessed Images in the NVIDIA DRIVE OS SDK Developer Guide