Secure Monitor: Difference between revisions

No edit summary
 
(33 intermediate revisions by 4 users not shown)
Line 1: Line 1:
= Secure Monitor calls =
= SMC =
The secure monitor provides two top level handlers of which each provides a range of sub handlers.
The secure monitor provides two top level handlers of which each provides a range of sub handlers.


Secure Monitor calls follow the ARM SMC calling convention up to a small change:
Secure Monitor calls follow the ARM SMC calling convention with a small change:
{| class=wikitable
{| class=wikitable
! Bit number || Bit mask || Description
! Bits || Description
|-
|-
| 31 || 0x80000000 || Set to 0 means Yielding Call; Set to 1 means Fast Call.
| 0-7 || Function Number
|-
|-
| 30 || 0x40000000 || Set to 0 means SMC32 convention; Set to 1 means SMC64.
| 8-15 || Argument Type
|-
|-
| 29-24 || 0x3F000000 || Service Call ranges.
| 16-23 || Reserved
|-
|-
| 23-16 || 0x00FF0000 || Must be zero.
| 24-29 || Call Range
|-
|-
| 15-8 || 0x0000FF00 || Argument type. This is different from the ARM SMC calling convention.
| 30 || Call Convention (0 = SMC32, 1 = SMC64)
|-
|-
| 7-0 || 0x000000FF || Function number within the range call type.
| 31 || Call Type (0 = Yielding Call, 1 = Fast Call)
|}
|}


Line 31: Line 31:
| 0xC3000401 || SetConfig
| 0xC3000401 || SetConfig
|-
|-
| 0xC3000002 || [[#GetConfig]] (same as in [[#FunctionId1]])
| 0xC3000002 || [[#GetConfig|GetConfig]] (same as in [[#FunctionId1]])
|-
|-
| 0xC3000003 || GetResult
| 0xC3000003 || GetResult
Line 37: Line 37:
| 0xC3000404 || GetResultData
| 0xC3000404 || GetResultData
|-
|-
| 0xC3000E05 || ExpMod
| 0xC3000E05 || ModularExponentiate
|-
|-
| 0xC3000006 || [[#GenerateRandomBytes]] (same as in [[#FunctionId1]])
| 0xC3000006 || [[#GenerateRandomBytes|GenerateRandomBytes]] (same as in [[#FunctionId1]])
|-
|-
| 0xC3000007 || [[#GenerateAesKek]]
| 0xC3000007 || [[#GenerateAesKek|GenerateAesKek]]
|-
|-
| 0xC3000008 || [[#LoadAesKey]]
| 0xC3000008 || [[#LoadAesKey|LoadAesKey]]
|-
|-
| 0xC3000009 || [[#ComputeAes]]
| 0xC3000009 || [[#ComputeAes|ComputeAes]]
|-
|-
| 0xC300000A || [[#GenerateSpecificAesKey]]
| 0xC300000A || [[#GenerateSpecificAesKey|GenerateSpecificAesKey]]
|-
|-
| 0xC300040B || [[#ComputeCmac]]
| 0xC300040B || [[#ComputeCmac|ComputeCmac]]
|-
|-
| [1.0.0-4.1.0] 0xC300100C || [[#ImportEsKey]]
| [1.0.0-4.1.0] 0xC300100C || [[#DecryptAndImportEsDeviceKey|DecryptAndImportEsDeviceKey]]
|-
|-
| [5.0.0+] 0xC300D60C || [[#ReEncryptRsaPrivateKey]]
| [5.0.0+] 0xC300D60C || [[#ReencryptDeviceUniqueData|ReencryptDeviceUniqueData]]
|-
|-
| [1.0.0-4.1.0] 0xC300100D || [[#DecryptRsaPrivateKey]]
| 0xC300100D || [[#DecryptDeviceUniqueData|DecryptDeviceUniqueData]]
|-
|-
| [5.0.0+] 0xC300100D || [[#DecryptOrImportRsaPrivateKey]]
| [1.0.0-4.1.0] 0xC300100E || [[#DecryptAndImportLotusKey|DecryptAndImportLotusKey]]
|-
|-
| [1.0.0-4.1.0] 0xC300100E || [[#ImportLotusKey]]
| 0xC300060F || [[#ModularExponentiateByStorageKey|ModularExponentiateByStorageKey]]
|-
|-
| 0xC300060F || [[#StorageExpMod]]
| 0xC3000610 || [[#PrepareEsDeviceUniqueKey|PrepareEsDeviceUniqueKey]]
|-
|-
| 0xC3000610 || [[#UnwrapTitleKey]]
| 0xC3000011 || [[#LoadPreparedAesKey|LoadPreparedAesKey]]
|-
|-
| 0xC3000011 || [[#LoadTitleKey]]
| 0xC3000012 || [2.0.0+] [[#PrepareEsCommonKey|PrepareEsCommonKey]]
|-
| 0xC3000012 || [2.0.0+] [[#UnwrapCommonTitleKey]]
|}
|}


Line 79: Line 77:
** This means: Plaintext kek keys never leave TrustZone.
** This means: Plaintext kek keys never leave TrustZone.
** Further, this means: Actual AES/RSA keys never leave TrustZone.
** Further, this means: Actual AES/RSA keys never leave TrustZone.
=== GenerateRandomBytes ===
Takes an u64 '''Size'''. Returns [[#Result]] and '''RandomBytes'''.
'''Size''' is limited to 0x38 (for fitting in return registers).


=== GenerateAesKek ===
=== GenerateAesKek ===
Line 101: Line 104:
Calculates CMAC over input data.
Calculates CMAC over input data.


=== ImportEsKey ===
=== DecryptAndImportEsDeviceKey ===
Takes a session kek created with [[#GenerateAesKek]], a wrapped AES key, and a wrapped RSA private key.
Takes a session kek created with [[#GenerateAesKek]], a wrapped AES key, and a wrapped RSA private key.


The session kek must have been created with [[#CryptoUsecase|CryptoUsecase TitleKey]].
The session kek must have been created with [[#CryptoUsecase|CryptoUsecase TitleKey]].


[5.0.0] This function was removed and replaced with [[#ReEncryptRsaPrivateKey]].
[5.0.0] This function was removed and replaced with [[#ReencryptDeviceUniqueData]].


=== ReEncryptRsaPrivateKey ===
=== ReencryptDeviceUniqueData ===
Takes in two session keks created with [[#GenerateAesKek]], two wrapped AES keys, an enum member, and a wrapped RSA private key.
Takes in two session keks created with [[#GenerateAesKek]], two wrapped AES keys, an enum member, and a wrapped RSA private key.


Decrypts and validates the wrapped RSA private key with the first kek/wrapped key, and re-encrypts it with the second if valid.
Decrypts and validates the wrapped RSA private key with the first kek/wrapped key, and re-encrypts it with the second if valid.


The re-encrypted key is then passed to the user, for use with [[#DecryptOrImportRsaPrivateKey]].
The re-encrypted key is then passed to the user, for use with [[#DecryptDeviceUniqueData]].


=== DecryptRsaPrivateKey ===
=== DecryptDeviceUniqueData ===
Takes a session kek created with [[#GenerateAesKek]], a wrapped AES key, an enum member, and a wrapped RSA private key.
Takes a session kek created with [[#GenerateAesKek]], a wrapped AES key, an enum member, and a wrapped RSA private key.


Line 122: Line 125:
[4.0.0+] The SMC handler when certain conditions pass and FunctionId0==0xC300100D now returns error 0x6 instead of calling the handler funcptr.
[4.0.0+] The SMC handler when certain conditions pass and FunctionId0==0xC300100D now returns error 0x6 instead of calling the handler funcptr.


[5.0.0+] This function was replaced by [[#DecryptOrImportRsaPrivateKey]].
[5.0.0+] This function now takes an additional input [[#DecryptOrImportMode]]. This extends the original functionality to enable importing private keys into the security engine instead of decrypting them.
 
=== DecryptOrImportRsaPrivateKey ===
This function replaced [[#DecryptRsaPrivateKey]] in [[5.0.0]], adding an additional [[#DecryptOrImportMode]].
 
This SMC extends DecryptRsaPrivateKey's original functionality to enable importing private keys into the security engine instead of decrypting them, when certain enum members are passed.


=== ImportLotusKey ===
=== DecryptAndImportLotusKey ===
Takes a session kek created with [[#GenerateAesKek]], and a wrapped RSA key.
Takes a session kek created with [[#GenerateAesKek]], and a wrapped RSA key.


Line 136: Line 134:
[5.0.0] This function was removed.
[5.0.0] This function was removed.


=== SecureExpMod ===
=== ModularExponentiateByStorageKey ===
Performs an ExpMod operation using an exponent previously loaded with the [[#ImportLotusKey]] command.
Performs an ExpMod operation using an exponent previously loaded with the [[#DecryptAndImportLotusKey]] command.


[5.0.0+] This now uses any exponent previously loaded with [[#DecryptOrImportRsaPrivateKey]] and takes an [[#SecureExpModMode]].
[5.0.0+] This now uses any exponent previously loaded with [[#DecryptDeviceUniqueData]] and takes an [[#SecureExpModMode]].


=== UnwrapTitleKey ===
=== PrepareEsDeviceUniqueKey ===
Takes an Rsa-Oaep-wrapped TitleKey, an RSA Public Key, and a label hash.
Takes an Rsa-Oaep-wrapped TitleKey, an RSA Public Key, and a label hash.


Performs an ExpMod operation using an exponent previously loaded with the [[#ImportEsKey]] command, and then validates/extracts a Titlekey from the resulting message.
Performs an ExpMod operation using an exponent previously loaded with the [[#DecryptAndImportEsDeviceKey]] command, and then validates/extracts a Titlekey from the resulting message.


Returns a session-unique AES key especially for use in [[#LoadTitleKey]].
Returns a session-unique AES key especially for use in [[#LoadTitleKey]].


[5.0.0+] This now uses any exponent previously loaded with [[#DecryptOrImportRsaPrivateKey]].
[5.0.0+] This now uses any exponent previously loaded with [[#DecryptDeviceUniqueData]].


=== LoadTitleKey ===
=== LoadPreparedAesKey ===
Takes a session-unique AES key from [[#UnwrapCommonTitleKey]] or [[#UnwrapTitleKey]].
Takes a session-unique AES key from [[#PrepareEsCommonKey]] or [[#PrepareEsDeviceUniqueKey]].


=== UnwrapCommonTitleKey ===
=== PrepareEsCommonKey ===
Takes an AES-wrapped TitleKey and returns a sealed AES key.
Takes an AES-wrapped common TitleKey and returns a sealed AES key.


== FunctionId1 ==
== FunctionId1 ==
Line 162: Line 160:
! Value || Name
! Value || Name
|-
|-
| 0xC4000001 || [[#CpuSuspend]]
| 0xC4000001 || [[#SuspendCpu|SuspendCpu]]
|-
|-
| 0x84000002 || [[#CpuOff]]
| 0x84000002 || [[#PowerOffCpu|PowerOffCpu]]
|-
|-
| 0xC4000003 || [[#CpuOn]]
| 0xC4000003 || [[#PowerOnCpu|PowerOnCpu]]
|-
|-
| 0xC3000004 || [[#GetConfig]] (same as in [[#FunctionId0]])
| 0xC3000004 || [[#GetConfig|GetConfig]] (same as in [[#FunctionId0]])
|-
|-
| 0xC3000005 || [[#GenerateRandomBytes]] (same as in [[#FunctionId0]])
| 0xC3000005 || [[#GenerateRandomBytes|GenerateRandomBytesNonBlocking]]
|-
|-
| 0xC3000006 || [[#Panic]]
| 0xC3000006 || [[#ShowError|ShowError]]
|-
|-
| 0xC3000007 || [2.0.0+] [[#ConfigureCarveout]]
| 0xC3000007 || [2.0.0+] [[#SetKernelCarveoutRegion|SetKernelCarveoutRegion]]
|-
|-
| 0xC3000008 || [2.0.0+] [[#ReadWriteRegister]]
| 0xC3000008 || [2.0.0+] [[#ReadWriteRegister|ReadWriteRegister]]
|}
|}


=== CpuSuspend ===
=== SuspendCpu ===
Takes an u64 '''PowerState''', an u64 '''EntrypointAddr''' and an u64 '''ContextId'''. No output.
Takes an u64 '''PowerState''', an u64 '''EntrypointAddress''' and an u64 '''ContextId'''. No output.


Suspends the CPU (CPU0).
Suspends the CPU (CPU0).
Line 186: Line 184:
The kernel calls this SMC on shutdown with '''PowerState''' set to 0x0201001B (power level: 0x02==system; power type: 0x01==powerdown; ID: 0x1B).
The kernel calls this SMC on shutdown with '''PowerState''' set to 0x0201001B (power level: 0x02==system; power type: 0x01==powerdown; ID: 0x1B).


=== CpuOff ===
=== PowerOffCpu ===
No input/output.
No input/output.


Turns off the CPU (CPU1, CPU2 or CPU3).
Turns off the CPU (CPU1, CPU2 or CPU3).


=== CpuOn ===
=== PowerOnCpu ===
Takes an u64 '''TargetCpu''', an u64 '''EntrypointAddr''' and an u64 '''ContextId'''. Returns [[#Result]].
Takes an u64 '''TargetCpu''', an u64 '''EntrypointAddress''' and an u64 '''ContextId'''. Returns [[#Result]].


Turns on the CPU (CPU1, CPU2 or CPU3).
Turns on the CPU (CPU1, CPU2 or CPU3).


=== GetConfig ===
=== GetConfig ===
Takes a [[#ConfigItem]]. Returns [[#Result]] and a '''ConfigVal'''.
Takes a [[#ConfigItem]]. Returns [[#Result]] and a '''ConfigValue'''.


==== ConfigItem ====
==== ConfigItem ====
Line 206: Line 204:
| 1 || [[#DisableProgramVerification]]
| 1 || [[#DisableProgramVerification]]
|-
|-
| 2 || [[#DramId]]
| 2 || [S1] [[#DramId]]
|-
|-
| 3 || [[#SecurityEngineInterruptNumber]]
| 3 || [[#SecurityEngineInterruptNumber]]
|-
|-
| 4 || [[#FuseVersion]]
| 4 || [S1] [[#FuseVersion]]
|-
|-
| 5 || [[#HardwareType]]
| 5 || [[#HardwareType]]
|-
|-
| 6 || [[#IsRetail]]
| 6 || [[#HardwareState]]
|-
|-
| 7 || [[#IsRecoveryBoot]]
| 7 || [S1] [[#IsRecoveryBoot]]
|-
|-
| 8 || [[#DeviceId]]
| 8 || [[#DeviceId]]
Line 224: Line 222:
| 10 || [[#MemoryMode]]
| 10 || [[#MemoryMode]]
|-
|-
| 11 || [[#IsDebugMode]]
| 11 || [[#IsDevelopmentFunctionEnabled]]
|-
|-
| 12 || [[#KernelConfiguration]]
| 12 || [[#KernelConfiguration]]
|-
|-
| 13 || [[#IsChargerHiZModeEnabled]]
| 13 || [S1] [[#IsChargerHiZModeEnabled]]
|-
|-
| 14 || [4.0.0+] [[#IsQuest]]
| 14 || [4.0.0+] [[#RetailInteractiveDisplayState]]
|-
|-
| 15 || [5.0.0+] [[#RegulatorType]]
| 15 || [S1] [5.0.0+] [[#RegulatorType]]
|-
|-
| 16 || [5.0.0+] [[#DeviceUniqueKeyGeneration]]
| 16 || [5.0.0+] [[#DeviceUniqueKeyGeneration]]
|-
|-
| 17 || [5.0.0+] [[#Package2Hash]]
| 17 || [5.0.0+] [[#Package2Hash]]
|-
| 18 || [S2]
|-
| 19 || [S2]
|-
| 256-280 || [S2] [[#Bcc]]
|}
|}


Line 258: Line 262:
|-
|-
| 3
| 3
| Reserved
| [11.0.0+] MarikoIowaHynix1y4gb ([1.0.0-10.2.0] EristaCopperSamsung4gb)
|-
|-
| 4
| 4
Line 264: Line 268:
|-
|-
| 5
| 5
| [4.0.0+] Reserved
| [12.0.0+] MarikoHoagHynix1y4gb ([4.0.0-11.0.1] EristaCopperHynix4gb)
|-
|-
| 6
| 6
| [4.0.0+] Reserved
| [13.0.0+] MarikoAulaHynix1y4gb ([4.0.0-12.1.0] EristaCopperMicron4gb)
|-
|-
| 7
| 7
| [5.0.0+] MarikoIowax1x2Samsung4gb ([4.0.0-4.1.0] Reserved)
| [15.0.0+] Reserved ([5.0.0-14.1.2] MarikoIowax1x2Samsung4gb, [4.0.0-4.1.0] Reserved)
|-
|-
| 8
| 8
Line 297: Line 301:
|-
|-
| 16
| 16
| [8.0.0+] MarikoIowaSamsung4gbY
| [15.0.0+] Reserved ([8.0.0-14.1.2] MarikoIowaSamsung4gbY)
|-
|-
| 17
| 17
Line 309: Line 313:
|-
|-
| 20
| 20
| [9.0.0+] MarikoIowaSamsung1y4gbY
| [14.0.0+] MarikoIowaSamsung1z4gb ([9.0.0-13.2.1] MarikoIowaSamsung1y4gbY)
|-
|-
| 21
| 21
| [9.0.0+] MarikoIowaSamsung1y8gbY
| [14.0.0+] MarikoHoagSamsung1z4gb ([9.0.0-13.2.1] MarikoIowaSamsung1y8gbY)
|-
|-
| 22
| 22
| [9.0.0+] MarikoIowaSamsung1y4gbA
| [14.0.0+] MarikoAulaSamsung1z4gb ([13.0.0-13.2.1] Reserved, [9.0.0-12.1.0] MarikoAulaSamsung1y4gb)
|-
|-
| 23
| 23
| [10.0.0+] MarikoUnkSamsung1y8gbX
| [10.0.0+] MarikoHoagSamsung1y8gbX
|-
|-
| 24
| 24
| [10.0.0+] MarikoUnkSamsung1y4gbX
| [10.0.0+] MarikoAulaSamsung1y4gbX
|-
| 25
| [11.0.0+] MarikoIowaMicron1y4gb
|-
| 26
| [11.0.0+] MarikoHoagMicron1y4gb
|-
| 27
| [11.0.0+] MarikoAulaMicron1y4gb
|-
| 28
| [11.0.0+] MarikoAulaSamsung1y8gbX
|-
| 29
| [16.0.0+] MarikoIowaHynix1a4gb ([15.0.0-15.0.1] MarikoIowax1x2Samsung4gb)
|-
| 30
| [16.0.0+] MarikoHoagHynix1a4gb ([15.0.0-15.0.1] MarikoHoagx1x2Samsung4gb)
|-
| 31
| [16.0.0+] MarikoAulaHynix1a4gb ([15.0.0-15.0.1] MarikoAulax1x2Samsung4gb)
|-
| 32
| [16.0.0+] MarikoIowaMicron1a4gb ([15.0.0-15.0.1] MarikoIowaSamsung4gbY)
|-
| 33
| [16.0.0+] MarikoHoagMicron1a4gb ([15.0.0-15.0.1] MarikoHoagSamsung4gbY)
|-
| 34
| [16.0.0+] MarikoAulaMicron1a4gb ([15.0.0-15.0.1] MarikoAulaSamsung4gbY)
|}
|}


Line 329: Line 363:
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! SoC
! SocType
! Platform
! Platform
! DramId
! DramId
! Revision
! Revision
! DVFS version
! DVFS
|-
|-
| T210
| Erista
| jetson-tx1
| jetson-tx1
| N/A
| N/A
Line 351: Line 385:
  11_1600000_02_V9.8.3_V1.6
  11_1600000_02_V9.8.3_V1.6
|-
|-
| T210
| Erista
| nx-abcb
| nx-abcb
| EristaIcosaSamsung4gb
| EristaIcosaSamsung4gb
Line 367: Line 401:
  10_1600000_NoCfgVersion_V9.8.7_V1.6
  10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
|-
| T210
| Erista
| nx-abcb
| nx-abcb
| EristaIcosaMicron4gb
| EristaIcosaMicron4gb
Line 383: Line 417:
  10_1600000_NoCfgVersion_V9.8.4_V1.6
  10_1600000_NoCfgVersion_V9.8.4_V1.6
|-
|-
| T210
| Erista
| nx-abcb
| nx-abcb
| EristaIcosaHynix4gb
| EristaIcosaHynix4gb
Line 399: Line 433:
  10_1600000_NoCfgVersion_V9.8.4_V1.6
  10_1600000_NoCfgVersion_V9.8.4_V1.6
|-
|-
| T210
| Erista
| nx-abca2
| nx-abca2
| EristaIcosaSamsung4gb, EristaIcosaMicron4gb
| EristaIcosaSamsung4gb, EristaIcosaMicron4gb
Line 415: Line 449:
  10_1600000_NoCfgVersion_V9.8.7_V1.6
  10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
|-
| T210
| Erista
| nx-abca2
| nx-abca2
| EristaIcosaHynix4gb
| EristaIcosaHynix4gb
Line 431: Line 465:
  10_1600000_NoCfgVersion_V9.8.7_V1.6
  10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
|-
| T210
| Erista
| nx-abca2
| nx-abca2
| EristaIcosaSamsung6gb
| EristaIcosaSamsung6gb
Line 447: Line 481:
  10_1600000_NoCfgVersion_V9.8.7_V1.6
  10_1600000_NoCfgVersion_V9.8.7_V1.6
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowax1x2Samsung4gb
| MarikoIowax1x2Samsung4gb
Line 456: Line 490:
  01_1600000_NoCfgVersion_V0.3.1_V2.0
  01_1600000_NoCfgVersion_V0.3.1_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung4gb, MarikoHoagSamsung4gb
| MarikoIowaSamsung4gb, MarikoHoagSamsung4gb
Line 465: Line 499:
  01_1600000_NoCfgVersion_V0.3.1_V2.0
  01_1600000_NoCfgVersion_V0.3.1_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung8gb, MarikoHoagSamsung8gb
| MarikoIowaSamsung8gb, MarikoHoagSamsung8gb
Line 474: Line 508:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaHynix4gb, MarikoHoagHynix4gb
| MarikoIowaHynix4gb, MarikoHoagHynix4gb
Line 483: Line 517:
  01_1600000_NoCfgVersion_V0.3.1_V2.0
  01_1600000_NoCfgVersion_V0.3.1_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaMicron4gb, MarikoHoagMicron4gb
| MarikoIowaMicron4gb, MarikoHoagMicron4gb
Line 492: Line 526:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung4gbY
| MarikoIowaSamsung4gbY
Line 501: Line 535:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y4gbX
| MarikoIowaSamsung1y4gbX
Line 510: Line 544:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y8gbX
| MarikoIowaSamsung1y8gbX
Line 519: Line 553:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoHoagSamsung1y4gbX
| MarikoHoagSamsung1y4gbX
Line 528: Line 562:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y4gbY
| MarikoIowaSamsung1y4gbY
Line 537: Line 571:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y8gbY
| MarikoIowaSamsung1y8gbY
Line 546: Line 580:
  01_1600000_NoCfgVersion_V0.4.2_V2.0
  01_1600000_NoCfgVersion_V0.4.2_V2.0
|-
|-
| T214
| Mariko
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| nx-abca2, nx-abcb, nx-abcc, nx-abcd
| MarikoIowaSamsung1y4gbA
| MarikoIowaSamsung1y4gbA
Line 558: Line 592:
'''nx-abca2''' ('''Icosa''' in '''Erista''', '''Iowa''' in '''Mariko''') hardware types are variations of the retail, EDEV and SDEV form factors.
'''nx-abca2''' ('''Icosa''' in '''Erista''', '''Iowa''' in '''Mariko''') hardware types are variations of the retail, EDEV and SDEV form factors.


'''nx-abcb''' ('''Copper''' in '''Erista''', '''Calcio''' in '''Mariko''') is a prototype unit. Among other differences, this has extra hardware to support HDMI output.
'''nx-abcb''' ('''Copper''' in '''Erista''', '''Calcio''' in '''Mariko''') is unreleased. Among other differences, this has extra hardware to support HDMI output.


[8.0.0+] '''nx-abcc''' ('''Hoag''') was added for the Lite retail and HDEV form factors.
[8.0.0+] '''nx-abcc''' ('''Hoag''') was added for the Lite retail and HDEV form factors.


[10.0.0+] '''nx-abcd''' was added.
[10.0.0+] '''nx-abcd''' ('''Aula''') was added for the OLED Model retail and ADEV form factors.


'''Erista''' memory is LPDDR4, while '''Mariko''' memory is LPDDR4X.
'''Erista''' memory is LPDDR4, while '''Mariko''' memory is LPDDR4X.
Line 570: Line 604:


===== FuseVersion =====
===== FuseVersion =====
The current [[Package2#Versions|Package1 Maxver Constant]] - 1.
The current [[Package2#Versions|bootloader maximum version]] - 1.


===== HardwareType =====
===== HardwareType =====
[1.0.0+] This item is obtained by checking bits 8 and 2 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]. It can be:
{| class=wikitable
* 0 ('''Icosa'''; Erista retail, EDEV and SDEV), if development flag (bit 8) is '''Retail''' and production flag (bit 2) is '''Production'''.
! Value || Description
* 1 ('''Copper'''; Erista prototype), if development flag (bit 8) is '''Development''' and production flag (bit 2) is '''Prototype'''.
|-
* 3 (Invalid).
| 0 || Icosa
|-
| 1 || Copper
|-
| 2 || [8.0.0+] Hoag ([1.0.0-7.0.1] Invalid)
|-
| 3 || [4.0.0+] Iowa
|-
| 4 || [8.0.0+] Calcio
|-
| 5 || [10.0.0+] Aula
|-
| 15 || Invalid
|}


Value 2 is reserved and considered invalid.
[1.0.0+] This item is obtained by checking bits 8 and 2 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].


[4.0.0+] This item is obtained by checking bits 8, 2 and 16-19 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]. It can be:
[4.0.0+] This item is obtained by checking bits 8, 2 and 16-19 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
* 0 ('''Icosa'''; Erista retail, EDEV and SDEV), if development flag (bit 8) is '''Retail''' and production flag (bit 2) is '''Production'''.
* 1 ('''Copper'''; Erista prototype), if development flag (bit 8) is '''Development''' and production flag (bit 2) is '''Prototype'''.
* 3 ('''Iowa'''; Mariko retail, EDEV and SDEV), if new hardware type (bits 16-19) is '''Iowa'''.
* 4 (Invalid).


Value 2 is reserved and considered invalid.
[7.0.0+] This item can now only be 0 (Icosa) or 15 (Invalid) in Erista units.


[7.0.0+] This item can be obtained by checking bits 8, 2 and 16-19 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]], but is now only 0 (Icosa) or 0xF (Invalid) in retail units.
Hardware is '''Icosa''' (Erista retail, EDEV and SDEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType1]] (bit 2) is 1 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType2]] (bit 8) is 0.


[8.0.0+] This item can be obtained by checking bits 8, 2 and 16-19 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]. It can be:
Hardware is '''Copper''' (unreleased Erista model) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType1]] (bit 2) is 0 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType2]] (bit 8) is 1.
* 0 ('''Icosa'''; Erista retail, EDEV and SDEV), if development flag (bit 8) is '''Retail''' and production flag (bit 2) is '''Production'''.
* 1 ('''Copper'''; Erista prototype), if development flag (bit 8) is '''Development''' and production flag (bit 2) is '''Prototype'''.
* 2 ('''Hoag'''; Mariko Lite retail and HDEV), if new hardware type (bits 16-19) is '''Hoag'''.
* 3 ('''Iowa'''; Mariko retail, EDEV and SDEV), if new hardware type (bits 16-19) is '''Iowa'''.
* 4 ('''Calcio'''; Mariko prototype), if development flag (bit 8) is '''Development''' and production flag (bit 2) is '''Prototype'''.
* 5 (Invalid).


It is still only 0 (Icosa) or 0xF (Invalid) in retail units.
[4.0.0+] Hardware is '''Iowa''' (Mariko retail, EDEV and SDEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType3]] (bits 16-19) is 1.


[10.0.0+] This item can be obtained by checking bits 8, 2 and 16-19 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]. It can be:
[8.0.0+] Hardware is '''Hoag''' (Mariko Lite retail and HDEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType3]] (bits 16-19) is 2.
* 0 ('''Icosa'''; Erista retail, EDEV and SDEV), if development flag (bit 8) is '''Retail''' and production flag (bit 2) is '''Production'''.
* 1 ('''Copper'''; Erista prototype), if development flag (bit 8) is '''Development''' and production flag (bit 2) is '''Prototype'''.
* 2 ('''Hoag'''; Mariko Lite retail and HDEV), if new hardware type (bits 16-19) is '''Hoag'''.
* 3 ('''Iowa'''; Mariko retail, EDEV and SDEV), if new hardware type (bits 16-19) is '''Iowa'''.
* 4 ('''Calcio'''; Mariko prototype), if development flag (bit 8) is '''Development''' and production flag (bit 2) is '''Prototype'''.
* 5 ('''Unknown'''), if new hardware type (bits 16-19) is 0x4.
* 6 (Invalid).


It is still only 0 (Icosa) or 0xF (Invalid) in retail units.
[8.0.0+] Hardware is '''Calcio''' (unreleased Mariko model) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType1]] (bit 2) is 0 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType2]] (bit 8) is 1.


===== IsRetail =====
[10.0.0+] Hardware is '''Aula''' (Mariko OLED Model retail and ADEV) if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareType3]] (bits 16-19) is 4.
This item is obtained by checking bits 9 and 0-1 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]]. It can be 0 (Debug), 1 (Retail) or 2 (Invalid).
 
===== HardwareState =====
{| class=wikitable
! Value || Description
|-
| 0 || Development
|-
| 1 || Production
|-
| 2 || Invalid
|}
 
This item is obtained by checking bits 9 and 0-1 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
 
Hardware is '''Development''' if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState1]] (bits 0-1) is 3 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState2]] (bit 9) is 0.
 
Hardware is '''Production''' if [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState1]] (bits 0-1) is 0 and [[Fuse_registers#FUSE_RESERVED_ODM4|HardwareState2]] (bit 9) is 1.


===== IsRecoveryBoot =====
===== IsRecoveryBoot =====
Line 684: Line 730:
|}
|}


===== IsDebugMode =====
===== IsDevelopmentFunctionEnabled =====
Kernel uses this to determine behavior of svcBreak positive arguments. It will break instead of just force-exiting the process which is what happens on retail.
Kernel uses this to determine behavior of [[SVC#svcBreak|svcBreak]] positive arguments. It will break instead of just force-exiting the process which is what happens on retail.


[2.0.0+] This is also used with certain debug [[SVC|SVCs]].
[2.0.0+] This is also used with certain debug [[SVC|SVCs]].
Line 704: Line 750:
|-
|-
| 2
| 2
| PerformanceMonitoringUnit
| EnablePmuAccess
|-
|-
| 3
| 3
| [8.0.0+] EnableApplicationExtraThread
| [8.0.0+] EnableExtraThreadResourceAllocation
|-
| 4
| [13.0.0+] DisableDynamicSystemResourceAllocation
|-
|-
| 8
| 8
Line 718: Line 767:
Kernel reads this when setting up memory-related code.
Kernel reads this when setting up memory-related code.


EnableNonZeroFillMemory is a boolean determining whether kernel should it will memset various allocated memory-regions with 0x58, 0x59, 0x5A ('X', 'Y', 'Z') instead of zero. This allows Nintendo devs to find uninitialized memory bugs.
'''EnableNonZeroFillMemory''' is a boolean determining whether kernel should it will memset various allocated memory-regions with 0x58, 0x59, 0x5A ('X', 'Y', 'Z') instead of zero. This allows Nintendo devs to find uninitialized memory bugs.


EnableUserExceptionHandler is a boolean determining whether kernel should forcefully enable usermode exception handlers (when false, only certain aborts (((1LL << (esr >> 26)) & 0x1115804400224001) == 0, typically data/prefetch aborts) that occur when the faulting address is in a readable region with MemoryType_CodeStatic will trigger usermode exception handlers).
'''EnableUserExceptionHandler''' is a boolean determining whether kernel should forcefully enable usermode exception handlers (when false, only certain aborts (((1LL << (esr >> 26)) & 0x1115804400224001) == 0, typically data/prefetch aborts) that occur when the faulting address is in a readable region with MemoryType_CodeStatic will trigger usermode exception handlers).


PerformanceMonitoringUnit is a boolean determining whether kernel should enable usermode access to the Performance Monitors (whether PMUSERENR_EL0 should be 1 or 0).
'''EnablePmuAccess''' is a boolean determining whether kernel should enable usermode access to the Performance Monitors (whether PMUSERENR_EL0 should be 1 or 0).


EnableApplicationExtraThread is a boolean determining whether the kernel should increase the KThread slabheap capacity by 160. This also increases object capacities that are calculated based on number of threads.
'''EnableExtraThreadResourceAllocation''' is a boolean determining whether the kernel should increase the KThread slabheap capacity by 160. This also increases object capacities that are calculated based on number of threads.


CallShowErrorOnPanic is a boolean determining whether kernel should call smcPanic on error instead of infinite-looping.
'''CallShowErrorOnPanic''' is a boolean determining whether kernel should call smcPanic on error instead of infinite-looping.


MemorySize determines how much memory is available. 00/03 = 4 GB, 01 = 6 GB, 02 = 8 GB.
'''MemorySize''' determines how much memory is available. 00/03 = 4 GB, 01 = 6 GB, 02 = 8 GB.


===== IsChargerHiZModeEnabled =====
===== IsChargerHiZModeEnabled =====
This tells if the TI Charger (bq24192) is active.
This tells if the TI Charger (bq24192) is active.


===== IsQuest =====
===== RetailInteractiveDisplayState =====
{| class=wikitable
! Value || Description
|-
| 0 || Disabled
|-
| 1 || Enabled
|}
 
This item is bit 10 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].
This item is bit 10 from [[Fuse_registers#FUSE_RESERVED_ODM4|FUSE_RESERVED_ODM4]].


Line 742: Line 799:
|-
|-
! Value
! Value
! SoC
! SocType
! GPU
! GPU
! Power Blocks
! Power Blocks
|-
|-
| 0
| 0
| T210
| Erista
| GM20B (0x12B)
| GM20B (0x12B)
| max77620_sd0, max77621_cpu and max77621_gpu
| max77620_sd0, max77621_cpu and max77621_gpu
|-
|-
| 1
| 1
| T214
| Mariko
| GM20B_B (0x12E)
| GM20B_B (0x12E)
| max77620_sd0, max77812_cpu and max77812_gpu
| max77620_sd0, max77812_cpu and max77812_gpu
|-
|-
| 2
| 2
| T214
| Mariko
| GM20B_B (0x12E)
| GM20B_B (0x12E)
| max77620_sd0, max77812_cpu and max77812_gpu
| max77620_sd0, max77812_cpu and max77812_gpu
|}
|}
This item is currently hardcoded to 0.


[5.0.0+] [[PCV_services|PCV]] uses this value in combination with [[#HardwareType|HardwareType]] to configure power blocks and memory tables for different hardware.
[5.0.0+] [[PCV_services|PCV]] uses this value in combination with [[#HardwareType|HardwareType]] to configure power blocks and memory tables for different hardware.
Line 774: Line 829:
This is a SHA-256 hash calculated over the [[Package2|package2]] image. Since the hash calculation is an optional step in pkg2ldr, this item is only valid in recovery mode. Otherwise, an error is returned instead.
This is a SHA-256 hash calculated over the [[Package2|package2]] image. Since the hash calculation is an optional step in pkg2ldr, this item is only valid in recovery mode. Otherwise, an error is returned instead.


=== GenerateRandomBytes ===
===== Bcc =====
Takes an u64 '''RndSize'''. Returns [[#Result]] and '''RndData'''.
This is a 0x320 bytes buffer split across 25 items of 0x20 bytes each. When put together, these form a Boot Certificate Chain (BCC) for Switch 2 remote device attestation.


The kernel limits '''RndSize''' to 0x38 (for fitting in return registers).
The format follows the [https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md Open Profile for DICE] from Google and includes the main DK_pub and the following entries (twice, likely for phases 2 and 3):
* codeHash (empty)
* configurationDescriptor ("Security version" set to 0)
* authorityHash (empty)
* mode ("Normal")
* keyUsage ("keyCertSign")
* subjectPublicKey (changes on reboot)


=== Panic ===
=== ShowError ===
Takes an u32 '''PanicColor''' and issues a system panic.
Takes an u32 '''Color''' and issues a system panic.


The kernel always calls this with '''PanicColor''' set to 0xF00.
The kernel always calls this with '''Color''' set to 0xF00.


=== ConfigureCarveout ===
=== SetKernelCarveoutRegion ===
Takes an u64 '''CarveoutIdx''', an u64 '''CarveoutAddr''' and an u64 '''CarveoutSize'''. Returns [[#Result]].
Takes an u64 '''Index''', an u64 '''Address''' and an u64 '''Size'''. Returns [[#Result]].


If '''CarveoutIdx''' is 0, '''CarveoutAddr''' and '''CarveoutSize''' are used to configure '''MC_SECURITY_CARVEOUT4'''.
If '''Index''' is 0, '''Address''' and '''Size''' are used to configure '''MC_SECURITY_CARVEOUT4'''.
If '''CarveoutIdx''' is 1, '''CarveoutAddr''' and '''CarveoutSize''' are used to configure '''MC_SECURITY_CARVEOUT5'''.
If '''Index''' is 1, '''Address''' and '''Size''' are used to configure '''MC_SECURITY_CARVEOUT5'''.
Any other '''CarveoutIdx''' values are invalid.
Any other '''Index''' values are invalid.


The kernel calls this with '''CarveoutIdx''' set to 0, '''CarveoutAddr''' set to 0x80060000 and '''CarveoutSize''' set to a dynamically calculated size which covers all the kernel and built-in sysmodules' DRAM regions.
The kernel calls this with '''Index''' set to 0, '''Address''' set to 0x80060000 and '''Size''' set to a dynamically calculated size which covers all the kernel and built-in sysmodules' DRAM regions.


=== ReadWriteRegister ===
=== ReadWriteRegister ===
Takes an u64 '''RegAddr''', an u32 '''RwMask''' and an u32 '''InValue'''. Returns [[#Result]] and an u32 '''OutValue'''.
Takes an u64 '''Register''', an u32 '''Mask''' and an u32 '''InValue'''. Returns [[#Result]] and an u32 '''OutValue'''.


Relays [[SVC#svcReadWriteRegister|svcReadWriteRegister]] to the Secure Monitor.
Relays [[SVC#svcReadWriteRegister|svcReadWriteRegister]] to the Secure Monitor.
Line 806: Line 867:
| 1 || RsaPrivate
| 1 || RsaPrivate
|-
|-
| 2 || RsaSecureExpMod
| 2 || SecureExpMod
|-
| 3 || RsaOaep
|-
| 4 || [5.0.0+] RsaImport
|-
| 5 || [5.0.0+]
|-
|-
| 3 || TitleKey
| 6 || [5.0.0+]
|}
|}
TitleKey represents a RSA wrapped AES key.


= CipherMode =
= CipherMode =
Line 848: Line 913:
|-
|-
| 2 || Drm
| 2 || Drm
|}
= EsKeyType =
{| class=wikitable
! Value || Name
|-
| 0 || TitleKey
|-
| 1 || ElicenseKey
|}
|}


Line 866: Line 940:
| 5 || Invalid async operation
| 5 || Invalid async operation
|-
|-
| [8.0.0+] 6 || Not permitted
| 6 || [8.0.0+] Not permitted
|}
|}