TSEC: Difference between revisions
6.2.0 changes |
No edit summary |
||
Line 5: | Line 5: | ||
== Registers == | == Registers == | ||
Registers from 0x54500000 to 0x54501000 are used to configure | Registers from 0x54500000 to 0x54501000 are used to configure the host interface (HOST1X). | ||
Registers from 0x54501000 to 0x54502000 are a MMIO window for communicating with the Falcon microprocessor. From this range, the subset of registers from 0x54501400 to 0x54501FE8 are specific to the TSEC. | Registers from 0x54501000 to 0x54502000 are a MMIO window for communicating with the Falcon microprocessor. From this range, the subset of registers from 0x54501400 to 0x54501FE8 are specific to the TSEC and are subdivided into: | ||
* 0x54501400 to 0x54501500: SCP (secure crypto processor?). | |||
* 0x54501500 to 0x54501600: Unknown. | |||
* 0x54501600 to 0x54501700: MCCIF (Memory Controller Client Interface). | |||
* 0x54501700 to 0x54501800: DMA. | |||
* 0x54501800 to 0x54501900: TEGRA (miscellaneous interfaces). | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 80: | Line 85: | ||
| [[#FALCON_IRQDEST|FALCON_IRQDEST]] | | [[#FALCON_IRQDEST|FALCON_IRQDEST]] | ||
| 0x5450101C | | 0x5450101C | ||
| 0x04 | |||
|- | |||
| FALCON_PERIODIC_PERIOD | |||
| 0x54501020 | |||
| 0x04 | |||
|- | |||
| FALCON_PERIODIC_TIME | |||
| 0x54501024 | |||
| 0x04 | |||
|- | |||
| FALCON_PERIODIC_ENABLE | |||
| 0x54501028 | |||
| 0x04 | |||
|- | |||
| FALCON_TIME_LOW | |||
| 0x5450102C | |||
| 0x04 | |||
|- | |||
| FALCON_TIME_HIGH | |||
| 0x54501030 | |||
| 0x04 | |||
|- | |||
| FALCON_WATCHDOG_TIME | |||
| 0x54501034 | |||
| 0x04 | |||
|- | |||
| FALCON_WATCHDOG_ENABLE | |||
| 0x54501038 | |||
| 0x04 | | 0x04 | ||
|- | |- | ||
Line 106: | Line 139: | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_CMDCTX | ||
| | | 0x54501058 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_STATUS_MASK | ||
| | | 0x5450105C | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_VM_SUPERVISOR | ||
| | | 0x54501060 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_FIFO_DATA | ||
| | | 0x54501064 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_FIFO_CMD | ||
| | | 0x54501068 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_FIFO_DATA_WR | ||
| | | 0x5450106C | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_FIFO_OCCUPIED | ||
| | | 0x54501070 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_FIFO_ACK | ||
| | | 0x54501074 | ||
| 0x04 | |||
|- | |||
| FALCON_FIFO_LIMIT | |||
| 0x54501078 | |||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_SUBENGINE_RESET | ||
| | | 0x5450107C | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_SCRATCH2 | ||
| | | 0x54501080 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_SCRATCH3 | ||
| | | 0x54501084 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_PM_TRIGGER | ||
| | | 0x54501088 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_PM_MODE | ||
| | | 0x5450108C | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_DEBUG1 | ||
| | | 0x54501090 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_DEBUGINFO | ||
| | | 0x54501094 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_BREAKPOINT0 | ||
| | | 0x54501098 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_BREAKPOINT1 | ||
| | | 0x5450109C | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | FALCON_CGCTL | ||
| | | 0x545010A0 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_CODE_INDEX | | FALCON_ENGCTL | ||
| 0x54501180 | | 0x545010A4 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_CODE | | FALCON_PM_SEL | ||
| 0x54501184 | | 0x545010A8 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_CODE_VIRT_ADDR | | FALCON_HOST_IO_INDEX | ||
| 0x54501188 | | 0x545010AC | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_DATA_INDEX0 | | [[#FALCON_CPUCTL|FALCON_CPUCTL]] | ||
| 0x545011C0 | | 0x54501100 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_DATA0 | | [[#FALCON_BOOTVEC|FALCON_BOOTVEC]] | ||
| 0x545011C4 | | 0x54501104 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_DATA_INDEX1 | | FALCON_HWCFG | ||
| 0x545011C8 | | 0x54501108 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_DATA1 | | [[#FALCON_DMACTL|FALCON_DMACTL]] | ||
| 0x545011CC | | 0x5450110C | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_DATA_INDEX2 | | [[#FALCON_DMATRFBASE|FALCON_DMATRFBASE]] | ||
| 0x545011D0 | | 0x54501110 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| FALCON_DATA2 | | [[#FALCON_DMATRFMOFFS|FALCON_DMATRFMOFFS]] | ||
| 0x54501114 | |||
| 0x04 | |||
|- | |||
| [[#FALCON_DMATRFCMD|FALCON_DMATRFCMD]] | |||
| 0x54501118 | |||
| 0x04 | |||
|- | |||
| [[#FALCON_DMATRFFBOFFS|FALCON_DMATRFFBOFFS]] | |||
| 0x5450111C | |||
| 0x04 | |||
|- | |||
| FALCON_DMATRFSTAT | |||
| 0x54501120 | |||
| 0x04 | |||
|- | |||
| FALCON_CRYPTTRFSTAT | |||
| 0x54501124 | |||
| 0x04 | |||
|- | |||
| FALCON_CPUSTAT | |||
| 0x54501128 | |||
| 0x04 | |||
|- | |||
| FALCON_HWCFG_ALIAS | |||
| 0x5450112C | |||
| 0x04 | |||
|- | |||
| FALCON_CPUCTL_ALIAS | |||
| 0x54501130 | |||
| 0x04 | |||
|- | |||
| FALCON_TLB_CMD | |||
| 0x54501140 | |||
| 0x04 | |||
|- | |||
| FALCON_TLB_CMD_RES | |||
| 0x54501144 | |||
| 0x04 | |||
|- | |||
| FALCON_BRANCH_HISTORY_CTRL | |||
| 0x54501148 | |||
| 0x04 | |||
|- | |||
| FALCON_BRANCH_HISTORY_PC | |||
| 0x5450114C | |||
| 0x04 | |||
|- | |||
| FALCON_IMFILLRNG0 | |||
| 0x54501150 | |||
| 0x04 | |||
|- | |||
| FALCON_IMFILLRNG1 | |||
| 0x54501154 | |||
| 0x04 | |||
|- | |||
| FALCON_IMFILLCTL | |||
| 0x54501158 | |||
| 0x04 | |||
|- | |||
| FALCON_EXTERRWIN | |||
| 0x54501160 | |||
| 0x04 | |||
|- | |||
| FALCON_EXTERRCFG | |||
| 0x54501164 | |||
| 0x04 | |||
|- | |||
| FALCON_EXTERRADDR | |||
| 0x54501168 | |||
| 0x04 | |||
|- | |||
| FALCON_EXTERRSTAT | |||
| 0x5450116C | |||
| 0x04 | |||
|- | |||
| FALCON_CG2 | |||
| 0x5450117C | |||
| 0x04 | |||
|- | |||
| FALCON_CODE_INDEX | |||
| 0x54501180 | |||
| 0x04 | |||
|- | |||
| FALCON_CODE | |||
| 0x54501184 | |||
| 0x04 | |||
|- | |||
| FALCON_CODE_VIRT_ADDR | |||
| 0x54501188 | |||
| 0x04 | |||
|- | |||
| FALCON_DATA_INDEX0 | |||
| 0x545011C0 | |||
| 0x04 | |||
|- | |||
| FALCON_DATA0 | |||
| 0x545011C4 | |||
| 0x04 | |||
|- | |||
| FALCON_DATA_INDEX1 | |||
| 0x545011C8 | |||
| 0x04 | |||
|- | |||
| FALCON_DATA1 | |||
| 0x545011CC | |||
| 0x04 | |||
|- | |||
| FALCON_DATA_INDEX2 | |||
| 0x545011D0 | |||
| 0x04 | |||
|- | |||
| FALCON_DATA2 | |||
| 0x545011D4 | | 0x545011D4 | ||
| 0x04 | | 0x04 | ||
Line 274: | Line 423: | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK0 | ||
| 0x54501400 | | 0x54501400 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK1 | ||
| 0x54501404 | | 0x54501404 | ||
| 0x04 | | 0x04 | ||
Line 290: | Line 439: | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK2 | ||
| 0x54501410 | | 0x54501410 | ||
| 0x04 | | 0x04 | ||
Line 298: | Line 447: | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK3 | ||
| 0x54501420 | | 0x54501420 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK4 | ||
| 0x54501428 | | 0x54501428 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK5 | ||
| 0x54501430 | | 0x54501430 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK6 | ||
| 0x54501454 | | 0x54501454 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK7 | ||
| 0x54501458 | | 0x54501458 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK8 | ||
| 0x54501470 | | 0x54501470 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK9 | ||
| 0x54501480 | | 0x54501480 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_SCP_UNK10 | ||
| 0x54501490 | | 0x54501490 | ||
| 0x04 | | 0x04 | ||
Line 366: | Line 515: | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_MCCIF_UNK0 | ||
| 0x54501600 | | 0x54501600 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_MCCIF_FIFOCTRL | ||
| 0x54501604 | | 0x54501604 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_MCCIF_UNK1 | ||
| 0x54501608 | | 0x54501608 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_MCCIF_UNK2 | ||
| 0x5450160C | | 0x5450160C | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_MCCIF_UNK3 | ||
| 0x54501630 | | 0x54501630 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_MCCIF_UNK4 | ||
| 0x54501634 | | 0x54501634 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | TSEC_MCCIF_UNK5 | ||
| 0x54501640 | | 0x54501640 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | [[#TSEC_MCCIF_UNK6|TSEC_MCCIF_UNK6]] | ||
| 0x54501644 | | 0x54501644 | ||
| 0x04 | | 0x04 | ||
|- | |- | ||
| | | [[#TSEC_MCCIF_UNK7|TSEC_MCCIF_UNK7]] | ||
| 0x54501648 | | 0x54501648 | ||
| 0x04 | | 0x04 | ||
Line 586: | Line 735: | ||
| TSEC_SCP_CTL_PKEY_LOADED | | TSEC_SCP_CTL_PKEY_LOADED | ||
|} | |} | ||
=== TSEC_MCCIF_UNK6 === | |||
Used to control accesses to DRAM. | |||
[6.0.0+] The nvhost_tsec firmware sets this register to 0x10 or 0x111110 before reading memory from the GPU UCODE carveout. | |||
=== TSEC_MCCIF_UNK7 === | |||
Used to control accesses to DRAM. | |||
[6.0.0+] The nvhost_tsec firmware sets this register to (data_size << 4) before reading memory from the GPU UCODE carveout. | |||
=== TSEC_DMA_CMD === | === TSEC_DMA_CMD === | ||
Line 792: | Line 951: | ||
deadlock(); | deadlock(); | ||
== | == TSEC key generation == | ||
The TSEC | The TSEC key is generated by reading SOR1 registers modified by the Falcon CPU. | ||
// Clear magic value in host1x scratch space | // Clear magic value in host1x scratch space | ||
*(u32 *)0x50003300 = 0; | *(u32 *)0x50003300 = 0; | ||
// Read TSEC | // Read TSEC key | ||
u32 | u32 tsec_key[4]; | ||
tsec_key[0] = *(u32 *)NV_SOR_DP_HDCP_BKSV_LSB; | |||
tsec_key[1] = *(u32 *)NV_SOR_TMDS_HDCP_BKSV_LSB; | |||
tsec_key[2] = *(u32 *)NV_SOR_TMDS_HDCP_CN_MSB; | |||
tsec_key[3] = *(u32 *)NV_SOR_TMDS_HDCP_CN_LSB; | |||
// Clear SOR1 registers | // Clear SOR1 registers | ||
Line 813: | Line 972: | ||
out_size = 0x10; | out_size = 0x10; | ||
// Copy back the TSEC | // Copy back the TSEC key | ||
memcpy(out_buf, | memcpy(out_buf, tsec_key, out_size); | ||
[6.2.0+] This is now done inside an encrypted TSEC payload. | [6.2.0+] This is now done inside an encrypted TSEC payload. | ||
Line 860: | Line 1,019: | ||
== Boot == | == Boot == | ||
During this stage, [[#Key data|key data]] is loaded and [[#KeygenLdr|KeygenLdr]] is authenticated, loaded and executed. | During this stage, [[#Key data|key data]] is loaded and [[#KeygenLdr|KeygenLdr]] is authenticated, loaded and executed. | ||
Before returning, this stage writes back to the host (using MMIO registers) and sets the | Before returning, this stage writes back to the host (using MMIO registers) and sets the key used by the first bootloader. | ||
[6.2.0+] During this stage, [[#Key data|key data]] is loaded and execution jumps to [[#Loader|Loader]]. | [6.2.0+] During this stage, [[#Key data|key data]] is loaded and execution jumps to [[#Loader|Loader]]. | ||
Line 876: | Line 1,035: | ||
=== Main === | === Main === | ||
Falcon reads the [[#Key data|key data]] | Falcon reads the [[#Key data|key data]] and then authenticates, loads and executes [[#KeygenLdr|KeygenLdr]] which sets the TSEC key. | ||
u32 boot_base_addr = 0; | u32 boot_base_addr = 0; | ||
u8 key_data_buf[0x7C]; | u8 key_data_buf[0x7C]; | ||
Line 972: | Line 1,131: | ||
} | } | ||
// | // Overwrite the TSEC key in SOR1 registers | ||
// This has no effect because the KeygenLdr locks out the TSEC DMA engine | |||
tsec_set_key(key_data_buf); | |||
return boot_res; | return boot_res; | ||
Line 997: | Line 1,157: | ||
return 0; | return 0; | ||
==== | ==== tsec_set_key ==== | ||
This method takes '''key_data_buf''' as argument and writes | This method takes '''key_data_buf''' (a 16 bytes buffer) as argument and writes its contents to SOR1 registers. | ||
// This is TSEC_MMIO + 0x1000 + (0x1C300 / 0x40) | // This is TSEC_MMIO + 0x1000 + (0x1C300 / 0x40) | ||
*(u32 *)TSEC_DMA_UNK = 0xFFF; | *(u32 *)TSEC_DMA_UNK = 0xFFF; | ||
Line 1,270: | Line 1,430: | ||
else if (key_version == 0x02) // Use HOVI_COMMON_01 | else if (key_version == 0x02) // Use HOVI_COMMON_01 | ||
hovi_key_addr = key_buf + 0x60; | hovi_key_addr = key_buf + 0x60; | ||
else if (key_version == 0x03) // Use empty | else if (key_version == 0x03) // Use debug key (empty) | ||
hovi_key_addr = key_buf + 0x00; | hovi_key_addr = key_buf + 0x00; | ||
else | else | ||
Line 1,560: | Line 1,720: | ||
== Keygen == | == Keygen == | ||
This stage is decrypted by [[#KeygenLdr|KeygenLdr]] using a key generated by encrypting a seed with an hardware secret. It will generate the final TSEC | This stage is decrypted by [[#KeygenLdr|KeygenLdr]] using a key generated by encrypting a seed with an hardware secret. It will generate the final TSEC key. | ||
== Loader == | == Loader == | ||
This stage starts by authenticating and executing [[#KeygenLdr|KeygenLdr]] which in turn authenticates, decrypts and executes [[#Keygen|Keygen]] (both blobs remain unchanged from previous firmware versions). | This stage starts by authenticating and executing [[#KeygenLdr|KeygenLdr]] which in turn authenticates, decrypts and executes [[#Keygen|Keygen]] (both blobs remain unchanged from previous firmware versions). | ||
After the TSEC | After the TSEC key has been generated, execution returns to this stage which then parses and executes [[#Payload|Payload]]. | ||
=== Main === | === Main === | ||
Line 1,774: | Line 1,934: | ||
// fuc5 crypt cauth instruction | // fuc5 crypt cauth instruction | ||
// Set auth_addr to 0x100, auth_size to 0x1300 and | // Set auth_addr to 0x100, auth_size to 0x1300, | ||
// bit 16 (is_secret) and bit 17 (is_encrypted) | |||
cauth((0x02 << 0x10) | (0x01 << 0x10) | (0x1300 << 0x10) | (0x100 >> 0x08)); | cauth((0x02 << 0x10) | (0x01 << 0x10) | (0x1300 << 0x10) | (0x100 >> 0x08)); | ||
Line 1,796: | Line 1,957: | ||
| 0x00 | | 0x00 | ||
| 0x10 | | 0x10 | ||
| | | Debug key (empty) | ||
|- | |- | ||
| 0x10 | | 0x10 |