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. |
| |} | | |} |