TSEC: Difference between revisions

No edit summary
Line 1,171: Line 1,171:
|-
|-
| 6
| 6
| FALCON_CPUCTL_SCP_UNK
| FALCON_CPUCTL_START_SCP_LS
|}
|}


Line 1,367: Line 1,367:
  1: Light Secure
  1: Light Secure
  2: Heavy Secure
  2: Heavy Secure
|-
| 4-5
| FALCON_SCTL_OLD_SEC_MODE
0: Non-secure
1: Light Secure
2: Heavy Secure
|-
| 12-13
| Unknown
|-
| 14
| Initialize the transition to LS mode
|}
|}


Line 1,475: Line 1,487:
!  Description
!  Description
|-
|-
| 0-7
| 0-3
| Crypto fuc5 destination register or immediate value
| Crypto fuc5 destination register or immediate value
|-
|-
| 8-15
| 8-13
| Crypto fuc5 source register or immediate value
| Crypto fuc5 source register or immediate value
|-
|-
| 20-24
| 20-24
| Crypto fuc5 operation
| Crypto fuc5 operation
  0x0:  none (fuc5 opcode 0x00)  
  0x0:  nop (fuc5 opcode 0x00)  
  0x1:  cmov (fuc5 opcode 0x84)
  0x1:  cmov (fuc5 opcode 0x84)
  0x2:  cxsin (fuc5 opcode 0x88) or xdst (with cxset)
  0x2:  cxsin (fuc5 opcode 0x88) or xdst (with cxset)
  0x3:  cxsout (fuc5 opcode 0x8C) or xdld (with cxset)  
  0x3:  cxsout (fuc5 opcode 0x8C) or xdld (with cxset)  
  0x4:  crng (fuc5 opcode 0x90)
  0x4:  crnd (fuc5 opcode 0x90)
  0x5:  cs0begin (fuc5 opcode 0x94)
  0x5:  cs0begin (fuc5 opcode 0x94)
  0x6:  cs0exec (fuc5 opcode 0x98)
  0x6:  cs0exec (fuc5 opcode 0x98)
Line 1,508: Line 1,520:
  0x17: csigenc (fuc5 opcode 0xDC)
  0x17: csigenc (fuc5 opcode 0xDC)
  0x18: csigclr (fuc5 opcode 0xE0)
  0x18: csigclr (fuc5 opcode 0xE0)
|-
| 28
| Unknown
|-
|-
| 31
| 31
Line 1,738: Line 1,753:
|}
|}


== Authenticated Mode ==
== SCP ==
===== Entry =====
Part of the information here (which hasn't made it into envytools documentation yet) was shared by [https://wiki.0x04.net/wiki/Marcin_Ko%C5%9Bcielnicki mwk] from reverse engineering falcon processors over the years.
 
=== Authenticated Mode ===
==== Entry ====
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.
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 =====
==== Exit ====
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.
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.


===== Implementation =====
==== Implementation ====
Under certain circumstances, it is possible to observe [[#csigauth|csigauth]] being briefly written to [[#TSEC_SCP_INSN_STAT|TSEC_SCP_INSN_STAT]] as "csigauth $c4 $c6" while the opcodes in [[#TSEC_SCP_AES_STAT|TSEC_SCP_AES_STAT]] are set to "cxsin" and "csigauth", respectively.
Under certain circumstances, it is possible to observe [[#csigauth|csigauth]] being briefly written to [[#TSEC_SCP_INSN_STAT|TSEC_SCP_INSN_STAT]] as "csigauth $c4 $c6" while the opcodes in [[#TSEC_SCP_AES_STAT|TSEC_SCP_AES_STAT]] are set to "cxsin" and "csigauth", respectively.


Via [[#TSEC_SCP_SEQ0_STAT|TSEC_SCP_SEQ0_STAT]] it can be observed that a 3-sized macro sequence is loaded into cs0 during a secure mode transition.
Via [[#TSEC_SCP_SEQ0_STAT|TSEC_SCP_SEQ0_STAT]] it can be observed that a 3-sized macro sequence is loaded into cs0 during a secure mode transition.


== Crypto processing ==
=== Operations ===
Part of the information here (which hasn't made it into envytools documentation yet) was shared by [https://wiki.0x04.net/wiki/Marcin_Ko%C5%9Bcielnicki mwk] from reverse engineering falcon processors over the years.
 
=== cauth ===
$cauth is a special purpose register in the CPU.
 
{| class="wikitable" border="1"
!  Bits
!  Description
|-
| 0-7 || Start of region to authenticate (in 0x100 pages)
|-
| 8-15 || Unused
|-
| 16 || Use secret xfers (?)
|-
| 17 || Region is signed and encrypted and double the size (?)
|-
| 18 ||
|-
| 19 ||
|-
| 20-23 || Unused
|-
| 31-24 || Size of region to authenticate (in 0x100 pages)
|}
 
== SCP operations ==
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
!  Opcode
!  Opcode
Line 1,837: Line 1,827:
| 0x18 || csigenc || $cX || $cY || <code>if (has_sig) $cX = aes_enc(current_sig, $cY);</code> || ?
| 0x18 || csigenc || $cX || $cY || <code>if (has_sig) $cX = aes_enc(current_sig, $cY);</code> || ?
|}
|}
==== csigauth ====
<code>00000000: f5 3c XY d8    csigauth $cY $cX</code>
Takes 2 crypto registers as operands and is automatically executed when jumping to a code region previously uploaded as secret. This instruction does not work in secure mode.
==== csigclr ====
<code>00000000: f5 3c 00 e0    csigclr</code>
This instruction takes no operands and appears to clear the saved cauth signature used by the csigenc instruction.
==== cchmod ====
<code>00000000: f5 3c XY a8    cchmod $cY 0X</code> or <code>00000000: f5 3c XY a9    cchmod $cY 1X</code>
This instruction takes a crypto register and a 5 bit immediate value which represents the [[#ACL|ACL]] mask to set.
==== crnd ====
<code>00000000: f5 3c 0X 90    crnd $cX</code>
This instruction initializes a crypto register with random data.
Executing this instruction only succeeds if the TRNG is enabled for the SCP, which requires taking the following steps:
* Write 0x7FFF to TSEC_TRNG_CLKDIV.
* Write 0x3FF0000 to TSEC_TRNG_UNK0.
* Write 0xFF00 to TSEC_TRNG_UNK7.
* Write 0x1000 to [[#TSEC_SCP_CTL_TRNG|TSEC_SCP_CTL_TRNG]].
Otherwise it hangs forever.


=== ACL ===
=== ACL ===
Line 1,861: Line 1,879:
Spilling a $cX to DMEM using xdld instruction is allowed if (ACL($cX) & 2) or (ACL($cX) & 8), for secure and insecure mode respectively.
Spilling a $cX to DMEM using xdld instruction is allowed if (ACL($cX) & 2) or (ACL($cX) & 8), for secure and insecure mode respectively.


=== csigauth ===
Loading a secret into $cX sets a per-secret ACL, unconditionally.
<code>00000000: f5 3c XY d8    csigauth $cY $cX</code>


Takes 2 crypto registers as operands and is automatically executed when jumping to a code region previously uploaded as secret. This instruction does not work in secure mode.
=== cauth ===
$cauth is a special purpose register in the CPU.


=== csigclr ===
{| class="wikitable" border="1"
<code>00000000: f5 3c 00 e0    csigclr</code>
!  Bits
 
!  Description
This instruction takes no operands and appears to clear the saved cauth signature used by the csigenc instruction.
|-
 
| 0-7 || Start of region to authenticate (in 0x100 pages)
=== cchmod ===
|-
<code>00000000: f5 3c XY a8    cchmod $cY 0X</code> or <code>00000000: f5 3c XY a9    cchmod $cY 1X</code>
| 8-15 || Unused
 
|-
This instruction takes a crypto register and a 5 bit immediate value.
| 16 || Use secret xfers (?)
 
|-
=== crng ===
| 17 || Region is encrypted (?)
<code>00000000: f5 3c 0X 90    crng $cX</code>
|-
 
| 18 || Unknown
This instruction initializes a crypto register with random data.
|-
 
| 19 || Unknown
Executing this instruction only succeeds if the TRNG is enabled for the SCP, which requires taking the following steps:
|-
* Write 0x7FFF to TSEC_TRNG_CLKDIV.
| 20-23 || Unused
* Write 0x3FF0000 to TSEC_TRNG_UNK0.
|-
* Write 0xFF00 to TSEC_TRNG_UNK7.
| 31-24 || Size of region to authenticate (in 0x100 pages)
* Write 0x1000 to [[#TSEC_SCP_CTL_TRNG|TSEC_SCP_CTL_TRNG]].
|}
 
Otherwise it hangs forever.


=== cxset ===
=== cxset ===
Line 1,919: Line 1,935:


{| class=wikitable
{| class=wikitable
! Index || Notes || Console-unique
! Index || ACL || Console-unique || Notes
|-
| 0x00 || 0x07 || No || Used by [[TSEC_Firmware#Keygen|Keygen]], nvhost_tsec, nvhost_nvdec_bl020_prod, nvhost_nvdec020_prod, nvhost_nvdec020_ns and acr_ucode firmwares.
|-
| 0x01 || 0x01 || || Used by nvhost_nvdec_bl020_prod firmware.
|-
| 0x02 || 0x01 || ||
|-
| 0x03 || 0x05 || || Used by nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares.
|-
| 0x04 || 0x01 || || Used by nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares.
|-
| 0x05 || 0x07 || || Used by nvhost_tsec, nvhost_nvdec_bl020_prod, nvhost_nvdec020_prod, nvhost_nvdec020_ns and acr_ucode firmwares.
|-
| 0x06 || 0x05 || ||
|-
| 0x07 || 0x05 || || Used by [6.0.0+] nvhost_tsec firmware.
|-
| 0x08 || 0x01 || ||
|-
| 0x09 || 0x07 || || Used by nvhost_tsec firmware.
|-
| 0x0A || 0x05 || ||
|-
| 0x0B || 0x01 || || Used by nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares.
|-
| 0x0C || 0x07 || ||
|-
| 0x0D || 0x05 || ||
|-
| 0x0E || 0x01 || ||
|-
| 0x0F || 0x07 || || Used by nvhost_tsec firmware.
|-
| 0x10 || 0x05 || || Used by [1.0.0-5.1.0] nvhost_tsec firmware.
|-
| 0x11 || 0x01 || ||
|-
| 0x12 || 0x07 || ||
|-
| 0x13 || 0x05 || ||
|-
| 0x14 || 0x01 || ||
|-
| 0x15 || 0x07 || || Used by nvhost_nvdec_bl020_prod, [5.0.0+] nvhost_nvdec020_prod, [5.0.0+] nvhost_nvdec020_ns and [6.0.0+] nvhost_tsec firmwares.
|-
| 0x16 || 0x05 || ||
|-
| 0x17 || 0x01 || ||
|-
| 0x18 || 0x07 || ||
|-
| 0x19 || 0x05 || ||
|-
| 0x1A || 0x01 || ||
|-
| 0x1B || 0x07 || ||
|-
| 0x1C || 0x05 || ||
|-
| 0x1D || 0x01 || ||
|-
| 0x1E || 0x07 || ||
|-
| 0x1F || 0x05 || ||
|-
| 0x20 || 0x01 || ||
|-
| 0x21 || 0x07 || ||
|-
| 0x22 || 0x05 || ||
|-
| 0x23 || 0x01 || ||
|-
| 0x24 || 0x07 || ||
|-
| 0x25 || 0x05 || ||
|-
| 0x26 || 0x01 || No || Used by [[TSEC_Firmware#KeygenLdr|KeygenLdr]].
|-
| 0x27 || 0x07 || ||
|-
| 0x28 || 0x05 || ||
|-
| 0x29 || 0x01 || ||
|-
| 0x2A || 0x07 || ||
|-
| 0x2B || 0x05 || ||
|-
| 0x2C || 0x01 || ||
|-
| 0x2D || 0x07 || ||
|-
| 0x2E || 0x05 || ||
|-
| 0x2F || 0x01 || ||
|-
| 0x30 || 0x07 || ||
|-
| 0x31 || 0x05 || ||
|-
|-
| 0x00 || Used by [[TSEC_Firmware#Keygen|Keygen]], nvhost_tsec, nvhost_nvdec_bl020_prod, nvhost_nvdec020_prod, nvhost_nvdec020_ns and acr_ucode firmwares. || No
| 0x32 || 0x01 || ||
|-
|-
| 0x01 || Used by nvhost_nvdec_bl020_prod firmware. ||
| 0x33 || 0x07 || ||
|-
|-
| 0x03 || Used by nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares. ||
| 0x34 || 0x05 || ||
|-
|-
| 0x04 || Used by nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares. ||
| 0x35 || 0x01 || ||
|-
|-
| 0x05 || Used by nvhost_tsec, nvhost_nvdec_bl020_prod, nvhost_nvdec020_prod, nvhost_nvdec020_ns and acr_ucode firmwares. ||
| 0x36 || 0x07 || ||
|-
|-
| 0x07 || Used by [6.0.0+] nvhost_tsec firmware. ||
| 0x37 || 0x05 || ||
|-
|-
| 0x09 || Used by nvhost_tsec firmware. ||
| 0x38 || 0x01 || ||
|-
|-
| 0x0B || Used by nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares. ||
| 0x39 || 0x07 || ||
|-
|-
| 0x0F || Used by nvhost_tsec firmware. ||
| 0x3A || 0x05 || ||
|-
|-
| 0x10 || Used by [1.0.0-5.1.0] nvhost_tsec firmware. ||
| 0x3B || 0x01 || ||
|-
|-
| 0x15 || Used by nvhost_nvdec_bl020_prod, [5.0.0+] nvhost_nvdec020_prod, [5.0.0+] nvhost_nvdec020_ns and [6.0.0+] nvhost_tsec firmwares. ||
| 0x3C || 0x07 || || Used by nvhost_tsec firmware.  
|-
|-
| 0x26 || Used by [[TSEC_Firmware#KeygenLdr|KeygenLdr]]. || No
| 0x3D || 0x05 || ||
|-
|-
| 0x3C || Used by nvhost_tsec firmware. ||
| 0x3E || 0x01 || ||
|-
|-
| 0x3F || Used by [[TSEC_Firmware#Keygen|Keygen]], nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares. || Yes
| 0x3F || 0x01 || Yes || Used by [[TSEC_Firmware#Keygen|Keygen]], nvhost_tsec, nvhost_nvdec020_prod and nvhost_nvdec020_ns firmwares.  
|}
|}