Jump to content

RidgeRun Platform Security Manual/Getting Started/Secure Boot: Difference between revisions

Line 257: Line 257:
</syntaxhighlight>
</syntaxhighlight>


Which as we can see has zeros in all of them because we have not write to them. Once a 1 has been written to one of the bits of the fuses, it cannot be reversed. The next step to activate secure boot is to generate the keys that are going to be stored in the fuses. For this example we are going to just use the PublicKeyHash fuse and SecureBootKey fuse. The Public key is use for boot code authentication and the secure boot key is used for boot codes encryption and decryption.
Starting with the Public key used for authenticating the boot codes, it can be generated as an RSA 3K key, ECDSA P-256 or ECDSA P-521 key. For reference, these are two types of algorithms for genetring a PKC pair and the numbers are just the size of the keys. In terms of security RSA 3K and ECDSA P-256 provide a similar level of security but ECDSA is more efficient because it needs less storage. ECDSA P-521 provides a higher security level the the previous algorithms explained and has a lower size than RSA 3K. RSA 3K is a more known/applied/compatible algorithm. For this guide, an RSA 3K key is going to be used. To generated, create a keys folder inside the Linux for Tegra directory:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
sudo ./fskp_fuseburn.py -h
mkdir keys
[sudo] password for chidalgo:
cd keys
FSKP execution started 2025-03-13 11:53:29.595125
openssl genrsa -out rsa_priv.pem 3072
fskp_fuseburn.py script version 0.2
</syntaxhighlight>
Parsing input arguments
usage: fskp_fuseburn.py [-h] [-b] [-B BOARDNAME] [--board-spec BOARD_SPEC] [-c {0,x,2,3}]
                        [--instance INSTANCE] [-C <fskpcfg.txt|random>] [-e]
                        [-f <fuse_data.xml>] [-g <directory path>]
                        [-i <fskp key slot number>] [-H [HSM [HSM ...]]]
                        [-k <fskp.key> | -K | --key-exp <authkey> <enckey>]
                        [-p <pkc.key>] [-r {emmc,ufs,spi}] [-s] [-S {TA977SA,TA983SA}]
                        [-t] [-u] [-v [VERBOSE]] [-V] [-P <directory path>]
                        [--fskp-blob-out FSKP_BLOB_OUT] [--multi-blob KDK_DATABASE]


Parse Aruguments
the output should look like the following:


optional arguments:
<syntaxhighlight lang="bash">
  -h, --help            show this help message and exit
Generating RSA private key, 3072 bit long modulus (2 primes)
  -b, --burnfuse        Burn fuses on target
.................................................................++++
  -B BOARDNAME, --board BOARDNAME
...................................................................++++
                        set target board name or board config file. eg. p3701
e is 65537 (0x010001)
  --board-spec BOARD_SPEC
                        set target board info file.
  -c {0,x,2,3}, --chip {0,x,2,3}
                        set tegra chipid. eg. 0x23 for Orin
  --instance INSTANCE  set USB interface id.
  -C <fskpcfg.txt|random>, --fskpcfg <fskpcfg.txt|random>
                        Provide fskp configuration text file or use 'random' for
                        generating random strings
  -e, --ecid            Print ECID of the target
  -f <fuse_data.xml>, --fusefile <fuse_data.xml>
                        Provide fuse xml file
  -g <directory path>, --outdir <directory path>
                        Generate blob at <directory path> only and do not burn
  -i <fskp key slot number>, --keyindex <fskp key slot number>
                        Tegra FSKP Key index alloted to OEM
  -H [HSM [HSM ...]], --hsm [HSM [HSM ...]]
                        perform signing encryption operation in HSM mode. [ | fskp]
  -k <fskp.key>, --key <fskp.key>
                        FSKP key file provided to OEM as per keyindex
  -K, --skipfskpkey    Skip using FSKP keyslot and key
  --key-exp <authkey> <enckey>
                        Specifying the expansion auth key file and expansion enc key file
                        <authkey> <enckey>
  -p <pkc.key>, --pkckey <pkc.key>
                        Provide PKC Key file. Flash PKC secured image.
  -r {emmc,ufs,spi}, --rpmb {emmc,ufs,spi}
                        do RPMB Key Provisioning on given storage
  -s, --skipconfirmation
                        skip confirmation message while fuse burning
  -S {TA977SA,TA983SA}, --sku {TA977SA,TA983SA}
                        set target sku. eg. TA970SA or TA977SA
  -t, --test            perform test operation, do not burn fuses (default option).
  -u, --skipuid        skip querying UID of the target
  -v [VERBOSE], --verbose [VERBOSE]
                        Enable verbose prints
  -V, --version        Print FSKP script version
  -P <directory path>, --prebuilt <directory path>
                        Pick prebuilt blob from <directory path> and do not generate
  --fskp-blob-out FSKP_BLOB_OUT
                        Only generate fskp blob at specified output directory.
  --multi-blob KDK_DATABASE
                        The kdk fuse database
</syntaxhighlight>
</syntaxhighlight>


A file named rsa_priv.pem should be in the directory. To generate the Public key hash, the tegrasign_v3.py script can be used to generate it, use this command from the keys directory:
<syntaxhighlight lang="bash">
./tegrasign_v3.py --pubkeyhash rsa_priv.pubkey rsa_priv.hash --key rsa_priv.pem
</syntaxhighlight>


{{review|synthesise the info from the portal|lleon}}
the output looks like the following:


<syntaxhighlight lang="bash">
Key size is 384 bytes
Saving pkc public key in rsa_priv.pubkey
Sha saved in pcp.sha
tegra-fuse format (big-endian): 0x513a1d8764dbd5d700932d18db4f48da4c13094b4986660c4525d69ef2307ceaba65ddec675bacc8bbeb2c91d31f1e7fb98be4472a354010ff7dea49510b7b48
</syntaxhighlight>


make sure to save the result because it is going to be need on the fuse configuration file explained below.


* pongo lo de nvidia portal?
Now, the secure boot key is randomly generated with a size of 32 bits. Specifically, the Orin SoC requires an SBK key of eight 32-bit words. You can use the following commands to generate it:
* here will be specified that these is for an ubuntu system
 
* here will be specified also that secure boot ends at the bootloader (UEFI) so after this comes UEFI secure Boot.
<syntaxhighlight lang="bash">
SBK_0=$(openssl rand -hex 4)
SBK_1=$(openssl rand -hex 4)
SBK_2=$(openssl rand -hex 4)
SBK_3=$(openssl rand -hex 4)
SBK_4=$(openssl rand -hex 4)
SBK_5=$(openssl rand -hex 4)
SBK_6=$(openssl rand -hex 4)
SBK_7=$(openssl rand -hex 4)
SBK_KEY=$(echo "0x${SBK_0} 0x${SBK_1} 0x${SBK_2} 0x${SBK_3} 0x${SBK_4} 0x${SBK_5} 0x${SBK_6}
0x${SBK_7}")
echo "${SBK_KEY}" > sbk.key
SBK_KEY_XML=$(echo "0x${SBK_0}${SBK_1}${SBK_2}${SBK_3}${SBK_4}${SBK_5}${SBK_6}${SBK_7}")
echo "${SBK_KEY_XML}" > sbk_xml.key
</syntaxhighlight>
 
A sbk.key and a sbk_xml.key file are now in the directory. the second one has the value that is going to be used in the fuse configuration file.
 
In this case we use openssl to generate the 8 random 32 byte words. It is used because it's a widely adopted, open-source cryptographic toolkit that provides robust functionality for securing communications and data. But you can use the tool of your choice.
 
The next step is to create the fuse configuration file. The fuse configuration file is a xml file  that states that which fuse is burned with x value. It has three main tags which are name, size and value. In the same order, the tags are for the fuse name, its size in bytes and the value to be burned on to the fuse. There is a list of fuses on the Orin SoCs, but we are going to use only the PublicKeyHash, SecureBootKey and BootSecurityInfo fuses. For reference, below is the Jetson Orin reference configuration file for your reference:
 
<syntaxhighlight lang="bash">
<genericfuse MagicId="0x45535546" version="1.0.0">
    <!-- <fuse name="OdmId" size="8" value="0xFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="OdmInfo" size="4" value="0xFFFF"/> -->
    <!-- <fuse name="ArmJtagDisable" size="4" value="0x1"/> -->
    <!-- <fuse name="DebugAuthentication" size="4" value="0x1F"/> -->
    <!-- <fuse name="CcplexDfdAccessDisable" size="4" value="0x1"/> -->
    <!-- <fuse name="ReservedOdm0" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="ReservedOdm1" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="ReservedOdm2" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="ReservedOdm3" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="OdmLock" size="4" value="0xF"/> -->
    <!-- <fuse name="ReservedOdm4" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="ReservedOdm5" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="ReservedOdm6" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="ReservedOdm7" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="OptInEnable" size="4" value="0x1"/> -->
    <!-- <fuse name="SwReserved" size="4" value="0xFFFFFF"/> -->
    <!-- <fuse name="BootDevInfo" size="4" value="0xFFFFFF"/> -->
    <!-- <fuse name="ZeroizeDis" size="4" value="0x1"/> -->
    <!-- <fuse name="PublicKeyHash" size="64" value="0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="PkcPubkeyHash1" size="64" value="0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="PkcPubkeyHash2" size="64" value="0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="EndorseKey" size="68" value="0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="SecureBootKey" size="32" value="0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="Kdk0" size="32" value="0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="PscOdmStatic" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="OemK1" size="32" value="0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="OemK2" size="32" value="0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"/> -->
    <!-- <fuse name="BootSecurityInfo" size="4" value="0xFFFFFFFF"/> -->
    <!-- <fuse name="SecurityMode" size="4" value="0x1"/> -->
</genericfuse>
</syntaxhighlight>
 
It is also important to check the [https://developer.download.nvidia.com/assets/embedded/secure/jetson/agx_orin/Jetson-Orin-Fuse-Specification_DA-10877-001v1.4.pdf?__token__=exp=1742448417~hmac=d2e6139780a4fc1fed9eb010099f9002929c35437006cd2a532ce03d5c41cbfd&t=eyJscyI6ImdzZW8iLCJsc2QiOiJodHRwczovL3d3dy5nb29nbGUuY29tLyJ9 Jetson Orin Fuse Specification: Application Note] to get information of the fuses being burned.
 
Create and open a fuse_config.xml file with your favourite text editor and add the fuse burning data. In our case it looks like the following. As a note MagicId of “0x45535546” is used by the target-binary and must not be changed.:
 
<syntaxhighlight lang="bash">
<genericfuse MagicId="0x45535546" version="1.0.0">
    <fuse name="PublicKeyHash" size="64" value="0x99a6b7d25ffd5d7cc49bf2612d01d7fe58b5121f9c473748728232bc114c25ae2415d56666157c79fc9bf0e3b4445344ff8af51a64f334289912cdff7414fa00"/>
    <fuse name="SecureBootKey" size="32" value="0xf4d8f0c3180f8b2b430d89e1eb0d600c01f99be7a3e9045d4b27d621de571d57"/>
    <fuse name="BootSecurityInfo" size="4" value="0x9"/>
</genericfuse>
</syntaxhighlight>
 
With the fuse data generated, we can proceed with the encryption of it. In this process we will also activate the decryption of the fuse blob (fuse data encrypted) and the fuse burning in the board.
 
<syntaxhighlight lang="bash">
sudo ./fskp_fuseburn.py -b -f ~/work/devdir/security-features-RnD/nvidia-jetson4/Linux_for_Tegra/keys/fuse_config.xml -i 63 --key-exp fskp_ak.bin fskp_ek.bin --fskpcfg fskp_conf.txt -g out/ -c 0x23 -B ~/work/devdir/security-features-RnD/nvidia-jetson4/Linux_for_Tegra/jetson-orin-nano-devkit.conf --board-spec orinnano-board-spec.txt -v
</syntaxhighlight>
 
<syntaxhighlight lang="bash">
sudo ./fskp_fuseburn.py --board-spec orinnano-board-spec.txt -P ./out -b -c 0x23 -B ~/work/devdir/security-features-RnD/nvidia-jetson4/Linux_for_Tegra/jetson-orin-nano-devkit.conf
</syntaxhighlight>


=== UEFI Secure Boot ===
=== UEFI Secure Boot ===
174

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.