PKC Key Revocation#
Revocation of PKC Keys for Jetson Thor#
Applies only to the Jetson Thor SoC.
The Jetson Thor SoC supports 16 PKC public keys and provides a revoking mechanism if keys are compromised after the product is shipped. The Jetson Thor SoC is capable of revoking multiple keys at the same time. Only the first 15 PKC keys are revocable. The last PKC key (key_id="15") cannot be revoked.
If a key used in an inactive boot chain is listed for revocation, the Jetson Thor SoC will not revoke it. This prevents the inactive boot chain from becoming unbootable.
To revoke the comprised PKC keys (key_id 0 through 14):
Determine a revoke bitmap of keys to be revoked. Each bit in the revoke bitmap represents a
key_id: bit 0 forkey_id="0", bit 1 forkey_id="1", and so on.Add
u16_fuse_revoke_bitmap = <revoke_bitmap>to thebrbctsection of the<br_bct.dts>file of your target board.In the
<pkc_key_list>file, edit theactive_indexfield to use akey_idthat is bigger than the largestkey_idin<revoke_bitmap>.Update the bootloader using the
<pkc_key_list>file for the revocation to take effect. Perform one of the following actions:Flash the device. For details, refer to Sign and Flash Secured Images.
Note
Flashing the device will update the bootloader of both boot chains.
or
Perform an Over-the-Air (OTA) update by triggering a UEFI Capsule update twice. For details, refer to Manually Trigger the Capsule Update.
Note
Triggering the UEFI Capsule update twice updates both boot chains. This is required because key revocation cannot occur while either boot chain still uses a key that is scheduled for revocation.
First, perform the OTA update on the inactive boot chain. After it completes and the system successfully boots from the newly updated chain, the previously active chain becomes inactive. Then perform the second OTA update on the new inactive chain. Once the second update completes and the system reboots from it, both boot chains are updated, and key revocation will be executed during boot by MB2.
Note
To find the <br_bct.dts> file of your target board, look for the DEV_PARAMS= entry in your target board config file.
An Example: Revoke PKC keys 0, 1, and 5#
This example shows how to revoke three PKC keys—0, 1, and 5—on a jetson-agx-thor-devkit target.
For these three keys, the revoke bitmap is 0x23. The entry DEV_PARAMS="tegra264-br-bct-common-l4t.dts" is set in t264.conf.common, which is included by jetson-agx-thor-devkit.conf.
In
<LDK_DIR>/bootloader/generic/BCT/tegra264-br-bct-common-l4t.dts, afterpreprod_dev_sign = <1>;, add the following entry:u16_fuse_revoke_bitmap = <0x23>;
In the
<pkc_key_list>file, change theactive_index=field to 6 (or a greater value, but no higher than 14):active_index="6"
Execute the following flash command:
sudo ./l4t_initrd_flash.sh -u <pkc_key_list> jetson-agx-thor-devkit internal
Reset the
jetson-agx-thor-devkittarget to enable the key revocation.Verify that the target can boot successfully.
Note
If the active_index= field is set to 2 (or 3 or 4), only PKC keys 0 and 1 are revoked. This happens because, if revocation policy is enabled (bit 5) in the BootSecurityInfo fuse, only PKC keys whose key_id are less than active_index are revoked.
Revocation of PKC Keys for Jetson Orin#
Applies only to the Jetson Orin NX series, the Jetson Orin Nano series, and the Jetson AGX Orin series.
The Jetson Orin SoC supports three PKC public keys and provides a revoking mechanism if a key is compromised after the product is shipped.
Here is some information about these keys:
These PKC keys must be of the same type and strength.
These keys are OEM programmable and the SHA2-512 hashes of the keys are burned into the fuses (FUSE_PUBLIC_KEY, FUSE_PK_H1 and FUSE_PK_H2) by the OEM during the manufacturing process. (Use the corresponding fuse name of PublicKeyHash, PkcPubkeyHash1, PkcPubkeyHash2 in the Fuse Configuration XML file.)
To enable ratchet, FUSE_OPT_CUSTOMER_OPTIN_FUSE (Fuse Configuration file XML entry: <fuse name=”OptInEnable” size=”4” value=”0x1” />) must be burned. This is to prevent running an earlier versions of the software, which compromises the revocation effect.
The keys are always active until they are revoked, and SoC will accept images signed with any of the non-revoked keys.
The last key (FUSE_PK_H2) is not revocable, and the system can always boot with images signed with the private key of the last key.
To revoke the first PKC (FUSE_PUBLIC_KEY) key:
Add revoke_pk_h0 = <1> to the brbct section of the <br_bct.dts> file of your target board.
Use the second PKC private key or the last PKC private key as the sign key in -u option in flash.sh.
To revoke the second PKC (FUSE_PK_H1) key:
Add revoke_pk_h1 = <1> to the brbct section of the <br_bct.dts> file of your target board.
Use the last PKC private key as the sign key in -u option in flash.sh.
After a key is revoked, it is permanently unusable. It cannot be restored even if revoke_pk_h0 or revoke_pk_h1 is set to <0>.
To support PKC keys revocation, all three PKC keys must be fused at device provision.
Note
To find the <br_bct.dts> file of your target board, look for “DEV_PARAMS=” entry of your target board config file.
An Example: Fusing the Three PKC keys#
Generate the rsa3k-0.pem, rsa3k-1.pem, and rsa3k-2.pem PKC keys:
$ openssl genrsa -out rsa3k-0.pem 3072
$ openssl genrsa -out rsa3k-1.pem 3072
$ openssl genrsa -out rsa3k-2.pem 3072
Generate the Hash values from the PKC keys:
$ ./tegrasign_v3.py --pubkeyhash rsa3k-0.pubkey rsa3k-0.hash --key rsa3k-0.pem
$ ./tegrasign_v3.py --pubkeyhash rsa3k-1.pubkey rsa3k-1.hash --key rsa3k-1.pem
$ ./tegrasign_v3.py --pubkeyhash rsa3k-2.pubkey rsa3k-2.hash --key rsa3k-2.pem
Create a Fuse Configuration file (fuse_rsa3k.xml):
Enter the hexadecimal public key hash that was generated from rsa3k-0.pem to the value field of the “PublicKeyHash” fuse name.
Enter the hexadecimal public key hash that was generated from rsa3k-1.pem to the value field of the “PkcPubkeyHash1” fuse name.
Enter the hexadecimal public key hash that was generated from rsa3k-2.pem to the value field of the “PkcPubkeyHash2” fuse name.
Note
For more information about generating the PublicKeyHash fuse value, refer to Generate PublicKeyHash Value from a PKC Key Pair for Jetson Orin.
Here is an example Fuse Configuration file:
<genericfuse MagicId="0x45535546" version="1.0.0">
<fuse name="SecureBootKey" size="32" value="0x123456789abcdef0fedcba987654321023456789abcdef01edcba9876543210f"/>
<fuse name="PublicKeyHash" size="64" value="0xad2474627c14e3f7f4944a832bd15d0640938a3dc162f558692458f3d12f9453e11bea2ec75df3f83e8b29c47fc3d2483d528d3e94a5469c4ba1ec61f1584b23"/>
<fuse name="PkcPubkeyHash1" size="64" value="0xd87796fb510d79738f8509c98511be0bb79dcc17d204a2f0f0bea9680b91bd1273ee2ae7a8a6bdb8b95deb0f421e72404939ae20d12c82649712283027201f39"/>
<fuse name="PkcPubkeyHash2" size="64" value="0x99a5b6eac64dfb29698cb684165529e5d8650c1aab0e18b677c5d5f0998af53f8a8a1f09ad1d79368bc500e57eb199e9108fc7b1499995d869b028fec3f367db"/>
<fuse name="OptInEnable" size="4" value="0x1"/>
<fuse name="BootSecurityInfo" size="4" value="0x9"/>
<fuse name="SecurityMode" size="4" value="0x1"/>
</genericfuse>
Burn the fuses with the Fuse Configuration file (fuse_rsa3k.xml):
$ sudo ./odmfuse.sh -X fuse_rsa3k.xml -i 0x23 jetson-agx-orin-devkit
Note
In the following examples, the sbk key is stored in file sbk-32.key with content:
0x12345678 0x9abcdef0 0xfedcba98 0x76543210 0x23456789 0xabcdef01 0xedcba987 0x6543210f
An Example: Revoking the First PKC key (rsa3k-0.pem)#
Add revoke_pk_h0 = <1> to tegra234-br-bct-p3767-0000-l4t.dts:
/dts-v1/;
/ {
brbct {
. . .
revoke_pk_h0 = <1>;
bf_bl_allbits {
. . .
}
};
};
Flash with rsa3k-1.pem or rsa3k-2.pem:
Option 1: rsa3k-1.pem
$ sudo ./flash.sh -u rsa3k-1.pem -v sbk-32.key jetson-agx-orin-devkit internal
Option 2: rsa3k-2.pem
$ sudo ./flash.sh -u rsa3k-2.pem -v sbk-32.key jetson-agx-orin-devkit internal
Use the UEFI Capsule update to revoke the first PKC key.
Generate the Capsule payload with the modified dts file. For more information, refer to Generating the Capsule Update Payload.
Option 1: Generate the Capsule payload signed by the second PKC key rsa3k-1.pem.
$ sudo ./l4t_generate_soc_bup.sh -u rsa3k-1.pem -v sbk-32.key -e t23x_agx_bl_spec t23x $ ./generate_capsule/l4t_generate_soc_capsule.sh -i bootloader/payloads_t23x/bl_only_payload -o ./TEGRA_BL.Cap t234
Option 2: Generate the Capsule payload signed by the third PKC key rsa3k-2.pem.
$ sudo ./l4t_generate_soc_bup.sh -u rsa3k-2.pem -v sbk-32.key -e t23x_agx_bl_spec t23x $ ./generate_capsule/l4t_generate_soc_capsule.sh -i bootloader/payloads_t23x/bl_only_payload -o ./TEGRA_BL.Cap t234
Trigger a Capsule update. For more information, refer to Use the Helper Script to Trigger the Capsule Update.
An Example: Revoking the Second PKC key (rsa3k-1.pem)#
Add revoke_pk_h1 = <1> to tegra234-br-bct-p3767-0000-l4t.dts:
/dts-v1/;
/ {
brbct {
. . .
revoke_pk_h1 = <1>;
bf_bl_allbits {
. . .
}
};
};
Flash with rsa3k-2.pem:
$ sudo ./flash.sh -u rsa3k-2.pem -v sbk-32.key jetson-agx-orin-devkit internal
Use the UEFI Capsule update to revoke the second PKC key.
Generate the Capsule payload with the modified dts file. For more information, refer to Generating the Capsule Update Payload.
$ sudo ./l4t_generate_soc_bup.sh -u rsa3k-2.pem -v sbk-32.key -e t23x_agx_bl_spec t23x $ ./generate_capsule/l4t_generate_soc_capsule.sh -i bootloader/payloads_t23x/bl_only_payload -o ./TEGRA_BL.Cap t234
Trigger a Capsule update. For more information, refer to Use the Helper Script to Trigger the Capsule Update.