Line 1: |
Line 1: |
− | = Secure Monitor calls = | + | = Secure Monitor Calls = |
| 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 37: |
Line 37: |
| | 0xC3000404 || GetResultData | | | 0xC3000404 || GetResultData |
| |- | | |- |
− | | 0xC3000E05 || ExpMod | + | | 0xC3000E05 || ModularExponentiate |
| |- | | |- |
| | 0xC3000006 || [[#GenerateRandomBytes]] (same as in [[#FunctionId1]]) | | | 0xC3000006 || [[#GenerateRandomBytes]] (same as in [[#FunctionId1]]) |
Line 51: |
Line 51: |
| | 0xC300040B || [[#ComputeCmac]] | | | 0xC300040B || [[#ComputeCmac]] |
| |- | | |- |
− | | [1.0.0-4.1.0] 0xC300100C || [[#ImportEsKey]] | + | | [1.0.0-4.1.0] 0xC300100C || [[#DecryptAndImportEsDeviceKey]] |
| |- | | |- |
− | | [5.0.0+] 0xC300D60C || [[#ReEncryptRsaPrivateKey]] | + | | [5.0.0+] 0xC300D60C || [[#ReencryptDeviceUniqueData]] |
| |- | | |- |
− | | [1.0.0-4.1.0] 0xC300100D || [[#DecryptRsaPrivateKey]] | + | | 0xC300100D || [[#DecryptDeviceUniqueData]] |
| |- | | |- |
− | | [5.0.0+] 0xC300100D || [[#DecryptOrImportRsaPrivateKey]] | + | | [1.0.0-4.1.0] 0xC300100E || [[#DecryptAndImportLotusKey]] |
| |- | | |- |
− | | [1.0.0-4.1.0] 0xC300100E || [[#ImportSecureExpModKey]] | + | | 0xC300060F || [[#ModularExponentiateByStorageKey]] |
| |- | | |- |
− | | 0xC300060F || [[#SecureExpMod]] | + | | 0xC3000610 || [[#PrepareEsDeviceUniqueKey]] |
| |- | | |- |
− | | 0xC3000610 || [[#UnwrapTitleKey]] | + | | 0xC3000011 || [[#LoadPreparedAesKey]] |
| |- | | |- |
− | | 0xC3000011 || [[#LoadTitleKey]]
| + | | 0xC3000012 || [2.0.0+] [[#PrepareEsCommonKey]] |
− | |-
| |
− | | 0xC3000012 || [2.0.0+] [[#UnwrapCommonTitleKey]] | |
| |} | | |} |
| | | |
Line 101: |
Line 99: |
| 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 120: |
| [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. | |
| | | |
− | === ImportSecureExpModKey === | + | === 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 129: |
| [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 [[#ImportSecureExpModKey]] 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 155: |
| ! Value || Name | | ! Value || Name |
| |- | | |- |
− | | 0xC4000001 || [[#CpuSuspend]] | + | | 0xC4000001 || [[#SuspendCpu]] |
| |- | | |- |
− | | 0x84000002 || [[#CpuOff]] | + | | 0x84000002 || [[#PowerOffCpu]] |
| |- | | |- |
− | | 0xC4000003 || [[#CpuOn]] | + | | 0xC4000003 || [[#PowerOnCpu]] |
| |- | | |- |
| | 0xC3000004 || [[#GetConfig]] (same as in [[#FunctionId0]]) | | | 0xC3000004 || [[#GetConfig]] (same as in [[#FunctionId0]]) |
Line 172: |
Line 165: |
| | 0xC3000005 || [[#GenerateRandomBytes]] (same as in [[#FunctionId0]]) | | | 0xC3000005 || [[#GenerateRandomBytes]] (same as in [[#FunctionId0]]) |
| |- | | |- |
− | | 0xC3000006 || [[#Panic]] | + | | 0xC3000006 || [[#ShowError]] |
| |- | | |- |
− | | 0xC3000007 || [2.0.0+] [[#ConfigureCarveout]] | + | | 0xC3000007 || [2.0.0+] [[#SetKernelCarveoutRegion]] |
| |- | | |- |
| | 0xC3000008 || [2.0.0+] [[#ReadWriteRegister]] | | | 0xC3000008 || [2.0.0+] [[#ReadWriteRegister]] |
| |} | | |} |
| | | |
− | === CpuSuspend === | + | === SuspendCpu === |
| Takes an u64 '''PowerState''', an u64 '''EntrypointAddress''' and an u64 '''ContextId'''. No output. | | Takes an u64 '''PowerState''', an u64 '''EntrypointAddress''' and an u64 '''ContextId'''. No output. |
| | | |
Line 186: |
Line 179: |
| 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 '''EntrypointAddress''' and an u64 '''ContextId'''. Returns [[#Result]]. | | Takes an u64 '''TargetCpu''', an u64 '''EntrypointAddress''' and an u64 '''ContextId'''. Returns [[#Result]]. |
| | | |
Line 785: |
Line 778: |
| The kernel limits '''Size''' to 0x38 (for fitting in return registers). | | The kernel limits '''Size''' to 0x38 (for fitting in return registers). |
| | | |
− | === Panic === | + | === ShowError === |
| Takes an u32 '''Color''' and issues a system panic. | | Takes an u32 '''Color''' and issues a system panic. |
| | | |
| The kernel always calls this with '''Color''' set to 0xF00. | | The kernel always calls this with '''Color''' set to 0xF00. |
| | | |
− | === ConfigureCarveout === | + | === SetKernelCarveoutRegion === |
| Takes an u64 '''Index''', an u64 '''Address''' and an u64 '''Size'''. Returns [[#Result]]. | | Takes an u64 '''Index''', an u64 '''Address''' and an u64 '''Size'''. Returns [[#Result]]. |
| | | |