Changes

2,639 bytes added ,  17:53, 29 January 2021
Secure BootROM
Line 4,939: Line 4,939:     
==== SEC1 ====
 
==== SEC1 ====
Unknown. Marked as "RESERVED".
+
Only available in Falcon v6+ CPUs, marked as "RESERVED" for v5.
    
==== IMB1 ====
 
==== IMB1 ====
Unknown. Marked as "RESERVED".
+
Only available in Falcon v6+ CPUs, marked as "RESERVED" for v5.
    
==== DMB1 ====
 
==== DMB1 ====
Unknown. Marked as "RESERVED".
+
Only available in Falcon v6+ CPUs, marked as "RESERVED" for v5.
   −
=== Heavy Secure Mode ===
+
=== Secure BootROM ===
==== Entry ====
+
Certain Falcon CPUs may have an optional "Secure BootROM", but contrary to the common purpose of bootrom code, this doesn't execute while booting the CPU. In fact, being a microprocessor, Falcon is designed to execute user supplied code right off the bat in a clean slate state. However, Falcon can be paired with a [[#SCP|secure co-processor]] and provide a cryptosystem for any hardware block that may require it, originating what is known as a "secretful" unit.
From non-secure mode, upon jumping to a page marked as secret, a secret fault occurs. This causes the CPU to verify the region specified in $cauth against the MAC loaded in $c6. If the comparison is successful, the valid bit (bit0) is set on all pages in the $cauth region, and $pc is set to the base of the $cauth region. If the comparsion fails, the CPU is halted.
     −
==== Exit ====
+
Secretful Falcon CPUs have [[#TSEC_FALCON_HWCFG1|TSEC_FALCON_HWCFG1_SECURITY_MODEL]] set to 3, which means they support "Heavy Secure" mode (or "HS" for short). While in HS mode, the Falcon's DMEM and IMEM regions are protected from read and write operations, which effectively hides code and data from attackers.
The CPU automatically goes back to non-secure mode when returning back into non-secret pages. When this happens, the valid bit (bit0) in the TLB flags is cleared for all secret pages.
+
 
 +
Entering HS mode first requires uploading code marked as "secure" to Falcon, which can be done from MMIO using [[#TSEC_FALCON_IMEMC|TSEC_FALCON_IMEMC]] with the [[#TSEC_FALCON_IMEMC|TSEC_FALCON_IMEMC_SECURE]] bit set. Upon jumping to a page marked as secret, the [[#TSEC_FALCON_EXCI|INV_INS]] exception is raised which tells the Falcon to start executing the secure bootrom code.
 +
 
 +
The secure bootrom lives in a hidden ROM region, instead of IMEM, and is mapped as --x at address 0. On Falcon v5 CPUs its size is 0x367 bytes.
 +
 
 +
==== Initialization ====
 +
The first instructions of the secure bootrom simply save each [[#REG0-REG15|GPR]] to the stack and check the contents of the [[#SEC|SEC SPR]].
 +
 
 +
==== Authentication ====
 +
The main purpose of the secure bootrom is to authenticate the code pages marked as "secure". This is done by first extracting the base address and size of the region to authenticate from the [[#SEC|SEC SPR]], then calculating a signature over this region and finally comparing it to the value of the [[#SCP|SCP]] register $c6.
 +
 
 +
If the comparison is successful, bit 18 of [[#SEC|SEC SPR]] is set (which is mirrored in [[#TSEC_FALCON_SVEC_SPR|TSEC_FALCON_SVEC_SPR]]), the signature comparison result in [[#TSEC_SCP_STAT1|TSEC_SCP_STAT1]] is set to 3 and each page from the region to authenticate is marked as valid.
 +
 
 +
If the comparison fails, an exception is raised, but since the secure bootrom is already running from an exception context, this causes a double exception state which forces the CPU to halt.
 +
 
 +
Below is the authentication algorithm's pseudocode:
 +
<syntaxhighlight>
 +
...
 +
// This runs in a loop for each 0x100 bytes page.
 +
cs0begin 0x03
 +
cxsin $c4
 +
cenc $c3 $c5
 +
cxor $c5 $c3
 +
ckeyreg $c4
 +
cxor $c5 $c5
 +
cs0exec 0x11
 +
...
 +
// Use secret 0x01 as key and $c7 as seed.
 +
csecret $c3 1
 +
ckeyreg $c3
 +
cenc $c3 $c7
 +
ckeyreg $c3
 +
cenc $c4 $c5
 +
csigcmp $c4 $c6
 +
...
 +
</syntaxhighlight>
 +
 
 +
==== Decryption ====
 +
If bit 17 is set in the [[#SEC|SEC SPR]], the secure bootrom will additionally attempt to decrypt the region to authenticate.
   −
==== Implementation ====
+
Below is the decryption algorithm's pseudocode:
Under certain circumstances, it is possible to observe [[#sigcmp|sigcmp]] being briefly written to [[#TSEC_SCP_CMD|TSEC_SCP_CMD]] as "csigcmp $c4 $c6" while the opcodes in [[#TSEC_SCP_STAT2|TSEC_SCP_STAT2]] are set to "cxsin" and "csigcmp", respectively.
+
<syntaxhighlight>
 +
...
 +
// Use secret 0x06 as key.
 +
cs0begin 0x03
 +
cxsin $c3
 +
cdec $c4 $c3
 +
cxsout $c4
 +
csecret $c5 0x06
 +
ckexp $c5 $c5
 +
cs0exec 0x10
 +
ckeyreg $c5
 +
...
 +
</syntaxhighlight>
   −
Via [[#TSEC_SCP_DBG0|TSEC_SCP_DBG0]] it can be observed that a 3-sized macro sequence is loaded into cs0 during a secure mode transition.
+
==== Exit ====
 +
The secure bootrom finishes by restoring each [[#REG0-REG15|GPR]] from stack and returning from the exception state. This will result in the authenticated code region being executed in HS mode until the current [[#PC|PC]] points to an address outside of the authenticated region. When this happens, each page from the authenticated region is automatically marked as invalid without any involvement of the secure bootrom, meaning that the secure bootrom is only invoked when entering HS mode.
    
== SCP ==
 
== SCP ==
"SCP" (Secure Co-Processor) is a proprietary coprocessor which can be found inside every [[#Falcon|Falcon]] that supports [[#Heavy_Secure_Mode|Heavy Secure Mode]]. On the Tegra X1 these are TSECA, TSECB, NVDEC and the GPU's PMU.
+
"SCP" (Secure Co-Processor) is a proprietary coprocessor which can be found inside every [[#Falcon|Falcon]] that supports [[#Secure BootROM|Heavy Secure Mode]]. On the Tegra X1 these are TSECA, TSECB, NVDEC and the GPU's PMU.
    
=== Hardware ===
 
=== Hardware ===
Line 5,120: Line 5,170:     
=== Secrets ===
 
=== Secrets ===
[[#Heavy_Secure_Mode|Heavy Secure Mode]] has access to 64 128-bit keys which are burned at factory. These keys can be loaded using the $csecret instruction which takes the target crypto register and the key index as arguments.
+
[[#Secure BootROM|Heavy Secure Mode]] has access to 64 128-bit keys which are burned at factory. These keys can be loaded using the $csecret instruction which takes the target crypto register and the key index as arguments.
    
Secrets are specific to each Falcon unit with the exception of secret 0x3F. This secret is effectively empty (all zeros), but is configured to be overwritten with the KFUSE private key once the KFUSE clock is enabled. The KFUSE private key is console-unique.
 
Secrets are specific to each Falcon unit with the exception of secret 0x3F. This secret is effectively empty (all zeros), but is configured to be overwritten with the KFUSE private key once the KFUSE clock is enabled. The KFUSE private key is console-unique.