Difference between revisions of "F00D Commands"

From Vita Development Wiki
Jump to navigation Jump to search
 
(59 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Depending on the F00D SELF that is currently loaded, different commands are handled.
+
Depending on the [[SM]] that is currently loaded, different commands are handled.
  
 
== Request Buffer ==
 
== Request Buffer ==
  
Each request that is made sends a page aligned buffer that has a max size of a page. After as 64 byte header common to all commands, the data afterwards is specific to each command. The documentation for each command below specifies the data that goes after the header. The special command id of -1 (<code>0xFFFFFFFF</code>) is used to shut down the currently loaded F00D SELF.
+
Each request that is made sends a page aligned buffer that has a max size of a page. After as 64 byte header common to all commands, the data afterwards is specific to each command. The documentation for each command below specifies the data that goes after the header. The special command id of -1 (<code>0xFFFFFFFF</code>) is used to stop the current loaded [[SM]].
  
{| class="wikitable"
+
Command buffer structure (as seen on FWs 3.60-3.73):
 +
 
 +
{| class='wikitable'
 
|-
 
|-
! Offset !! Size !! Description
+
! Offset
 +
! Size
 +
! Description
 
|-
 
|-
| 0x0 || 0x4 || Size of buffer
+
| 0x0
 +
| 0x4
 +
| Size of the structure (header + data)
 
|-
 
|-
| 0x4 || 0x4 || Command ID
+
| 0x4
 +
| 0x4
 +
| Command ID
 
|-
 
|-
| 0x8 || 0x4 || Return value (output)
+
| 0x8
 +
| 0x4
 +
| Command return value is written here by the SM
 
|-
 
|-
| 0xC || 0x34 || Unknown/Unused
+
| 0xC
 +
| 0x4
 +
| unk2
 
|-
 
|-
| 0x40 || Variable (max 0xFC0) || Command specific buffer
+
| 0x10
 +
| 0x30
 +
| padding
 
|-
 
|-
 +
| 0x40
 +
| variable, chosen by NS Kernel, max=0x1000-0x40
 +
| data buffer
 
|}
 
|}
  
=== Physical Address List ===
+
On FW 0.931, and maybe in later prototype FWs, the data buffer is located at offset 0x10 instead of 0x40. Thus we can ask why they added the 0x30 bytes padding.
 +
 
 +
=== Physical Address Range ===
  
 
A common format used in these requests is a list of physical address and size. This simple structure is defined below. See [[SceSysmem#sceKernelVARangeToPARangeForDriver|sceKernelVARangeToPARangeForDriver]] for information on creating this list.
 
A common format used in these requests is a list of physical address and size. This simple structure is defined below. See [[SceSysmem#sceKernelVARangeToPARangeForDriver|sceKernelVARangeToPARangeForDriver]] for information on creating this list.
Line 32: Line 51:
 
|-
 
|-
 
| 0x4 || 0x4 || Size
 
| 0x4 || 0x4 || Size
|-
 
 
|}
 
|}
  
This data format is used when passing large buffers of data to F00D. This is because the memory manager in kernel could allocate contiguous virtual addresses that corresponds to varying physical addresses.
+
This data format is used when passing large buffers of data to [[F00D]]. This is because the memory manager in kernel could allocate contiguous virtual addresses that corresponds to varying physical addresses.
  
 
== kprx_auth_sm.self ==
 
== kprx_auth_sm.self ==
  
This is a special SELF that is found in the boot [[SLB2]] partition. The raw (encrypted) SELF is found in secure world memory (placed there by an early bootloader). It is used to decrypt SELFs for ARM. The SELF header is passed into a page aligned buffer and a [[F00D Commands#Physical Address List|paddr list]] is generated from it.
+
This is a special SM found in the [[SLB2]] partition. The raw (encrypted) SELF is stored in [[Secure World]] memory. It is placed there by an early bootloader.
  
=== 0x10001 sceSblAuthMgrAuthHeaderForKernel ===
+
kprx_auth_sm is used to decrypt SELF and SPSFO files for ARM. The CF header is passed into a page aligned buffer and a [[F00D Commands#Physical Address Range|PA range]] is generated from it.
 +
 
 +
=== 0x10001 - sceSblAuthMgrAuthHeader ===
  
 
Used by [[SceSblAuthMgr#sceSblAuthMgrAuthHeaderForKernel|sceSblAuthMgrAuthHeaderForKernel]].
 
Used by [[SceSblAuthMgr#sceSblAuthMgrAuthHeaderForKernel|sceSblAuthMgrAuthHeaderForKernel]].
Line 57: Line 77:
 
|}
 
|}
  
=== 0x20001 sceSblAuthMgrLoadSegmentForKernel ===
+
=== 0x20001 - sceSblAuthMgrSetupAuthSegment ===
  
Used by [[SceSblAuthMgr#sceSblAuthMgrLoadSegmentForKernel|sceSblAuthMgrLoadSegmentForKernel]].
+
Used by [[SceSblAuthMgr#sceSblAuthMgrSetupAuthSegmentForKernel|sceSblAuthMgrSetupAuthSegmentForKernel]].
  
 
Set the program segment to decrypt. This corresponds to the segment index in the ELF program headers in the SELF header passed in with the command above.
 
Set the program segment to decrypt. This corresponds to the segment index in the ELF program headers in the SELF header passed in with the command above.
Line 75: Line 95:
 
|}
 
|}
  
=== 0x30001 sceSblAuthMgrLoadBlockForKernel ===
+
=== 0x30001 - sceSblAuthMgrLoadBlock ===
  
Used by [[SceSblAuthMgr#sceSblAuthMgrLoadBlockForKernel|sceSblAuthMgrLoadBlockForKernel]].
+
Used by [[SceSblAuthMgr#sceSblAuthMgrAuthSegmentForKernel|sceSblAuthMgrAuthSegmentForKernel]].
  
 
Decrypt a buffer from the SELF corresponding to the program segment number passed in above. The segment is read in <code>0x10000</code> bytes chunks and is decrypted in place (the input buffer will contain the decrypted data). A [[F00D Commands#Physical Address List|paddr list]] is generated from the buffer. The input buffer and output buffer can be the same.
 
Decrypt a buffer from the SELF corresponding to the program segment number passed in above. The segment is read in <code>0x10000</code> bytes chunks and is decrypted in place (the input buffer will contain the decrypted data). A [[F00D Commands#Physical Address List|paddr list]] is generated from the buffer. The input buffer and output buffer can be the same.
Line 94: Line 114:
 
|}
 
|}
  
=== 0x40001 sceSblAuthMgrGetEKcForDriver ===
+
=== 0x40001 - sceSblAuthMgrGetEKc ===
  
 
Decrypts provided buffer in ECB mode using one of three keys (NPDRM keys ?).
 
Decrypts provided buffer in ECB mode using one of three keys (NPDRM keys ?).
  
Used by [[SceSblAuthMgr#sceSblAuthMgrGetEKcForDriver|sceSblAuthMgrGetEKcForDriver]] for getting klicensee?
+
Used by [[SceSblAuthMgr#sceSblAuthMgrGetEKcForDriver|sceSblAuthMgrGetEKcForDriver]] for getting klicensee.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 116: Line 136:
 
|}
 
|}
  
=== 0x50001 sceSblAuthMgrSetDmac5KeyForKernel ===
+
=== 0x50001 - sceSblAuthMgrSetDmac5Key ===
  
 
Used by [[SceSblAuthMgr#sceSblAuthMgrSetDmac5KeyForKernel|sceSblAuthMgrSetDmac5KeyForKernel]] to set key for decryption.
 
Used by [[SceSblAuthMgr#sceSblAuthMgrSetDmac5KeyForKernel|sceSblAuthMgrSetDmac5KeyForKernel]] to set key for decryption.
Line 138: Line 158:
 
|}
 
|}
  
=== 0x60001 sceSblAuthMgrClearDmac5KeyForKernel ===
+
=== 0x60001 - sceSblAuthMgrClearDmac5Key ===
  
 
Used by [[SceSblAuthMgr#sceSblAuthMgrClearDmac5KeyForKernel|sceSblAuthMgrClearDmac5KeyForKernel]] for clearing the Dmac5 Key.
 
Used by [[SceSblAuthMgr#sceSblAuthMgrClearDmac5KeyForKernel|sceSblAuthMgrClearDmac5KeyForKernel]] for clearing the Dmac5 Key.
Line 144: Line 164:
 
This function writes zeroes into dmac5 keyring.
 
This function writes zeroes into dmac5 keyring.
  
=== 0x70001 sceSblAuthMgrDecBindDataForDriver ===
+
=== 0x70001 - sceSblAuthMgrDecBindDataForDriver ===
  
 
Used by [[SceSblAuthMgr#sceSblAuthMgrDecBindDataForDriver|sceSblAuthMgrDecBindDataForDriver]] and [[SceNpDrm]] for gamecard binding data used in conjunction with the RIF license file on the gamecard for deriving the klicensee.
 
Used by [[SceSblAuthMgr#sceSblAuthMgrDecBindDataForDriver|sceSblAuthMgrDecBindDataForDriver]] and [[SceNpDrm]] for gamecard binding data used in conjunction with the RIF license file on the gamecard for deriving the klicensee.
  
=== 0x80001 sceSblAuthMgrVerifySpsfoForDriver ===
+
=== 0x80001 - sceSblAuthMgrVerifySpsfo ===
  
 
Used by [[SceSblAuthMgr#sceSblAuthMgrVerifySpsfoForDriver|sceSblAuthMgrVerifySpsfoForDriver]].
 
Used by [[SceSblAuthMgr#sceSblAuthMgrVerifySpsfoForDriver|sceSblAuthMgrVerifySpsfoForDriver]].
Line 154: Line 174:
 
== act_sm.self ==
 
== act_sm.self ==
  
=== 0x1 check_activation_code_1 ===
+
=== 0x1 - check_activation_code_1 ===
  
Only on pre 2.10.
+
Removed on FW 2.10.
  
Verify SceKitActivationData derived from AFV.
+
Verify SceKitActivationData read from sd0:/act.dat.
  
Use "internal" keys (?internal kits maybe? Not used on PDEL kernel).
+
Uses different keys (AES256CBC and AES256CMAC) than check_activation_code_2.
 +
 
 +
Used only on TOOL rev 3.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 166: Line 188:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x80 || [[SceSblSsMgr#SceKitActivationData|SceKitActivationData]]
+
| 0x0 || 0x80 || Input: [[SceSblSsMgr|SceKitActivationData]]
 
|}
 
|}
  
=== 0x2 check_activation_code_2 ===
+
=== 0x2 - check_activation_code_2 ===
  
Only on pre 2.10.
+
Removed on FW 2.10.
  
Verify SceKitActivationData derived from AFV.
+
Verify SceKitActivationData read from sd0:VITA.ACT.
  
Use PDEL/PTEL keys. (maybe also latest DEM)
+
Uses different keys (AES256CBC and AES256CMAC) than check_activation_code_1.
 +
 
 +
Used on any Kit other than TOOL rev 3 (uses command 1), TEST, TOOL rev 4, Manufacturing Mode and QA flagged (bypasses activation).
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 181: Line 205:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x80 || [[SceSblSsMgr#SceKitActivationData|SceKitActivationData]]
+
| 0x0 || 0x80 || Input: [[SceSblSsMgr|SceKitActivationData]]
 
|}
 
|}
  
=== 0x4 check_cmac ===
+
=== 0x4 - check_nvs_cmac ===
  
Verify ?NVS? activation data. Maybe checks CMAC.
+
Not present on FW 0.931.
 +
 
 +
Verify NVS activation data authenticity using CMAC.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 192: Line 218:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x80 || input and output: [[SceSblSsMgr#SceKitActivationData|SceKitActivationData]]
+
| 0x0 || 0x20 || Input: [[SceSblSsMgr|SceNVSKitActivationData]]
 
|}
 
|}
  
=== 0x5 gen_act_cmac ===
+
=== 0x5 - gen_nvs_cmac ===
  
Only on pre 2.10.
+
Removed on FW 2.10.
  
Get activation data. The returned data is written to NVS at offset 0x520 or 0x530.
+
Generate CMAC of NVS activation data. The returned data is written to NVS at offset 0x520 or 0x530.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 205: Line 231:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || Magic "act\0"
+
| 0x0 || 0x4 || Magic "act\0"
 
|-
 
|-
| 0x44 || 0x4 || Issue number
+
| 0x4 || 0x4 || Issue number
 
|-
 
|-
| 0x48 || 0x4 || Start validity time unix timestamp
+
| 0x8 || 0x4 || Start validity time unix timestamp
 
|-
 
|-
| 0x4C || 0x4 || End validity time unix timestamp
+
| 0xC || 0x4 || End validity time unix timestamp
 
|-
 
|-
| 0x50 || 0x10 || Unknown (returned data) ?CMAC?
+
| 0x10 || 0x10 || Output: CMAC of the 0x10 input bytes
 
|}
 
|}
  
 
=== 0x7 ===
 
=== 0x7 ===
  
Only on pre 2.10.
+
Removed on FW 2.10.
  
 
Check if activation is valid. The input activation data is read from NVS at offset 0x520.
 
Check if activation is valid. The input activation data is read from NVS at offset 0x520.
Line 226: Line 252:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x10 || SceKitNVSActivationData without CMAC
+
| 0x0 || 0x10 || [[SceSblSsMgr|SceNVSKitActivationData]] without CMAC
 
|-
 
|-
| 0x50 || 0x20 || SceKitNVSActivationData
+
| 0x10 || 0x20 || [[SceSblSsMgr|SceNVSKitActivationData]]
 
|}
 
|}
  
=== 0xA gen_activation_with_sig ===
+
=== 0xA - gen_activation_with_sig ===
  
Introduced in 2.10.
+
Introduced in FW 2.10.
  
 
Check if new activation is valid. Extended activation check with a signature. This is ran when installing a new afv.
 
Check if new activation is valid. Extended activation check with a signature. This is ran when installing a new afv.
Line 241: Line 267:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x80 || [[SceSblSsMgr#SceKitActivationData|SceKitActivationData]] (new activation data)
+
| 0x0 || 0x80 || Input: [[SceSblSsMgr#|SceKitActivationData]] (new activation data)
 
|-
 
|-
| 0xC0 || 0x100 || RSA signature over new activation data
+
| 0x80 || 0x100 || Input: RSA signature over new activation data
 
|-
 
|-
| 0x1C0 || 0x80 ||[[SceSblSsMgr#SceKitActivationData|SceKitActivationData]] (previous activation data)
+
| 0x180 || 0x80 || Input: [[SceSblSsMgr|SceKitActivationData]] (previous activation data)
 
|-
 
|-
| 0x240 || 0x100 || RSA signature over previous activation data
+
| 0x200 || 0x100 || Input: RSA signature over previous activation data
 
|-
 
|-
| 0x340 || 0x20 || Output: SceKitNVSActivationData (same as command 0x4)
+
| 0x300 || 0x20 || Output: [[SceSblSsMgr|SceNVSKitActivationData]]
 
|}
 
|}
  
=== 0xB check_activation_with_sig ===
+
=== 0xB - check_activation_with_sig ===
  
Introduced in 2.10.
+
Introduced in FW 2.10.
  
Check if current activation is valid. Extended activation check with signature. This is ran on boot.
+
Check if Kit Activation Data is valid and not expired. Extended activation check with signature. This command is ran on boot.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 262: Line 288:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || Unknown
+
| 0x0 || 0x4 || Input: Previous return value
 +
|-
 +
| 0x4 || 0x4 || Input: Current time
 
|-
 
|-
| 0x44 || 0x4 || Current time
+
| 0x8 || 0x4 || Output: License Status
 
|-
 
|-
| 0x48 || 0x8 || Some return value
+
| 0xC || 0x4 || Output: Expire Date
 
|-
 
|-
| 0x50 || 0x8 || Unknown
+
| 0x10 || 0x8 || Reserved
 
|-
 
|-
| 0x58 || 0x20 || SceKitNVSActivationData (same as command 0x4)
+
| 0x18 || 0x20 || Input: [[SceSblSsMgr|SceNVSKitActivationData]] (read from NVS offset 0x520)
 
|-
 
|-
| 0x78 || 0x80 || AFV data
+
| 0x38 || 0x80 || Input: [[SceSblSsMgr|SceKitActivationData]] (read from tm0:activate/act.dat)
 
|-
 
|-
| 0xF8 || 0x100 || RSA signature over activation data
+
| 0xB8 || 0x100 || Input: RSA signature over activation data (read from tm0:activate/actsig.dat)
 
|}
 
|}
  
 
== aimgr_sm.self ==
 
== aimgr_sm.self ==
  
=== 0x1 ConsoleId ===
+
=== 0x1 - GetConsoleId ===
  
 
Returns the console's [[ConsoleId]].
 
Returns the console's [[ConsoleId]].
Line 285: Line 313:
 
Used in [[SceSblSsMgr#sceSblAimgrGetConsoleIdForDriver|sceSblAimgrGetConsoleIdForDriver]].
 
Used in [[SceSblSsMgr#sceSblAimgrGetConsoleIdForDriver|sceSblAimgrGetConsoleIdForDriver]].
  
=== 0x2 OpenPsId ===
+
=== 0x2 - GetOpenPsId ===
  
 
Returns the console's [[OpenPsId]].
 
Returns the console's [[OpenPsId]].
Line 291: Line 319:
 
Used in [[SceSblSsMgr#sceSblAimgrGetOpenPsIdForDriver|sceSblAimgrGetOpenPsIdForDriver]].
 
Used in [[SceSblSsMgr#sceSblAimgrGetOpenPsIdForDriver|sceSblAimgrGetOpenPsIdForDriver]].
  
=== 0x3 VisibleId ===
+
=== 0x3 - GetVisibleId ===
  
 
Returns the console's [[VisibleId]].
 
Returns the console's [[VisibleId]].
Line 297: Line 325:
 
Used in [[SceSblSsMgr#sceSblAimgrGetVisibleIdForDriver|sceSblAimgrGetVisibleIdForDriver]].
 
Used in [[SceSblSsMgr#sceSblAimgrGetVisibleIdForDriver|sceSblAimgrGetVisibleIdForDriver]].
  
=== 0x4 PsCode ===
+
=== 0x4 - GetPsCode ===
  
 
Returns the console's [[PsCode]].
 
Returns the console's [[PsCode]].
Line 303: Line 331:
 
Used in [[SceSblSsMgr#sceSblAimgrGetPscode2ForDriver|sceSblAimgrGetPscode2ForDriver]].
 
Used in [[SceSblSsMgr#sceSblAimgrGetPscode2ForDriver|sceSblAimgrGetPscode2ForDriver]].
  
=== 0x5 PassPhrase ===
+
=== 0x5 - CreatePassPhrase ===
  
 
Used in [[SceSblSsMgr#sceSblSsCreatePassPhraseForDriver|sceSblSsCreatePassPhraseForDriver]].
 
Used in [[SceSblSsMgr#sceSblSsCreatePassPhraseForDriver|sceSblSsCreatePassPhraseForDriver]].
Line 309: Line 337:
 
== compat_sm.self ==
 
== compat_sm.self ==
  
=== 0x10006 ===
+
Compat SM functions only works on DEX and CEX units, or on units in Manufacturing Mode or with a certain QA Flag. This is why most DevKit units don't have access to PSPEmu.
Seems to be called on init and before resume of PSP
+
 
 +
=== 0x10006 - sceCompatSecLoadSCBootCode ===
 +
 
 +
Load Secure CPU Boot Code. PSP main CPU (Tachyon codename) is an Allegrex 32-bit little-endian RISC CPU with FPU and VFPU, 1 ~ 333MHz, MIPS III-based.
 +
 
 +
Called on init and before resume of PSP.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 316: Line 349:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || Unknown
+
| 0x40 || 0x4 || Boot/resume cookie. Pass 0 when cold booting, <code>resume_handler ^ magic</code> when resuming
|-
 
| 0x44 || 0x4 || Set to 0
 
 
|-
 
|-
 +
| 0x44 || 0x4 || Set to 0 (unused)
 
|}
 
|}
  
=== 0x20006 ===
+
On FW 3.73 (simplified):
 +
 
 +
<source lang="C">
 +
*(u32 *)SceSonyRegbus_e8000004 = 4;
 +
syncm();
 +
memcpy(SceCompatSharedSram_e8100000, g_pre_ipl, 0x1000);  // PRE-IPL
 +
memcpy(SceCompatSharedSram_e8100fc0, g_challenge, 0x40);  // Challenge (IPL XOR key)
 +
memcpy(SceCompatSharedSram_e8100fbc, &cookie, 4);        // Boot/resume cookie
 +
syncm();
 +
*(u32 *)SceSonyRegbus_e8000004 = 0;
 +
</source>
 +
 
 +
If an error occurs during SCBootCode loading:
 +
 
 +
<source lang="c">
 +
memset(SceCompatSharedSram_e8100000, 0, 0x1000); // PRE-IPL
 +
syncm();
 +
*(u32 *)SceSonyRegbus_e8000004 = 10;
 +
</source>
 +
 
 +
The cookie, which represents the address where PRE-IPL will jump to when resuming, is passed by MIPS to ARM (written to <code>0xBFC001FC</code>) just before suspending, and it is calculated the same way as [https://github.com/mathieulh/Utopia_PSP/blob/master/371_main.bin.c#L409 on actual PSP], only that using <source lang="c">u8 data[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0x00, 0xde, 0xf0 };</source> as input to the SHA1, instead of the MAC address.
 +
 
 +
=== 0x20006 - sceCompatSecSetSSRAMAcl ===
 +
 
 +
Set Shared Static Random Access Memory Access-control list.
 +
 
 +
Removed since FW 3.50 and replaced by command 0x30006.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 334: Line 392:
 
|}
 
|}
  
== encdec_w_portability_sm.self ==
+
=== 0x30006 - sceCompatSecSetSSRAMAcl2 ===
 +
 
 +
Set Shared Static Random Access Memory Access-control list 2.
 +
 
 +
Appeared on FW 3.50 as replacement for command 0x20006. This change is related to the huge memory management improvement since FW 3.50. See [https://www.neogaf.com/threads/ps-vita-system-software-3-50-adds-30-more-memory-for-game-use.1028194/ PSVita System software 3.50 adds 30% more memory for game use].
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Offset !! Size !! Description
 +
|-
 +
| 0x40 || 0x4 || Unused
 +
|-
 +
|}
 +
 
 +
On 3.73-CEX (simplified):
 +
<source lang="c">
 +
*(u32 *)SceSonyRegbus_e8000004 = 4;
 +
syncm();
 +
ret = memcmp(SceCompatSharedSram_e8100fc0, g_challenge_result, 0x40); // Check challenge output
 +
if (ret == 0) {
 +
    // Success!!
 +
}
 +
syncm();
 +
*(u32 *)SceSonyRegbus_e8000004 = 10;
 +
</source>
 +
 
 +
== encdec_w_portability_sm.self ==
  
 
This seems to be used to do some kind of key derivation. May also be used as a general purpose encryption engine.
 
This seems to be used to do some kind of key derivation. May also be used as a general purpose encryption engine.
  
=== 0x1000A ===
+
=== 0x1000A - EncryptWithPortability ===
  
Encrypt data? Actually it always returns <code>0x800F1725</code>, so it does nothing.
+
Encrypt data. Actually it always returns <code>0x800F1725</code>, so it does nothing and is never used.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 357: Line 441:
 
|-
 
|-
 
| 0x8C || 0x10 || IV
 
| 0x8C || 0x10 || IV
|-
 
 
|}
 
|}
  
=== 0x2000A DecryptWithPortability ===
+
=== 0x2000A - DecryptWithPortability ===
  
 
Used by [[SceSblSsMgr#sceSblSsDecryptWithPortabilityForDriver|sceSblSsDecryptWithPortabilityForDriver]].
 
Used by [[SceSblSsMgr#sceSblSsDecryptWithPortabilityForDriver|sceSblSsDecryptWithPortabilityForDriver]].
Line 381: Line 464:
 
|-
 
|-
 
| 0x8C || 0x10 || IV
 
| 0x8C || 0x10 || IV
|-
 
 
|}
 
|}
  
Return of 0x800f0002 means invalid service ID. For encdec_w_portability_sm, only 0x1000A and 0x2000A are supported.
+
Return value of 0x800f0002 means invalid service ID. For encdec_w_portability_sm, only commmands 0x1000A and 0x2000A are supported.
  
Return of 0x800f1716 means invalid argument such as invalid key ID. Valid key IDs are only 1-20.
+
Return value of 0x800f1716 means invalid argument such as invalid key ID. Valid key IDs are only 1-20.
  
 
== gcauthmgr_sm.self ==
 
== gcauthmgr_sm.self ==
Line 392: Line 474:
 
=== 0x1000B ===
 
=== 0x1000B ===
  
This is one of variable sized buffers that can be placed inside [[F00D_Commands#Request_Buffer|Request_Buffer]]
+
This is one of the variable sized buffers that can be placed inside [[F00D_Commands#Request_Buffer|Request_Buffer]].
  
Type definition is located here [[SceSblSsSmComm#sceSblSmCommCallFuncForKernel|sm_comm_context]]
+
Response value returned to Kernel comes from [[F00D_Commands#Request_Buffer|Request Buffer]] at offset 8.
 +
 
 +
<source lang="C">
 +
// gc_param is generated by game card and has value 0x01
 +
typedef struct SceSblSmCommGcData { // size is 0x814
 +
int unk_0; // 1
 +
int command;
 +
char data[0x800];
 +
int key_id;
 +
int size;
 +
int unk_810; // 0
 +
} SceSblSmCommGcData;
 +
</source>
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 411: Line 505:
 
|-
 
|-
 
| 0x850 || 0x4 || Set to 0
 
| 0x850 || 0x4 || Set to 0
|-
 
 
|}
 
|}
  
Supported GC commands and structures
+
Following are the supported "KIRK" commands.
 +
 
 +
==== 0x4 - encrypt_with_portability ====
  
==== 0x4 kirk_encrypt ====
 
 
Original PSP Kirk 4 service for encrypting data.
 
Original PSP Kirk 4 service for encrypting data.
  
Line 425: Line 519:
 
Uses one set of keys.
 
Uses one set of keys.
  
Available <code>Key ID</code> values are (key is encrypted with key from keyslot 0x345 and put into keyslot 0x21): 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x38, 0x39, 0x3A, 0x80, 0x81, 0x82, 0x83
+
Available <code>Key ID</code> values are (key is encrypted with key from keyslot 0x345 and put into keyslot 0x21): 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x38, 0x39, 0x3A, 0x80, 0x81, 0x82, 0x83.
  
 
Special <code>Key ID</code> 0x100 is available. Uses keys from keyslots 0x601 and 0x602.
 
Special <code>Key ID</code> 0x100 is available. Uses keys from keyslots 0x601 and 0x602.
Line 435: Line 529:
 
seed is aes cbc encrypted with key to produce resulting key.
 
seed is aes cbc encrypted with key to produce resulting key.
  
==== 0x7 kirk_decrypt ====
+
==== 0x7 - decrypt_with_portability ====
Original PSP Kirk 7 service for decrypting data
+
 
 +
Original PSP Kirk 7 service for decrypting data.
  
 
Does not use any specific data structure in <code>Data Buffer</code>.
 
Does not use any specific data structure in <code>Data Buffer</code>.
Line 444: Line 539:
 
Uses two sets of keys.
 
Uses two sets of keys.
  
Available key ids are (key is encrypted with key from keyslot 0x345 and put into keyslot 0x21): 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x38, 0x39, 0x3A, 0x80, 0x81, 0x82, 0x83
+
Available key ids are (key is encrypted with key from keyslot 0x345 and put into keyslot 0x21): 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x38, 0x39, 0x3A, 0x80, 0x81, 0x82, 0x83.
  
Available <code>Key ID</code> values are (key is encrypted with key from keyslot 0x340 and put into keyslot 0x10): 0x44, 0x53, 0x57, 0x63, 0x64, 0x68, 0xC0, 0xC1, 0xC2, 0xC3
+
Available <code>Key ID</code> values are (key is encrypted with key from keyslot 0x340 and put into keyslot 0x10): 0x44, 0x53, 0x57, 0x63, 0x64, 0x68, 0xC0, 0xC1, 0xC2, 0xC3.
  
 
Special <code>Key ID</code> 0x100 is available. Uses keys from keyslots 0x601 and 0x602 (will be documented later).
 
Special <code>Key ID</code> 0x100 is available. Uses keys from keyslots 0x601 and 0x602 (will be documented later).
Line 456: Line 551:
 
seed is aes cbc encrypted with key to produce resulting key.
 
seed is aes cbc encrypted with key to produce resulting key.
  
==== 0xC kirk_ecc160_generate_keys ====
+
==== 0xC - ecc160_generate_keys ====
 +
 
 
Original PSP Kirk 0xC service for Generating a 160bit ECC private/public keypair. Call with an empty buffer of length 0x3C. The structure below is the return structure.
 
Original PSP Kirk 0xC service for Generating a 160bit ECC private/public keypair. Call with an empty buffer of length 0x3C. The structure below is the return structure.
  
Line 482: Line 578:
 
|}
 
|}
  
==== 0xD kirk_ecc160_multiply ====
+
==== 0xD - ecc160_multiply ====
 +
 
 
Original PSP Kirk 0xD service for multiplying a 160bit ECC curve point with a value. Call with a multiplier, x and y point value.
 
Original PSP Kirk 0xD service for multiplying a 160bit ECC curve point with a value. Call with a multiplier, x and y point value.
  
Line 509: Line 606:
 
|}
 
|}
  
==== 0xE kirk_ecc160_generate_random ====
+
==== 0xE - ecc160_prngen ====
Original PSP Kirk 0xE service for 160bit Random number generation. Call with an empty buffer, the result structure is below.
+
 
 +
Original PSP Kirk 0xE service for 160bit Random number generation. Call with an empty buffer.
  
Output:
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x0|| 0x14 || Cryptographic Random Number
+
| 0x0|| 0x14 || Output: Pseudo Random Number
 
|-
 
|-
 
|}
 
|}
  
==== 0x10 kirk_ecc160_sign ====
+
==== 0x10 - ecc160_sig_gen ====
 +
 
 
Original PSP Kirk 0x10 service for 160bit ECC signing.
 
Original PSP Kirk 0x10 service for 160bit ECC signing.
  
Line 539: Line 637:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x0|| 0x20 || Encrypted private key (see kirk-engine implementation for fuse_id process for encryption)
+
| 0x0|| 0x20 || Encrypted private key
 
|-
 
|-
| 0x20|| 0x14 || SHA1 hash of the content you want signed
+
| 0x20|| 0x14 || SHA1 hash of the content to sign
 
|-
 
|-
 
|}
 
|}
Line 556: Line 654:
 
|}
 
|}
  
==== 0x11 kirk_ecc160_verify ====
+
==== 0x11 - ecc160_sig_verify ====
 +
 
 
Original PSP Kirk 0x11 service for 160bit ECC signature verification. Call with the below structure, then function will return pass or fail.
 
Original PSP Kirk 0x11 service for 160bit ECC signature verification. Call with the below structure, then function will return pass or fail.
 +
 +
Input size is 0x64 bytes.
  
 
Input:
 
Input:
Line 568: Line 669:
 
| 0x14|| 0x14 || Public Key Y component
 
| 0x14|| 0x14 || Public Key Y component
 
|-
 
|-
| 0x28|| 0x14 || SHA1 hash of the content that is signed
+
| 0x28|| 0x14 || SHA1 hash of the signed content
 
|-
 
|-
 
| 0x3C|| 0x14 || ECC Signature R component
 
| 0x3C|| 0x14 || ECC Signature R component
 
|-
 
|-
 
| 0x50|| 0x14 || ECC Signature S component
 
| 0x50|| 0x14 || ECC Signature S component
|-
 
 
|}
 
|}
  
==== 0x12 verify_cmac_signature ====
+
No output.
 +
 
 +
==== 0x12 - cert_verify ====
  
 
This function checks that CMAC of <code>Message</code> equals <code>Encrypted CMAC value</code>.
 
This function checks that CMAC of <code>Message</code> equals <code>Encrypted CMAC value</code>.
Line 597: Line 699:
 
|}
 
|}
  
==== 0x14 kirk_ecc224_generate_keys ====
+
==== 0x14 - ecc224_generate_keys ====
New Vita Kirk 0x14 service for Generating a 224bit ECC private/public keypair. Call with an empty buffer of length 0x54. The structure below is the return structure.
+
 
 +
New Vita Kirk 0x14 service for generating a 224bit ECC private/public keypair. Call with an empty buffer of length 0x54. The structure below is the return structure.
  
 
Private key <code>dA</code> is obtained by:
 
Private key <code>dA</code> is obtained by:
Line 623: Line 726:
 
|}
 
|}
  
==== 0x15 kirk_ecc224_multiply ====
+
==== 0x15 - ecc224_multiply ====
 +
 
 
New Vita Kirk 0x15 service for multiplying a 224bit ECC curve point with a value. Call with a multiplier, x and y point value.
 
New Vita Kirk 0x15 service for multiplying a 224bit ECC curve point with a value. Call with a multiplier, x and y point value.
  
Line 650: Line 754:
 
|}
 
|}
  
==== 0x16 kirk_ecc224_generate_random ====
+
==== 0x16 - ecc224_prngen ====
New Vita Kirk 0x16 service for 224bit Random number generation. Call with an empty buffer, the result structure is below.
+
 
 +
New Vita Kirk 0x16 service for 224bit Random number generation. Call with an empty buffer.
  
Output:
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x0|| 0x1C || Cryptographic Random Number
+
| 0x0|| 0x1C || Output: Pseudo Random Number
 
|-
 
|-
 
|}
 
|}
  
==== 0x17 kirk_ecc224_sign ====
+
==== 0x17 - ecc224_sig_gen ====
 +
 
 
New Vita Kirk 0x17 service for 224bit ECC signing.
 
New Vita Kirk 0x17 service for 224bit ECC signing.
  
Line 697: Line 802:
 
|}
 
|}
  
==== 0x18 kirk_ecc224_verify ====
+
==== 0x18 - ecc224_sig_verify ====
 +
 
 
New Vita Kirk 0x18 service for 224bit ECDSA signature verification. Call with the below structure, then function will return pass or fail.
 
New Vita Kirk 0x18 service for 224bit ECDSA signature verification. Call with the below structure, then function will return pass or fail.
  
Line 715: Line 821:
 
| 0x70|| 0x1C || ECC Signature S component
 
| 0x70|| 0x1C || ECC Signature S component
 
|-
 
|-
 
 
|}
 
|}
  
==== 0x19 verify_cmac_signature ====
+
==== 0x19 - cert_verify_new ====
  
 
This function checks that CMAC of <code>Message</code> equals <code>Encrypted CMAC value</code>.
 
This function checks that CMAC of <code>Message</code> equals <code>Encrypted CMAC value</code>.
Line 728: Line 833:
 
Key in keyslot 0x0 is derived using key from keyslot 0x204 with static seed value.
 
Key in keyslot 0x0 is derived using key from keyslot 0x204 with static seed value.
  
This function is related to IdStorage somehow.
+
This function is used to verify PSVita new IdStorage Certificates.
  
 
Input:
 
Input:
Line 735: Line 840:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x0|| 0xD8 || Message
+
| 0x0|| 0xE8 || Input: Certificate
|-
 
| 0xD8|| 0x10 || Encrypted CMAC value
 
|-
 
 
|}
 
|}
  
==== 0x1B check_gc_authenticity ====
+
==== 0x1B - check_gc_authenticity ====
 +
 
 
New Vita Kirk 0x1B service. This service is related to SceSdif and is used by SceSblGcAuthMgr.
 
New Vita Kirk 0x1B service. This service is related to SceSdif and is used by SceSblGcAuthMgr.
 
This service is part of SD MMC CMD56 custom initialization protocol.
 
This service is part of SD MMC CMD56 custom initialization protocol.
Line 747: Line 850:
  
 
- packet 7 should contain challenge0 for the card that can be encrypted (by card) with key_id and master_key.
 
- packet 7 should contain challenge0 for the card that can be encrypted (by card) with key_id and master_key.
 
  
 
- packet 8 should contain encrypted message which can be decrypted (by vita) with key_id and master_key.  
 
- packet 8 should contain encrypted message which can be decrypted (by vita) with key_id and master_key.  
Line 757: Line 859:
 
- this way we know that card knows how to properly encrypt.
 
- this way we know that card knows how to properly encrypt.
  
 
+
- Kirk service 1B will decrypt packet 8 with key_id and master_key
- kirk service 1B will decrypt packet 8 with key_id and master_key
 
  
 
- then it will verify challenge0
 
- then it will verify challenge0
Line 774: Line 875:
 
|}
 
|}
  
==== 0x1C generate_vita_authenticity_proof ====
+
==== 0x1C - generate_vita_authenticity_proof ====
 +
 
 
New Vita Kirk 0x1C service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol.  
 
New Vita Kirk 0x1C service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol.  
 
This is a data generation service. Size of request is 0x40. Size of response is 0x33.
 
This is a data generation service. Size of request is 0x40. Size of response is 0x33.
Line 787: Line 889:
  
 
- then packet 9 will be encrypted with key_id and master_key
 
- then packet 9 will be encrypted with key_id and master_key
 
  
 
- packet 9 should contain encrypted message which can be decrypted (by card) with key_id and master_key.  
 
- packet 9 should contain encrypted message which can be decrypted (by card) with key_id and master_key.  
Line 821: Line 922:
 
|}
 
|}
  
==== 0x1D challenge_handshake ====
+
==== 0x1D - challenge_handshake ====
 +
 
 
New Vita Kirk 0x1D service. This service is related to SceSdif and is used by SceSblGcAuthMgr.  
 
New Vita Kirk 0x1D service. This service is related to SceSdif and is used by SceSblGcAuthMgr.  
 
This service is part of SD MMC CMD56 custom initialization protocol. This is a data validation service with no response. Size of request is 0xA3.
 
This service is part of SD MMC CMD56 custom initialization protocol. This is a data validation service with no response. Size of request is 0xA3.
Line 827: Line 929:
 
- packet 13 should contain challenge1 for the card that can be encrypted (by card) with key_id and master_key.
 
- packet 13 should contain challenge1 for the card that can be encrypted (by card) with key_id and master_key.
  
- packet 14 should contain challenge1 and master_key that are encrypted (by card) with key_id and master_key
+
- packet 14 should contain challenge1 and master_key that are encrypted (by card) with key_id and master_key.
  
 
+
- kirk service 0x1D will decrypt secondary_key0 from packet 9 with key_id and master_key
- kirk service 1D will decrypt secondary_key0 from packet 9 with key_id and master_key
 
  
 
- then it will decrypt packet 14
 
- then it will decrypt packet 14
Line 852: Line 953:
 
|}
 
|}
  
==== 0x1E generate_packets_15_17_with_cmac_signature ====
+
==== 0x1E - generate_packets_15_17_with_cmac_signature ====
 +
 
 
New Vita Kirk 0x1E service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data generation service. Size of request is 0x51. Size of response is 0x33.
 
New Vita Kirk 0x1E service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data generation service. Size of request is 0x51. Size of response is 0x33.
  
Line 899: Line 1,001:
 
|}
 
|}
  
==== 0x1F decrypt_packet_16 ====
+
==== 0x1F - decrypt_packet_16 ====
 +
 
 
New Vita Kirk 0x1F service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data validation service. Size of request is 0xB3. Size of response is 0x20.
 
New Vita Kirk 0x1F service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data validation service. Size of request is 0xB3. Size of response is 0x20.
  
Line 944: Line 1,047:
 
|}
 
|}
  
==== 0x20 get_klicensee_keys_with_rif_cmac_signature ====
+
==== 0x20 - get_klicensee_keys_with_rif_cmac_signature ====
 +
 
 
New Vita Kirk 0x20 service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data generation service. Size of request is 0x116. Size of response is 0x34.
 
New Vita Kirk 0x20 service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data generation service. Size of request is 0x116. Size of response is 0x34.
  
Line 979: Line 1,083:
 
|}
 
|}
  
==== 0x21 kirk_ecc160_sign ====
+
==== 0x21 - ecc160_hmac_sha256_sig_gen ====
 +
 
 
New Vita Kirk 0x21 service for 160bit ECC signing.  
 
New Vita Kirk 0x21 service for 160bit ECC signing.  
  
Line 999: Line 1,104:
 
| 0x0|| 0x20 || unknown, must be zeroes
 
| 0x0|| 0x20 || unknown, must be zeroes
 
|-
 
|-
| 0x20|| 0x14 || message hash
+
| 0x20|| 0x14 || Message hash
 
|-
 
|-
 
|}
 
|}
Line 1,014: Line 1,119:
 
|}
 
|}
  
==== 0x22 kirk_ecc224_sign_sceebootpbp ====
+
==== 0x22 - ecc224_sceebootpbp_sig_gen ====
 +
 
 
New Vita Kirk 0x22 service for 224bit ECC signing.  
 
New Vita Kirk 0x22 service for 224bit ECC signing.  
  
Line 1,051: Line 1,157:
 
|}
 
|}
  
==== 0x23 generate_cmac_signature ====
+
==== 0x23 - generate_cmac_signature ====
 +
 
 
New Vita Kirk 0x23 service.
 
New Vita Kirk 0x23 service.
 +
 +
It encrypts the plain message with AES128CBC, static key and null IV, then calculates the AES128CMAC of the encrypted message with another static key.
  
 
Input:
 
Input:
Line 1,059: Line 1,168:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x0|| 0x10 || Message
+
| 0x0|| 0x10 || Plain message
 
|-
 
|-
 
|}
 
|}
Line 1,068: Line 1,177:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x0|| 0x10 || Encrypted Message
+
| 0x0|| 0x10 || Encrypted message
 
|-
 
|-
| 0x10|| 0x10 || Encrypted Message CMAC
+
| 0x10|| 0x10 || Encrypted message CMAC
 
|-
 
|-
 
|}
 
|}
Line 1,078: Line 1,187:
 
[[SceSblPostSsMgr#sceSblPmMgrAuthEtoIForDriver|sceSblPmMgrAuthEtoIForDriver]] uses "sd0:sm/pm_sm_sd.self" whilst other PmSm functions use "os0:sm/pm_sm.self".
 
[[SceSblPostSsMgr#sceSblPmMgrAuthEtoIForDriver|sceSblPmMgrAuthEtoIForDriver]] uses "sd0:sm/pm_sm_sd.self" whilst other PmSm functions use "os0:sm/pm_sm.self".
  
Services 9 and 0xA appeared on 1.03 (maybe 1.00). They are not present on 0.990 and earlier.
+
Services 8, 9 and 0xA appeared on FW 1.03 (maybe 1.00). They are not present on FW 0.990 and earlier.
 +
 
 +
Keyset must be between 0-0xC on FW 0.931.
  
=== 0x1 get_product_mode ===
+
=== 0x1 - get_product_mode ===
  
 
Used by sceSblPmMgrGetProductModeFromNVS.
 
Used by sceSblPmMgrGetProductModeFromNVS.
  
Data size is 0x28 bytes. (0x20 bytes used)
+
Data size is 0x28 bytes.
  
 
Input: 0x20 buffer read from NVS at offset 0.
 
Input: 0x20 buffer read from NVS at offset 0.
Line 1,091: Line 1,202:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || Output: product mode
+
| 0x40 || 0x4 || Output: Product Mode
 
|-
 
|-
| 0x44 || 0x4 || zeroed
+
| 0x44 || 0x4 || Reserved
 
|-
 
|-
| 0x48 || 0x20 || input only: NVS data read at offset 0
+
| 0x48 || 0x20 || Input: NVS block read at offset 0
 
|}
 
|}
  
=== 0x2 set_product_mode ===
+
=== 0x2 - set_product_mode ===
  
 
Used by sceSblPmMgrSetProductMode.
 
Used by sceSblPmMgrSetProductMode.
  
Data size is 0x28 bytes. (0x20 bytes used)
+
Data size is 0x28 bytes.
  
 
Input: 0x20 bytes buffer read from NVS at offset 0, to which is written the new product mode to set.
 
Input: 0x20 bytes buffer read from NVS at offset 0, to which is written the new product mode to set.
Line 1,111: Line 1,222:
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || new product mode
+
| 0x40 || 0x4 || Input: Product Mode
 
|-
 
|-
| 0x44 || 0x1C || output only
+
| 0x44 || 0x4 || Reserved
 +
|-
 +
| 0x48 || 0x20 || Input and output: NVS block read/written at offset 0
 
|}
 
|}
  
=== 0x3 gen_req_hello ===
+
=== 0x3 - gen_req_hello ===
  
Input: 0x30 bytes buffer.
+
This command gets the Ernie secure packet for the first JIG auth command.
  
This is the first JIG auth command. The 0x28 buffer content is for the first time set by this service.
+
Data size is 0x30 bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || arg1 (6 or 14)
+
| 0x40 || 0x4 || Input: keyset (6, 14)
 
|-
 
|-
| 0x44 || 0x4 || arg2 (1 when arg1 in [4, 6, 12]; 2 when arg1 in [14]; otherwise undefined)
+
| 0x44 || 0x4 || Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
 
|-
 
|-
| 0x48 || 0x28 || output only
+
| 0x48 || 0x28 || Output: Ernie secure packet
 
|}
 
|}
  
=== 0x4 gen_challenge ===
+
=== 0x4 - gen_challenge ===
  
Input: 0x30 bytes buffer.
+
Data size is 0x30 bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || arg1 (6 or 14)
+
| 0x40 || 0x4 || Input: keyset (6, 14)
 
|-
 
|-
| 0x44 || 0x4 || arg2 (1 when arg1 in [4, 6, 12]; 2 when arg1 in [14]; otherwise undefined)
+
| 0x44 || 0x4 || Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
 
|-
 
|-
| 0x48 || 0x28 || input and output
+
| 0x48 || 0x28 || Input and output: Ernie secure packet
 
|}
 
|}
  
=== 0x5 check_response ===
+
=== 0x5 - check_response ===
  
Input: 0x30 bytes buffer.
+
Returns 0 on success.
  
Returns 0 on success, doesn't modify the input buffer.
+
Data size is 0x30 bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || arg1 (6 or 14)
+
| 0x40 || 0x4 || input: keyset (6, 14)
 
|-
 
|-
| 0x44 || 0x4 || arg2 (1 when arg1 in [4, 6, 12]; 2 when arg1 in [14]; otherwise undefined)
+
| 0x44 || 0x4 || input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when arg1 in [14]; otherwise undefined)
 
|-
 
|-
| 0x48 || 0x28 || input only
+
| 0x48 || 0x28 || input: Ernie secure packet
 
|}
 
|}
  
=== 0x6 gen_req_result ===
+
=== 0x6 - gen_req_result ===
  
Input: 0x30 bytes buffer.
+
Encrypts Ernie secure packet for step 4 with the chosen keyset.
 +
 
 +
Data size is 0x30 bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || arg1 (6 or 14)
+
| 0x40 || 0x4 || Input: keyset (4, 6 on FW 0.931-3.60)
 
|-
 
|-
| 0x44 || 0x4 || arg2 (1 when arg1 in [4, 6, 12]; 2 when arg1 in [14]; otherwise undefined)
+
| 0x44 || 0x4 || Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
 
|-
 
|-
| 0x48 || 0x28 || input and output
+
| 0x48 || 0x28 || Input and output: Ernie secure packet
 
|}
 
|}
  
=== 0x7 check_result ===
+
=== 0x7 - check_result ===
  
Input: 0x30 bytes buffer.
+
Returns 0 on success.
  
Returns 0 on success, doesn't modify the input buffer.
+
Data size is 0x30 bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || arg1 (6 or 14)
+
| 0x40 || 0x4 || Input: keyset (4, 6, 14)
 
|-
 
|-
| 0x44 || 0x4 || arg2 (1 when arg1 in [4, 6, 12]; 2 when arg in [14]; otherwise undefined)
+
| 0x44 || 0x4 || Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
 
|-
 
|-
| 0x48 || 0x28 || input only
+
| 0x48 || 0x28 || Input: Ernie secure packet
 
|}
 
|}
  
=== 0x8 ===
+
=== 0x8 - run_pm_command ===
  
Used on 1.03+ by sceSblPmMgrGetProductModeFromNVS.
+
Not present in old FWs.
  
Input: 0x70 bytes buffer.
+
Used on FW 1.03+ by sceSblPmMgrGetProductModeFromNVS.
 +
 
 +
Data size is 0x70 bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || new product mode
+
| 0x40 || 0x4 || Input: Command (0: gen_get_mgmt_data_req, 1: get_mgmt_data, 3: decrypt_response, 4: set_product_mode, 5: set_product_mode_off, 7: set_sd_mode_off)
 
|-
 
|-
| 0x44 || 0x4 || 0
+
| 0x44 || 0x4 || Reserved
 
|-
 
|-
| 0x48 || 0x4 || out1: current product mode
+
| 0x48 || 0x4 || Input and output: product mode
 
|-
 
|-
| 0x4C || 0x4 || out2
+
| 0x4C || 0x4 || Input and output: unknown Mgmt Data
 
|-
 
|-
| 0x50 || 0x60 || unk
+
| 0x50 || 0x30 || Input and output: Ernie secure packet for setting Product Mode
 +
|-
 +
| 0x80 || 0x30 || Input and output: Ernie secure packet for getting Product mode
 
|}
 
|}
  
=== 0x9 gen_jig_message ===
+
=== 0x9 - gen_jig_message ===
  
Only on 1.03+.
+
Only on FW 1.03+.
  
Input: 0x10C bytes buffer.
+
Data size is 0x10C bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || arg1: flag.
+
| 0x40 || 0x4 || Input: keyset_flag (0x48 for keyset 4, 0x49 for keyset 12)
 
|-
 
|-
| 0x44 || 0x4 || arg2
+
| 0x44 || 0x4 || Reserved
 
|-
 
|-
| 0x48 || 0x104 || output
+
| 0x48 || 0x104 || Output: jig_message
 
|}
 
|}
  
=== 0xA check_jig_response ===
+
=== 0xA - check_jig_response ===
 +
 
 +
Only on FW 1.03+.
  
Only on 1.03+.
+
Returns 0 on success.
  
Input: 0x10C bytes buffer.
+
Data size is 0x10C bytes.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! Offset !! Size !! Description
 
! Offset !! Size !! Description
 
|-
 
|-
| 0x40 || 0x4 || arg1: flag.
+
| 0x40 || 0x4 || Input: keyset_flag (0x48 for keyset 4, 0x49 for keyset 12)
 
|-
 
|-
| 0x44 || 0x4 || arg2
+
| 0x44 || 0x4 || Reserved
 
|-
 
|-
| 0x48 || 0x104 || input
+
| 0x48 || 0x104 || Input: jig_response
 
|}
 
|}
  
Line 1,256: Line 1,377:
 
=== 0x3 ===
 
=== 0x3 ===
  
=== 0x4 decrypt QAF version ===
+
=== 0x4 - decrypt QAF version ===
  
 
Input: 0x20 buffer read from NVS offset 0x2A0.
 
Input: 0x20 buffer read from NVS offset 0x2A0.
Line 1,273: Line 1,394:
 
|}
 
|}
  
=== 0x5 encrypt QAF version ===
+
=== 0x5 - encrypt QAF version ===
  
 
Input QAF version in this buffer of size 0x20:
 
Input QAF version in this buffer of size 0x20:
Line 1,290: Line 1,411:
 
Output of size 0x20 is then written to NVS offset 0x2A0.
 
Output of size 0x20 is then written to NVS offset 0x2A0.
  
=== 0x6 check_flag (decrypt) ===
+
=== 0x6 - check_flag (decrypt) ===
  
 
Input: 0x20 buffer read from NVS at offset 0.
 
Input: 0x20 buffer read from NVS at offset 0.
Line 1,298: Line 1,419:
 
Output  
 
Output  
  
=== 0x7 set_flag (encrypt) ===
+
=== 0x7 - set_flag (encrypt) ===
  
 
Input: 0x20 buffer.
 
Input: 0x20 buffer.
Line 1,345: Line 1,466:
 
== spkg_verifier_sm_w_key_2.self ==
 
== spkg_verifier_sm_w_key_2.self ==
  
=== 0xE0002 ===
+
This is an extension of update_service_sm.self. It was added to support command 0xE0002.
 +
 
 +
=== 0xE0002 - sceSblUsSmAuthSpkgWithKey2 ===
 +
 
 +
Used to decrypt downloaded lists (SPKGs). Same format as [[F00D Commands#0x40002|0x40002]].
  
Used to decrypt downloaded lists. Same format as [[F00D Commands#0x40002|0x40002]].
 
 
Lists URLS:
 
Lists URLS:
 
<source>
 
<source>
Line 1,359: Line 1,483:
 
This is used by [[SceSblUpdateMgr]] to decrypt update packages extracted from [[PUP]] files. Both 0x40002 and 0x50002 reference buffers in the following way: an inner paddr list is generated for the buffer containing the data to encrypt/decrypt, then an outer paddr list is generated for the inner list. That means there's two levels of indirection in the paddr list.
 
This is used by [[SceSblUpdateMgr]] to decrypt update packages extracted from [[PUP]] files. Both 0x40002 and 0x50002 reference buffers in the following way: an inner paddr list is generated for the buffer containing the data to encrypt/decrypt, then an outer paddr list is generated for the inner list. That means there's two levels of indirection in the paddr list.
  
=== 0x10002 sceSblUsSmAuthPupHeader ===
+
=== 0x10002 - sceSblUsSmAuthPupHeader ===
  
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_HEADER.
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_HEADER.
Line 1,367: Line 1,491:
 
Input data size: 0xFF0.
 
Input data size: 0xFF0.
  
=== 0x20002 sceSblUsSmAuthPupSegment ===
+
Input: PA vector of the PUP header including the PUP Hash (size: 0x80 + segment_num * 0x60 + 0x20)
 +
 
 +
=== 0x20002 - sceSblUsSmAuthPupSegment ===
  
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_SEGMENT.
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_SEGMENT.
Line 1,375: Line 1,501:
 
Input data size: 0xFF0.
 
Input data size: 0xFF0.
  
=== 0x30002 sceSblUsSmAuthPupWatermark ===
+
=== 0x30002 - sceSblUsSmAuthPupWatermark ===
  
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_WM.
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_WM.
Line 1,383: Line 1,509:
 
Input data size: 0xFF0.
 
Input data size: 0xFF0.
  
=== 0x40002 sceSblUsSmAuthSpkg ===
+
Input data: a packet embedding at least two paddr (or PA vectors): PUP Watermark (0x1000 bytes) and PUP Hash (0x20 bytes).
 +
 
 +
=== 0x40002 - sceSblUsSmAuthSpkg ===
  
 
SCE_SBL_SM_COMM_FID_SM_AUTH_SPKG.
 
SCE_SBL_SM_COMM_FID_SM_AUTH_SPKG.
  
Decrypt SPKG package. Allocate a page aligned buffer and read the complete SPKG file into the buffer. The buffer is decrypted in place.
+
Decrypt a SPKG. Allocate a page aligned buffer and read the complete SPKG file into the buffer. The buffer is decrypted in place.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 1,401: Line 1,529:
 
| 0x64 || 0x14 || <code>struct paddr_list_req</code> for pkg buffer
 
| 0x64 || 0x14 || <code>struct paddr_list_req</code> for pkg buffer
 
|-
 
|-
| 0x78 || Variable (max 0xF48) || Copy of paddr list for pkg buffer (contents described at 0x50)
+
| 0x78 || Variable (max 0xF88(0x1F1 entry)) || Copy of paddr list for pkg buffer (contents described at 0x50)
 
|}
 
|}
  
=== 0x50002 sceSblUsSmEncryptIndividualSLSK ===
+
=== 0x50002 - sceSblUsSmEncryptIndividualSLSK ===
  
 
SCE_SBL_SM_COMM_FID_SM_ENCIND_SLSK.
 
SCE_SBL_SM_COMM_FID_SM_ENCIND_SLSK.
Line 1,422: Line 1,550:
 
| 0x64 || 0x14 || <code>struct paddr_list_req</code> for inner paddr list. Not used.
 
| 0x64 || 0x14 || <code>struct paddr_list_req</code> for inner paddr list. Not used.
 
|-
 
|-
| 0x78 || Variable (max 0xF88) || outer paddr list / paddr list to paddr list to encrypt
+
| 0x78 || Variable (max 0xF88(0x1F1 entry)) || outer paddr list / paddr list to paddr list to encrypt
 
|}
 
|}
  
Line 1,475: Line 1,603:
 
</pre>
 
</pre>
  
=== 0x60002 sceSblUsSmSnvsEncryptSectors ===
+
=== 0x60002 - sceSblUsSmSnvsEncryptSectors ===
  
 
SCE_SBL_SM_COMM_FID_SM_SNVS_ENC_SECTORS.
 
SCE_SBL_SM_COMM_FID_SM_SNVS_ENC_SECTORS.
  
The input is plain sectors.
+
The input is plain SNVS sectors read from NVS.
  
 
Calculates a XTS Encrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. Appears to be intended for up to 0x3E0 bytes in size, but the size in F00D packet +4 derives the XTS size and memcpy.
 
Calculates a XTS Encrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. Appears to be intended for up to 0x3E0 bytes in size, but the size in F00D packet +4 derives the XTS size and memcpy.
  
The result is XTS encrypted sectors.
+
The result is XTS encrypted SNVS sectors.
  
 
Data size is 8 bytes + sectors size.
 
Data size is 8 bytes + sectors size.
Line 1,489: Line 1,617:
 
<source lang="C">
 
<source lang="C">
 
typedef struct data { // size is variable, at least 0x28 bytes
 
typedef struct data { // size is variable, at least 0x28 bytes
   int sectors_index; // input
+
   int sectors_index; // input: between 1 and 20 (SNVS sectors)
 
   int sectors_count; // input
 
   int sectors_count; // input
 
   char sectors[0x20 * sectors_count]; // input: read from NVS.
 
   char sectors[0x20 * sectors_count]; // input: read from NVS.
Line 1,495: Line 1,623:
 
</source>
 
</source>
  
=== 0x70002 sceSblUsSmSnvsDecryptSectors ===
+
=== 0x70002 - sceSblUsSmSnvsDecryptSectors ===
  
 
SCE_SBL_SM_COMM_FID_SM_SNVS_DEC_SECTORS.
 
SCE_SBL_SM_COMM_FID_SM_SNVS_DEC_SECTORS.
Line 1,509: Line 1,637:
 
<source lang="C">
 
<source lang="C">
 
typedef struct data { // size is variable, at least 0x28 bytes
 
typedef struct data { // size is variable, at least 0x28 bytes
   int sectors_index; // input
+
   int sectors_index; // input: between 1 and 20 (SNVS sectors)
 
   int sectors_count; // input
 
   int sectors_count; // input
 
   char sectors[0x20 * sectors_count]; // input: read from NVS.
 
   char sectors[0x20 * sectors_count]; // input: read from NVS.
Line 1,515: Line 1,643:
 
</source>
 
</source>
  
=== 0x80002 sceSblUsSmSnvsEncryptMgmtData ===
+
=== 0x80002 - sceSblUsSmSnvsEncryptMgmtData ===
  
 
SCE_SBL_SM_COMM_FID_SM_SNVS_ENC_MGMT.
 
SCE_SBL_SM_COMM_FID_SM_SNVS_ENC_MGMT.
  
The input are the new status and flags, and the current mgmt_data read from NVS at offset 0.
+
The input are the new status and flags, and the current Mgmt Data sector read from NVS at offset 0.
  
 
Calculates a XTS Decrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. It then calculates an HMAC using the keyring 0x504 to check the block passed in. If ok, then it uses the seed 0xACA9B1AC to recalculate the block, generate a new hmac, and xts encrypt the block.
 
Calculates a XTS Decrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. It then calculates an HMAC using the keyring 0x504 to check the block passed in. If ok, then it uses the seed 0xACA9B1AC to recalculate the block, generate a new hmac, and xts encrypt the block.
  
The result is a new mgmt_data, which is to be written to NVS at offset 0.
+
The result is a new Mgmt Data sector, which is to be written to NVS at offset 0.
  
 
Data size is 0x28 bytes.
 
Data size is 0x28 bytes.
Line 1,531: Line 1,659:
 
   int status; // input
 
   int status; // input
 
   char flags[4]; // input
 
   char flags[4]; // input
   char mgmt_data[0x20]; // input: read from NVS at offset 0. Likely to be 0x10 bytes of data followed by 0x10 bytes of HMAC.
+
   char sector[0x20]; // input: read from NVS at offset 0. Likely to be 0x10 bytes of data followed by 0x10 bytes of HMAC.
 
} data;
 
} data;
 
</source>
 
</source>
  
=== 0x90002 sceSblUsSmSnvsDecryptMgmtData ===
+
=== 0x90002 - sceSblUsSmSnvsDecryptMgmtData ===
  
 
SCE_SBL_SM_COMM_FID_SM_SNVS_DEC_MGMT.
 
SCE_SBL_SM_COMM_FID_SM_SNVS_DEC_MGMT.
  
The input is the current mgmt_data read from NVS at offset 0.
+
The input is the current Mgmt Data sector read from NVS at offset 0.
  
 
Calculates a XTS Decrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. It then calculates an HMAC using the keyring 0x504 to check the block passed in.
 
Calculates a XTS Decrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. It then calculates an HMAC using the keyring 0x504 to check the block passed in.
Line 1,551: Line 1,679:
 
   int status; // output
 
   int status; // output
 
   char flags[4]; // output
 
   char flags[4]; // output
   char mgmt_data[0x20]; // input: read from NVS at offset 0. Likely to be 0x10 bytes of data followed by 0x10 bytes of HMAC.
+
   char sector[0x20]; // input: read from NVS at offset 0. Likely to be 0x10 bytes of data followed by 0x10 bytes of HMAC.
 
} data;
 
} data;
 
</source>
 
</source>
Line 1,571: Line 1,699:
 
</source>
 
</source>
  
=== 0xA0002 sceSblUsSmAuthAdditionalSign ===
+
=== 0xA0002 - sceSblUsSmAuthAdditionalSign ===
  
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_AS.
 
SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_AS.
Line 1,577: Line 1,705:
 
Verify PUP Additional Signatures.
 
Verify PUP Additional Signatures.
  
=== 0xB0002 ===
+
=== 0xB0002 - sceSblUsSmSnvsEncryptDecryptSector ===
 +
 
 +
Added on FW 1.03. Usage similar to pm_sm command 8.
  
=== 0xC0002 ===
+
Data size is 0x88 bytes.
  
=== 0xD0002 ===
+
<source lang="C">
 +
typedef struct data { // size is 0x88
 +
  uint mode; // 0 before read, 1 after read, 2 before write, 3 after write
 +
  uint sector_index; // between 1 and 20 (SNVS sectors)
 +
  char base_buf[0x20]; // input: full of 0xdeadbeef
 +
  char inter_buf[0x30]; // output: input for nvs_read_special or nvs_write_special
 +
  char final_buf[0x30]; // input: output for nvs_read_special or nvs_write_special
 +
} data;
 +
</source>
 +
 
 +
Usage:
 +
* 1) sceSblSmCommCallFunc(id, 0xB0002, &f00d_resp, data, 0x88);
 +
For read:
 +
* 2) nvs_read_special(data + 0x28, 0x10, data + 0x58, 0x30)
 +
For write:
 +
* 2) nvs_write_special(data + 0x28, 0x30, data + 0x58, 0x10);
 +
* 3) sceSblSmCommCallFunc(id, 0xB0002, &f00d_resp, data, 0x88);
 +
 
 +
=== 0xC0002 - sceSblUsSmSnvsEncryptDecryptMgmtData ===
 +
 
 +
Added on FW 1.03. Usage similar to pm_sm command 8.
  
Syscon update related. Usage is to proxy encrypted data F00D <=> Syscon.
+
Data size is 0x70 bytes.
  
{| class="wikitable"
+
<source lang="C">
|-
+
typedef struct data { // Size is 0x70 bytes on FW 3.60
! Offset !! Size !! Description
+
  int mode; // ex: 0 before read, 1 after read, 2 before write, 3 after write
|-
+
  int sector_count; // always 0 (Mgmt Data)
| 0x40 || 0x4 || 0, 1, 3, or 4
+
  int status; // not set for read, set for write
|-
+
  int flags; // not set for read, set for write
| 0x44 || 0x4 || Unused
+
  char unk_10[0x30]; // output: input for nvs_read_special or nvs_write_special
|-
+
  char unk_40[0x30]; // input: output for nvs_read_special or nvs_write_special
| 0x48 || 0x28 || F00D input, syscon command 0xD2 output
+
} data;
|-
+
</source>
| 0x70 || 0x28 || F00D output, syscon command 0xD2 input
+
 
|-
+
Usage:
|}
+
* 1) sceSblSmCommCallFunc(id, 0xC0002, &f00d_resp, data, 0x70);
 +
For write:
 +
* 2) nvs_write_special(data + 0x10, 0x30, data + 0x40, 0x10);
 +
For read:
 +
* 2) nvs_read_special(data + 0x10, 0x10, data + 0x40, 0x30);
 +
* 3) sceSblSmCommCallFunc(id, 0xC0002, &f00d_resp, data, 0x70);
 +
 
 +
=== 0xD0002 ===
 +
 
 +
Syscon update related. Usage is to proxy encrypted data F00D <=> Syscon.
 +
 
 +
Data size is 0x58 bytes.
 +
 
 +
<source lang="C">
 +
typedef struct data { // Size is 0x58 bytes on FW 3.60
 +
  int mode; // ex: 0, 1, 2, 3, 4
 +
  int unk_4; // Maybe unused
 +
  char unk_8[0x28]; // input: syscon command 0xD2 output
 +
  char unk_30[0x28]; // output: syscon command 0xD2 input
 +
} data;
 +
</source>
 +
 
 +
Usage:
 +
* 1) sceSblSmCommCallFunc(id, 0xD0002, &f00d_resp, data, 0x58);
 +
For modes 0, 1 and 3:
 +
* 2) memcpy(data + 8, data + 0x30, 0x28); SceSysconForDriver_4D03754A(data + 8, 0x28, data + 0x30, 0x28);
 +
* 3) sceSblSmCommCallFunc(id, 0xD0002, &f00d_resp, data, 0x58);
  
 
== utoken_sm.self ==
 
== utoken_sm.self ==
Line 1,635: Line 1,811:
 
== mgkm_sm.self ==
 
== mgkm_sm.self ==
  
MagicGate Key Manager secure module.
+
Magic Gate Key Manager secure module.
These commands seem to be used to set keys (on FW 0.990 and 1.50). There are debug strings referencing these F00D commands as "set_key_command") on [[Dmac5|Dmac5]]. This key seems to be used to do stuff with TripleDES and another unknown encrypt algorithm.
+
 
 +
Present on 0.931-3.73. Commands are almost the same on any FW, only KEY_31 varies.
 +
0
 +
These commands are used to set keys (as seen on FWs from 0.940 to 3.60) to [[Dmac5|DMAC5]] registers in NS memory. These keys are used in to do encryption stuff with AES-ECB and TripleDES-ECB algorithms through [[Dmac5|DMAC5]].
 +
 
 +
On FW 0.940, commands 1 and 2 are only called by SceSblMgKeyMgrForDriver_1C5388D0 which consists of:
 +
<source lang="C">
 +
int SceSblMgKeyMgrForDriver_1C5388D0(void *in, void *out) {
 +
  int ret;
 +
  uint8_t tmp_buffer[16];
 +
  ret = call_cmd_1();
 +
  if ((ret == 0) && (ret = call_cmd_2(), ret == 0)) {
 +
    aesECBDec16B(in, tmp_buffer, 0x1E);
 +
    aesECBEnc16B(tmp_buffer, out, 0x1F);
 +
  }
 +
  return ret;
 +
}
 +
</source>
 +
 
 +
=== 0x1 - set_key_31 ===
 +
 
 +
<source lang="C">
 +
memset(buffer, 0, 0x20);
 +
memcpy(buffer, KEY_31, 0x10);
 +
bigmac_memcpy(0xE04E0000 + 0x1F * 0x20, buffer, 0x20);
 +
</source>
 +
 
 +
=== 0x2 - set_key_30 ===
 +
 
 +
<source lang="C">
 +
memset(buffer, 0, 0x20);
 +
memcpy(buffer, pOpenPsId, 0x10);
 +
memcpy(buffer + 0x10, KEY_30_SEED, 0x10);
 +
bigmac_sha256(buffer, buffer, 0x20);
 +
bigmac_memcpy(0xE04E0000 + 0x1E * 0x20, buffer, 0x20);
 +
</source>
 +
 
 +
=== 0x3 - unset_key_31 ===
 +
 
 +
<source lang="C">
 +
memset(buffer, 0, 0x20);
 +
bigmac_memcpy(0xE04E0000 + 0x1F * 0x20, buffer, 0x20);
 +
</source>
  
=== 0x1 ===
+
=== 0x4 - unset_key_30 ===
  
=== 0x2 ===
+
<source lang="C">
 +
memset(buffer, 0, 0x20);
 +
bigmac_memcpy(0xE04E0000 + 0x1E * 0x20, buffer, 0x20);
 +
</source>
  
  
 
[[Category:Kernel]]
 
[[Category:Kernel]]

Latest revision as of 05:08, 14 June 2020

Depending on the SM that is currently loaded, different commands are handled.

Contents

Request Buffer

Each request that is made sends a page aligned buffer that has a max size of a page. After as 64 byte header common to all commands, the data afterwards is specific to each command. The documentation for each command below specifies the data that goes after the header. The special command id of -1 (0xFFFFFFFF) is used to stop the current loaded SM.

Command buffer structure (as seen on FWs 3.60-3.73):

Offset Size Description
0x0 0x4 Size of the structure (header + data)
0x4 0x4 Command ID
0x8 0x4 Command return value is written here by the SM
0xC 0x4 unk2
0x10 0x30 padding
0x40 variable, chosen by NS Kernel, max=0x1000-0x40 data buffer

On FW 0.931, and maybe in later prototype FWs, the data buffer is located at offset 0x10 instead of 0x40. Thus we can ask why they added the 0x30 bytes padding.

Physical Address Range

A common format used in these requests is a list of physical address and size. This simple structure is defined below. See sceKernelVARangeToPARangeForDriver for information on creating this list.

Offset Size Description
0x0 0x4 Physical Address
0x4 0x4 Size

This data format is used when passing large buffers of data to F00D. This is because the memory manager in kernel could allocate contiguous virtual addresses that corresponds to varying physical addresses.

kprx_auth_sm.self

This is a special SM found in the SLB2 partition. The raw (encrypted) SELF is stored in Secure World memory. It is placed there by an early bootloader.

kprx_auth_sm is used to decrypt SELF and SPSFO files for ARM. The CF header is passed into a page aligned buffer and a PA range is generated from it.

0x10001 - sceSblAuthMgrAuthHeader

Used by sceSblAuthMgrAuthHeaderForKernel.

Checks the SELF header for decryption. The header is copied to the F00D private memory region first (on 1.69 with 0x1000 sized header, it is at 0x00811CC0 in F00D memory space.

Offset Size Description
0x40 0x130 SceSblSmCommContext130
0x170 0x4 Number of paddr list entries for buffer
0x174 0x4 Physical address of paddr list

0x20001 - sceSblAuthMgrSetupAuthSegment

Used by sceSblAuthMgrSetupAuthSegmentForKernel.

Set the program segment to decrypt. This corresponds to the segment index in the ELF program headers in the SELF header passed in with the command above.

Offset Size Description
0x40 0x4 Segment number
0x44 0x4 Return value. 0x1 if not compressed, 0x2 is compressed.
0x48 0x8 Unknown

0x30001 - sceSblAuthMgrLoadBlock

Used by sceSblAuthMgrAuthSegmentForKernel.

Decrypt a buffer from the SELF corresponding to the program segment number passed in above. The segment is read in 0x10000 bytes chunks and is decrypted in place (the input buffer will contain the decrypted data). A paddr list is generated from the buffer. The input buffer and output buffer can be the same.

Offset Size Description
0x40 0x4 Number of entries in input paddr list
0x44 0x4 Physical address of the input paddr list
0x48 0x4 Number of entries in output paddr list
0x4C 0x4 Physical address of the output paddr list

0x40001 - sceSblAuthMgrGetEKc

Decrypts provided buffer in ECB mode using one of three keys (NPDRM keys ?).

Used by sceSblAuthMgrGetEKcForDriver for getting klicensee.

Offset Size Description
0x40 0x100 Data Buffer (under 0x100 bytes)
0x140 0x4 Data Size - must be under 0x100
0x144 0x4 Key ID (0, 1, 2)
0x148 0x4 Set to 0
0x14C 0x4 Set to 0

0x50001 - sceSblAuthMgrSetDmac5Key

Used by sceSblAuthMgrSetDmac5KeyForKernel to set key for decryption.

This uses an unknown secret to derive the final key, then writes it into dmac5 keyring.

Offset Size Description
0x40 0x8-0x10 Key (64/128/196/256 bits)
0x140 0x4 Key size (in bytes)
0x144 0x4 Key ID
0x148 0x4 Slot ID
0x14C 0x4 Key size & 0xF (Should be 0)

0x60001 - sceSblAuthMgrClearDmac5Key

Used by sceSblAuthMgrClearDmac5KeyForKernel for clearing the Dmac5 Key.

This function writes zeroes into dmac5 keyring.

0x70001 - sceSblAuthMgrDecBindDataForDriver

Used by sceSblAuthMgrDecBindDataForDriver and SceNpDrm for gamecard binding data used in conjunction with the RIF license file on the gamecard for deriving the klicensee.

0x80001 - sceSblAuthMgrVerifySpsfo

Used by sceSblAuthMgrVerifySpsfoForDriver.

act_sm.self

0x1 - check_activation_code_1

Removed on FW 2.10.

Verify SceKitActivationData read from sd0:/act.dat.

Uses different keys (AES256CBC and AES256CMAC) than check_activation_code_2.

Used only on TOOL rev 3.

Offset Size Description
0x0 0x80 Input: SceKitActivationData

0x2 - check_activation_code_2

Removed on FW 2.10.

Verify SceKitActivationData read from sd0:VITA.ACT.

Uses different keys (AES256CBC and AES256CMAC) than check_activation_code_1.

Used on any Kit other than TOOL rev 3 (uses command 1), TEST, TOOL rev 4, Manufacturing Mode and QA flagged (bypasses activation).

Offset Size Description
0x0 0x80 Input: SceKitActivationData

0x4 - check_nvs_cmac

Not present on FW 0.931.

Verify NVS activation data authenticity using CMAC.

Offset Size Description
0x0 0x20 Input: SceNVSKitActivationData

0x5 - gen_nvs_cmac

Removed on FW 2.10.

Generate CMAC of NVS activation data. The returned data is written to NVS at offset 0x520 or 0x530.

Offset Size Description
0x0 0x4 Magic "act\0"
0x4 0x4 Issue number
0x8 0x4 Start validity time unix timestamp
0xC 0x4 End validity time unix timestamp
0x10 0x10 Output: CMAC of the 0x10 input bytes

0x7

Removed on FW 2.10.

Check if activation is valid. The input activation data is read from NVS at offset 0x520.

Offset Size Description
0x0 0x10 SceNVSKitActivationData without CMAC
0x10 0x20 SceNVSKitActivationData

0xA - gen_activation_with_sig

Introduced in FW 2.10.

Check if new activation is valid. Extended activation check with a signature. This is ran when installing a new afv.

Offset Size Description
0x0 0x80 Input: SceKitActivationData (new activation data)
0x80 0x100 Input: RSA signature over new activation data
0x180 0x80 Input: SceKitActivationData (previous activation data)
0x200 0x100 Input: RSA signature over previous activation data
0x300 0x20 Output: SceNVSKitActivationData

0xB - check_activation_with_sig

Introduced in FW 2.10.

Check if Kit Activation Data is valid and not expired. Extended activation check with signature. This command is ran on boot.

Offset Size Description
0x0 0x4 Input: Previous return value
0x4 0x4 Input: Current time
0x8 0x4 Output: License Status
0xC 0x4 Output: Expire Date
0x10 0x8 Reserved
0x18 0x20 Input: SceNVSKitActivationData (read from NVS offset 0x520)
0x38 0x80 Input: SceKitActivationData (read from tm0:activate/act.dat)
0xB8 0x100 Input: RSA signature over activation data (read from tm0:activate/actsig.dat)

aimgr_sm.self

0x1 - GetConsoleId

Returns the console's ConsoleId.

Used in sceSblAimgrGetConsoleIdForDriver.

0x2 - GetOpenPsId

Returns the console's OpenPsId.

Used in sceSblAimgrGetOpenPsIdForDriver.

0x3 - GetVisibleId

Returns the console's VisibleId.

Used in sceSblAimgrGetVisibleIdForDriver.

0x4 - GetPsCode

Returns the console's PsCode.

Used in sceSblAimgrGetPscode2ForDriver.

0x5 - CreatePassPhrase

Used in sceSblSsCreatePassPhraseForDriver.

compat_sm.self

Compat SM functions only works on DEX and CEX units, or on units in Manufacturing Mode or with a certain QA Flag. This is why most DevKit units don't have access to PSPEmu.

0x10006 - sceCompatSecLoadSCBootCode

Load Secure CPU Boot Code. PSP main CPU (Tachyon codename) is an Allegrex 32-bit little-endian RISC CPU with FPU and VFPU, 1 ~ 333MHz, MIPS III-based.

Called on init and before resume of PSP.

Offset Size Description
0x40 0x4 Boot/resume cookie. Pass 0 when cold booting, resume_handler ^ magic when resuming
0x44 0x4 Set to 0 (unused)

On FW 3.73 (simplified):

*(u32 *)SceSonyRegbus_e8000004 = 4;
syncm();
memcpy(SceCompatSharedSram_e8100000, g_pre_ipl, 0x1000);  // PRE-IPL
memcpy(SceCompatSharedSram_e8100fc0, g_challenge, 0x40);  // Challenge (IPL XOR key)
memcpy(SceCompatSharedSram_e8100fbc, &cookie, 4);         // Boot/resume cookie
syncm();
*(u32 *)SceSonyRegbus_e8000004 = 0;

If an error occurs during SCBootCode loading:

memset(SceCompatSharedSram_e8100000, 0, 0x1000); // PRE-IPL
syncm();
*(u32 *)SceSonyRegbus_e8000004 = 10;

The cookie, which represents the address where PRE-IPL will jump to when resuming, is passed by MIPS to ARM (written to 0xBFC001FC) just before suspending, and it is calculated the same way as on actual PSP, only that using

u8 data[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0x00, 0xde, 0xf0 };

as input to the SHA1, instead of the MAC address.

0x20006 - sceCompatSecSetSSRAMAcl

Set Shared Static Random Access Memory Access-control list.

Removed since FW 3.50 and replaced by command 0x30006.

Offset Size Description
0x40 0x4 Set to 0
0x44 0x4 Set to 0

0x30006 - sceCompatSecSetSSRAMAcl2

Set Shared Static Random Access Memory Access-control list 2.

Appeared on FW 3.50 as replacement for command 0x20006. This change is related to the huge memory management improvement since FW 3.50. See PSVita System software 3.50 adds 30% more memory for game use.

Offset Size Description
0x40 0x4 Unused

On 3.73-CEX (simplified):

*(u32 *)SceSonyRegbus_e8000004 = 4;
syncm();
ret = memcmp(SceCompatSharedSram_e8100fc0, g_challenge_result, 0x40); // Check challenge output
if (ret == 0) {
    // Success!!
}
syncm();
*(u32 *)SceSonyRegbus_e8000004 = 10;

encdec_w_portability_sm.self

This seems to be used to do some kind of key derivation. May also be used as a general purpose encryption engine.

0x1000A - EncryptWithPortability

Encrypt data. Actually it always returns 0x800F1725, so it does nothing and is never used.

Offset Size Description
0x40 0x4 Key ID (max 0xA)
0x44 0x4 Output Length
0x48 0x20 Output
0x68 0x4 Input Length (max 0x20)
0x6C 0x20 Input
0x8C 0x10 IV

0x2000A - DecryptWithPortability

Used by sceSblSsDecryptWithPortabilityForDriver.

Decrypt data by using AES-256-CBC with an internal key selected by key_id.

Offset Size Description
0x40 0x4 Key ID (1 - 20)
0x44 0x4 Input Length (max 0x20)
0x48 0x20 Input
0x68 0x4 Output Length (must match Input Length)
0x6C 0x20 Output
0x8C 0x10 IV

Return value of 0x800f0002 means invalid service ID. For encdec_w_portability_sm, only commmands 0x1000A and 0x2000A are supported.

Return value of 0x800f1716 means invalid argument such as invalid key ID. Valid key IDs are only 1-20.

gcauthmgr_sm.self

0x1000B

This is one of the variable sized buffers that can be placed inside Request_Buffer.

Response value returned to Kernel comes from Request Buffer at offset 8.

// gc_param is generated by game card and has value 0x01
typedef struct SceSblSmCommGcData { // size is 0x814
	int unk_0; // 1
	int command;
	char data[0x800];
	int key_id;
	int size;
	int unk_810; // 0
} SceSblSmCommGcData;
Offset Size Description
0x40 0x4 Set to 1
0x44 0x4 Command (0x4, 0x7, 0xC etc.)
0x48 0x800 Data Buffer (Input/Output)
0x848 0x4 Key ID (different meaning for different commands. usually used to select one of specific static keys)
0x84C 0x4 Data Buffer Length - Input/Written - Output
0x850 0x4 Set to 0

Following are the supported "KIRK" commands.

0x4 - encrypt_with_portability

Original PSP Kirk 4 service for encrypting data.

Does not use any specific data structure in Data Buffer.

Just encrypts data located in Data Buffer.

Uses one set of keys.

Available Key ID values are (key is encrypted with key from keyslot 0x345 and put into keyslot 0x21): 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x38, 0x39, 0x3A, 0x80, 0x81, 0x82, 0x83.

Special Key ID 0x100 is available. Uses keys from keyslots 0x601 and 0x602.

Key 0x601 is scrambled and used as seed.

Key 0x602 is scrambled and used as key.

seed is aes cbc encrypted with key to produce resulting key.

0x7 - decrypt_with_portability

Original PSP Kirk 7 service for decrypting data.

Does not use any specific data structure in Data Buffer.

Just decrypts data located in Data Buffer.

Uses two sets of keys.

Available key ids are (key is encrypted with key from keyslot 0x345 and put into keyslot 0x21): 0x02, 0x03, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x38, 0x39, 0x3A, 0x80, 0x81, 0x82, 0x83.

Available Key ID values are (key is encrypted with key from keyslot 0x340 and put into keyslot 0x10): 0x44, 0x53, 0x57, 0x63, 0x64, 0x68, 0xC0, 0xC1, 0xC2, 0xC3.

Special Key ID 0x100 is available. Uses keys from keyslots 0x601 and 0x602 (will be documented later).

Key 0x601 is scrambled and used as seed.

Key 0x602 is scrambled and used as key.

seed is aes cbc encrypted with key to produce resulting key.

0xC - ecc160_generate_keys

Original PSP Kirk 0xC service for Generating a 160bit ECC private/public keypair. Call with an empty buffer of length 0x3C. The structure below is the return structure.

Private key dA is obtained by:

1. Generating 0x40 sized random number rng.

2. dA = rng mod N

Public key Qa us obtained by:

Qa = dA * G

Output:

Offset Size Description
0x0 0x14 Private Key
0x14 0x14 Public Key X component
0x28 0x14 Public Key Y component

0xD - ecc160_multiply

Original PSP Kirk 0xD service for multiplying a 160bit ECC curve point with a value. Call with a multiplier, x and y point value.

Input:

Offset Size Description
0x0 0x14 Multiplier Value
0x14 0x14 Point X component
0x28 0x14 Point Y component

Output:

Offset Size Description
0x0 0x14 New Point X component
0x14 0x14 New Point Y component

0xE - ecc160_prngen

Original PSP Kirk 0xE service for 160bit Random number generation. Call with an empty buffer.

Offset Size Description
0x0 0x14 Output: Pseudo Random Number

0x10 - ecc160_sig_gen

Original PSP Kirk 0x10 service for 160bit ECC signing.

Specific nonce is used for signing.

For example if you will implement it with openssl it will be used to calculate precomputed parts of signing operation (kinv and rp).

nonce is obtained by:

1. Generating 0x40 sized random number rng.

2. nonce = rng mod N

Input:

Offset Size Description
0x0 0x20 Encrypted private key
0x20 0x14 SHA1 hash of the content to sign

Output:

Offset Size Description
0x0 0x14 ECC Signature R component
0x14 0x14 ECC Signature S component

0x11 - ecc160_sig_verify

Original PSP Kirk 0x11 service for 160bit ECC signature verification. Call with the below structure, then function will return pass or fail.

Input size is 0x64 bytes.

Input:

Offset Size Description
0x0 0x14 Public Key X component
0x14 0x14 Public Key Y component
0x28 0x14 SHA1 hash of the signed content
0x3C 0x14 ECC Signature R component
0x50 0x14 ECC Signature S component

No output.

0x12 - cert_verify

This function checks that CMAC of Message equals Encrypted CMAC value.

CMAC value of Message is calculated using key from keyslot 0x212.

Encrypted CMAC value is decrypted using a key from keyslot 0x0.

Key in keyslot 0x0 is derived using key from keyslot 0x204 with static seed value.

Input:

Offset Size Description
0x0 0xA8 Message
0xA8 0x10 Encrypted CMAC value

0x14 - ecc224_generate_keys

New Vita Kirk 0x14 service for generating a 224bit ECC private/public keypair. Call with an empty buffer of length 0x54. The structure below is the return structure.

Private key dA is obtained by:

1. Generating 0x40 sized random number rng.

2. dA = rng mod N

Public key Qa us obtained by:

Qa = dA * G

Output:

Offset Size Description
0x0 0x1C Private Key
0x1C 0x1C Public Key X component
0x38 0x1C Public Key Y component

0x15 - ecc224_multiply

New Vita Kirk 0x15 service for multiplying a 224bit ECC curve point with a value. Call with a multiplier, x and y point value.

Input:

Offset Size Description
0x0 0x1C Multiplier Value
0x1C 0x1C Point X component
0x38 0x1C Point Y component

Output:

Offset Size Description
0x0 0x1C New Point X component
0x1C 0x1C New Point Y component

0x16 - ecc224_prngen

New Vita Kirk 0x16 service for 224bit Random number generation. Call with an empty buffer.

Offset Size Description
0x0 0x1C Output: Pseudo Random Number

0x17 - ecc224_sig_gen

New Vita Kirk 0x17 service for 224bit ECC signing.

Specific nonce is used for signing.

For example if you will implement it with openssl it will be used to calculate precomputed parts of signing operation (kinv and rp).

nonce is obtained by:

1. Generating 0x40 sized random number rng.

2. nonce = rng mod N

Input:

Offset Size Description
0x0 0x20 Encrypted private key
0x20 0x1C SHA224 hash of the content you want signed

Output:

Offset Size Description
0x0 0x1C ECC Signature R component
0x1C 0x1C ECC Signature S component

0x18 - ecc224_sig_verify

New Vita Kirk 0x18 service for 224bit ECDSA signature verification. Call with the below structure, then function will return pass or fail.

Input:

Offset Size Description
0x0 0x1C Public Key X component
0x1C 0x1C Public Key Y component
0x38 0x1C SHA224 hash of the content that is signed
0x54 0x1C ECC Signature R component
0x70 0x1C ECC Signature S component

0x19 - cert_verify_new

This function checks that CMAC of Message equals Encrypted CMAC value.

CMAC value of Message is calculated using key from keyslot 0x212.

Encrypted CMAC value is decrypted using a key from keyslot 0x0.

Key in keyslot 0x0 is derived using key from keyslot 0x204 with static seed value.

This function is used to verify PSVita new IdStorage Certificates.

Input:

Offset Size Description
0x0 0xE8 Input: Certificate

0x1B - check_gc_authenticity

New Vita Kirk 0x1B service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data validation service with no response. Size of request is 0x53.

- packet 7 should contain challenge0 for the card that can be encrypted (by card) with key_id and master_key.

- packet 8 should contain encrypted message which can be decrypted (by vita) with key_id and master_key.

- part of message should be card_challenge0.

- another part of the message should be equal to challenge0.

- this way we know that card knows how to properly encrypt.

- Kirk service 1B will decrypt packet 8 with key_id and master_key

- then it will verify challenge0

Offset Size Description
0x00 0x20 cmd56 packet6 chunk
0x20 0x10 cmd56 packet7 chunk
0x30 0x23 cmd56 packet8 chunk

0x1C - generate_vita_authenticity_proof

New Vita Kirk 0x1C service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data generation service. Size of request is 0x40. Size of response is 0x33.

- kirk service 1C will generate packet 9

- it will decrypt packet 8 to retrieve challenge0 and card_challenge0

- then challenge0 and card_challenge0 will be tweaked

- then it will generate secondary_key0

- then packet 9 will be encrypted with key_id and master_key

- packet 9 should contain encrypted message which can be decrypted (by card) with key_id and master_key.

- message should have secondary_key0, tweaked challenge0 and tweaked card_challenge0.

- this way card will know that we know how to properly encrypt the data and we know the layout of the data because we tweak and reorder certain fields.

Request:

Offset Size Description
0x00 0x20 cmd56 packet6 chunk
0x20 0x20 cmd56 packet8 chunk

Response:

Offset Size Description
0x00 0x01 command
0x01 0x01 unknown
0x02 0x01 size
0x03 0x30 packet 9 chunk

0x1D - challenge_handshake

New Vita Kirk 0x1D service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data validation service with no response. Size of request is 0xA3.

- packet 13 should contain challenge1 for the card that can be encrypted (by card) with key_id and master_key.

- packet 14 should contain challenge1 and master_key that are encrypted (by card) with key_id and master_key.

- kirk service 0x1D will decrypt secondary_key0 from packet 9 with key_id and master_key

- then it will decrypt packet 14

- then it will verify challenge1 in packet 13 against decrypted packet 14

- then it will verify master_key in packet 6 against decrypted packet 14

Offset Size Description
0x00 0x20 cmd56 packet6 chunk
0x20 0x30 cmd56 packet9 chunk
0x50 0x10 cmd56 packet13 chunk
0x60 0x43 cmd56 packet14 chunk

0x1E - generate_packets_15_17_with_cmac_signature

New Vita Kirk 0x1E service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data generation service. Size of request is 0x51. Size of response is 0x33.

- kirk service 0x1E will generate packet 15

- it will decrypt secondary_key0 from packet 9 with key_id and master_key

- then it will generate secondary_key1

- then it will create a buffer with tweaked secondary_key1 and tweak_padding

- then it will encrypt the buffer using secondary_key0

- then it will create cmd56 input like buffer with encrypted buffer

- then it will calculate cmac of cmd56 like buffer using secondary_key0

- encrypted buffer and cmac will be the resulting data of packet 15

Request:

Offset Size Description
0x00 0x20 cmd56 packet6 chunk
0x20 0x30 cmd56 packet9 chunk
0x50 0x01 parameter (value 2 or 3)

Response:

Offset Size Description
0x00 0x01 command
0x01 0x01 unknown
0x02 0x01 size
0x03 0x30 packet 15/17 chunk

0x1F - decrypt_packet_16

New Vita Kirk 0x1F service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data validation service. Size of request is 0xB3. Size of response is 0x20.

- kirk service 0x1E will decrypt secondary_key0 from packet 9 with key_id and master_key

- then it will combine data from packet 16 into a cmd56 like buffer

- then it will calculate cmac of that cmd56 like buffer using secondary_key0

- then it will verify calculated cmac against cmac from packet 16

- then it will decrypt secondary_key1 and tweak_padding from packet 15

- then it will decrypt secondary_key1 and unknown data from packet 16

- then it will verify decrypted secondary_key1 from packet 15 against decrypted secondary_key1 from packet 16

- then it will verify that decrypted tweak_padding from packet 15 is properly tweaked

- then it will return unknown decrypted data from packet 16

Request:

Offset Size Description
0x00 0x20 cmd56 packet6 chunk
0x20 0x30 cmd56 packet9 chunk
0x50 0x20 cmd56 packet15 chunk
0x70 0x43 cmd56 packet16 chunk

Response:

Offset Size Description
0x00 0x20 decrypted packet16 chunk

0x20 - get_klicensee_keys_with_rif_cmac_signature

New Vita Kirk 0x20 service. This service is related to SceSdif and is used by SceSblGcAuthMgr. This service is part of SD MMC CMD56 custom initialization protocol. This is a data generation service. Size of request is 0x116. Size of response is 0x34.

Generated data is used to obtain klicensee using sceSblAuthMgrDecBindDataForDriver

Request:

Offset Size Description
0x00 0x20 cmd56 packet6 chunk
0x20 0x30 cmd56 packet9 chunk
0x50 0x20 cmd56 packet17 chunk
0x70 0x43 cmd56 packet18 chunk
0xB3 0x10 cmd56 packet19 chunk
0xC3 0x53 cmd56 packet20 chunk

Response:

Offset Size Description
0x00 0x20 keys that are used to obtain klicensee
0x20 0x14 cmac signature that should be same as rif data at offset 0xE0

0x21 - ecc160_hmac_sha256_sig_gen

New Vita Kirk 0x21 service for 160bit ECC signing.

Specific nonce is used for signing.

For example if you will implement it with openssl it will be used to calculate precomputed parts of signing operation (kinv and rp).

nonce is obtained by:

1. Generating 0x40 sized seed which is derived from message hash and static private key using hmac256 and sha256.

2. nonce = seed mod N

Input:

Offset Size Description
0x0 0x20 unknown, must be zeroes
0x20 0x14 Message hash

Output:

Offset Size Description
0x0 0x14 ECC Signature R component
0x14 0x14 ECC Signature S component

0x22 - ecc224_sceebootpbp_sig_gen

New Vita Kirk 0x22 service for 224bit ECC signing.

Specific nonce is used for signing.

For example if you will implement it with openssl it will be used to calculate precomputed parts of signing operation (kinv and rp).

nonce is obtained by:

1. Generating 0x40 sized seed which is derived from message hash and one of two static private keys using hmac256 and sha256. Key can be selected with key id 0 or 1.

Private key 0 is only used for signing __sceebootpbp files for firmware versions before 1.8X, otherwise private key 1 is used for signing __sceebootpbp.

2. nonce = seed mod N

Input:

Offset Size Description
0x0 0x20 unknown, must be zeroes
0x20 0x1C message hash

Output:

Offset Size Description
0x0 0x1C ECC Signature R component
0x1C 0x1C ECC Signature S component

0x23 - generate_cmac_signature

New Vita Kirk 0x23 service.

It encrypts the plain message with AES128CBC, static key and null IV, then calculates the AES128CMAC of the encrypted message with another static key.

Input:

Offset Size Description
0x0 0x10 Plain message

Output:

Offset Size Description
0x0 0x10 Encrypted message
0x10 0x10 Encrypted message CMAC

pm_sm.self

sceSblPmMgrAuthEtoIForDriver uses "sd0:sm/pm_sm_sd.self" whilst other PmSm functions use "os0:sm/pm_sm.self".

Services 8, 9 and 0xA appeared on FW 1.03 (maybe 1.00). They are not present on FW 0.990 and earlier.

Keyset must be between 0-0xC on FW 0.931.

0x1 - get_product_mode

Used by sceSblPmMgrGetProductModeFromNVS.

Data size is 0x28 bytes.

Input: 0x20 buffer read from NVS at offset 0.

Offset Size Description
0x40 0x4 Output: Product Mode
0x44 0x4 Reserved
0x48 0x20 Input: NVS block read at offset 0

0x2 - set_product_mode

Used by sceSblPmMgrSetProductMode.

Data size is 0x28 bytes.

Input: 0x20 bytes buffer read from NVS at offset 0, to which is written the new product mode to set.

Output data: 0x20 buffer to write to NVS at offset 0.

Offset Size Description
0x40 0x4 Input: Product Mode
0x44 0x4 Reserved
0x48 0x20 Input and output: NVS block read/written at offset 0

0x3 - gen_req_hello

This command gets the Ernie secure packet for the first JIG auth command.

Data size is 0x30 bytes.

Offset Size Description
0x40 0x4 Input: keyset (6, 14)
0x44 0x4 Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
0x48 0x28 Output: Ernie secure packet

0x4 - gen_challenge

Data size is 0x30 bytes.

Offset Size Description
0x40 0x4 Input: keyset (6, 14)
0x44 0x4 Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
0x48 0x28 Input and output: Ernie secure packet

0x5 - check_response

Returns 0 on success.

Data size is 0x30 bytes.

Offset Size Description
0x40 0x4 input: keyset (6, 14)
0x44 0x4 input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when arg1 in [14]; otherwise undefined)
0x48 0x28 input: Ernie secure packet

0x6 - gen_req_result

Encrypts Ernie secure packet for step 4 with the chosen keyset.

Data size is 0x30 bytes.

Offset Size Description
0x40 0x4 Input: keyset (4, 6 on FW 0.931-3.60)
0x44 0x4 Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
0x48 0x28 Input and output: Ernie secure packet

0x7 - check_result

Returns 0 on success.

Data size is 0x30 bytes.

Offset Size Description
0x40 0x4 Input: keyset (4, 6, 14)
0x44 0x4 Input: keyset_rev (1 when keyset in [4, 6, 12]; 2 when keyset in [14]; otherwise undefined)
0x48 0x28 Input: Ernie secure packet

0x8 - run_pm_command

Not present in old FWs.

Used on FW 1.03+ by sceSblPmMgrGetProductModeFromNVS.

Data size is 0x70 bytes.

Offset Size Description
0x40 0x4 Input: Command (0: gen_get_mgmt_data_req, 1: get_mgmt_data, 3: decrypt_response, 4: set_product_mode, 5: set_product_mode_off, 7: set_sd_mode_off)
0x44 0x4 Reserved
0x48 0x4 Input and output: product mode
0x4C 0x4 Input and output: unknown Mgmt Data
0x50 0x30 Input and output: Ernie secure packet for setting Product Mode
0x80 0x30 Input and output: Ernie secure packet for getting Product mode

0x9 - gen_jig_message

Only on FW 1.03+.

Data size is 0x10C bytes.

Offset Size Description
0x40 0x4 Input: keyset_flag (0x48 for keyset 4, 0x49 for keyset 12)
0x44 0x4 Reserved
0x48 0x104 Output: jig_message

0xA - check_jig_response

Only on FW 1.03+.

Returns 0 on success.

Data size is 0x10C bytes.

Offset Size Description
0x40 0x4 Input: keyset_flag (0x48 for keyset 4, 0x49 for keyset 12)
0x44 0x4 Reserved
0x48 0x104 Input: jig_response

qaf_sm.self

0x0

Decrypt or check QAF Token. Used on 1.03 PDEL.

0x1

0x2

0x3

0x4 - decrypt QAF version

Input: 0x20 buffer read from NVS offset 0x2A0.

Output: QAF version in this buffer of size 0x20:

Offset Size Description
0x0 0x4 unk
0x4 0x4 QAF version
0x8 0x18 unk

0x5 - encrypt QAF version

Input QAF version in this buffer of size 0x20:

Offset Size Description
0x0 0x4 unk
0x4 0x4 QAF version
0x8 0x18 unk

Output of size 0x20 is then written to NVS offset 0x2A0.

0x6 - check_flag (decrypt)

Input: 0x20 buffer read from NVS at offset 0.

Returns error if flag is bad, 0 on success.

Output

0x7 - set_flag (encrypt)

Input: 0x20 buffer.

Output: 0x20 encrypted buffer that can be written to NVS at offset 0.

0xC

0xD

rmauth_sm.self

Removable Media (Memory Card) authentication. Used by SceMsif.

0x1 - get_key_master_gen_no

Response (size 0x20 bytes):

Offset Size Description
0x40 0x10 unknown
0x50 0x4 Returned ID?
0x54 0xC unknown

0x2 - set_index_key

Scrambles and sets the DMAC5 keyslot 0x1C key. The scrambling process consists of encrypting the first and second halves of the key seed with a private internal (could be considered as a couple of 0x10 keys) rmmauth_sm key using AES128-CBC.

Request (size 0x20 bytes):

Offset Size Description
0x00 0x20 Key seed

0x3

?clear_index_key?

Clears the DMAC5 keyslot 0x1C key (to 0).

spkg_verifier_sm_w_key_2.self

This is an extension of update_service_sm.self. It was added to support command 0xE0002.

0xE0002 - sceSblUsSmAuthSpkgWithKey2

Used to decrypt downloaded lists (SPKGs). Same format as 0x40002.

Lists URLS:

.list_0_version:0000000125.list_0_url:http://vitacl.ww.dl.playstation.net/vitacl/ww/j/list_launch_vita.dat
.list_1_version:0000000111.list_1_url:http://vitacl.ww.dl.playstation.net/vitacl/ww/j/list_launch_emu.dat
.list_2_version:0000000001.list_2_url:http://vitacl.ww.dl.playstation.net/vitacl/ww/j/list_launch_teleport.dat

update_service_sm.self

This is used by SceSblUpdateMgr to decrypt update packages extracted from PUP files. Both 0x40002 and 0x50002 reference buffers in the following way: an inner paddr list is generated for the buffer containing the data to encrypt/decrypt, then an outer paddr list is generated for the inner list. That means there's two levels of indirection in the paddr list.

0x10002 - sceSblUsSmAuthPupHeader

SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_HEADER.

Verify PUP header.

Input data size: 0xFF0.

Input: PA vector of the PUP header including the PUP Hash (size: 0x80 + segment_num * 0x60 + 0x20)

0x20002 - sceSblUsSmAuthPupSegment

SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_SEGMENT.

Verify PUP segment.

Input data size: 0xFF0.

0x30002 - sceSblUsSmAuthPupWatermark

SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_WM.

Verify PUP watermark.

Input data size: 0xFF0.

Input data: a packet embedding at least two paddr (or PA vectors): PUP Watermark (0x1000 bytes) and PUP Hash (0x20 bytes).

0x40002 - sceSblUsSmAuthSpkg

SCE_SBL_SM_COMM_FID_SM_AUTH_SPKG.

Decrypt a SPKG. Allocate a page aligned buffer and read the complete SPKG file into the buffer. The buffer is decrypted in place.

Offset Size Description
0x40 0x8 Set to 0x0
0x48 0x8 Set to 0x1
0x50 0x14 struct paddr_list_req for Paddr list below
0x64 0x14 struct paddr_list_req for pkg buffer
0x78 Variable (max 0xF88(0x1F1 entry)) Copy of paddr list for pkg buffer (contents described at 0x50)

0x50002 - sceSblUsSmEncryptIndividualSLSK

SCE_SBL_SM_COMM_FID_SM_ENCIND_SLSK.

Re-encrypt individual SLSK files (.enp files).

Offset Size Description
0x40 0x8 Unknown/Zero
0x48 0x8 Set to 1
0x50 0x14 struct paddr_list_req for paddr list copied to 0x78. Only count field is used.
0x64 0x14 struct paddr_list_req for inner paddr list. Not used.
0x78 Variable (max 0xF88(0x1F1 entry)) outer paddr list / paddr list to paddr list to encrypt

Each inner paddr list is first copied to temporary f00d memory, then they all are checked for validity at once. Maximum size of inner list is 0xff7 (so probably 0xff7 / 8 * 8 = 0xff0). Any lengths higher than that result in SCE_SBL_ERROR_SL_ENOMEM = 0x800f020c.

How it works:

  • first, all inner entries are checked for validity, if something's invalid, bail out SCE_SBL_ERROR_SL_EINVAL 0x800f0216
  • start at last outer entry and move towards the first
  • if current entry looks valid (length >= 8), proceed to inner paddr encryption
  • if no valid entries found, error=SCE_SBL_ERROR_SL_EINVAL 0x800f0216
  • if multiple valid entries found, error=SCE_SBL_ERROR_SL_EIO 0x800f0205 (???) (but the first one found is always encrypted)
  • if only one valid entry is found, return success

Bugs(?):

  • encrypting same paddr twice or more times within a single inner paddr list always results in same output, no matter what input was, reproducible with length=0x10 or less
  • sum(inner list sizes) must be <= 0xFF0, but there's no overflow check, a large inner list causes f00d to overwrite memory with data like:
00:00:26	0 // this is paddr 0x1F000000
00:00:26	0
00:00:26	0
00:00:26	2000
00:00:26	8
00:00:26	812d40
00:00:26	0
00:00:26	1f000020 // this is paddr 0x1F00001C
00:00:26	0
00:00:26	0
00:00:26	0
00:00:26	2000
00:00:26	8
00:00:26	812d40
00:00:26	0
00:00:26	1f000040
00:00:26	0
00:00:26	0
00:00:26	0
00:00:26	2000
00:00:26	8
00:00:26	812d40
00:00:26	0
00:00:26	1f000060
00:00:26	0
00:00:26	0
00:00:26	0
00:00:26	2000
00:00:26	8
00:00:26	812d40
00:00:26	0
00:00:26	1f000080

0x60002 - sceSblUsSmSnvsEncryptSectors

SCE_SBL_SM_COMM_FID_SM_SNVS_ENC_SECTORS.

The input is plain SNVS sectors read from NVS.

Calculates a XTS Encrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. Appears to be intended for up to 0x3E0 bytes in size, but the size in F00D packet +4 derives the XTS size and memcpy.

The result is XTS encrypted SNVS sectors.

Data size is 8 bytes + sectors size.

typedef struct data { // size is variable, at least 0x28 bytes
  int sectors_index; // input: between 1 and 20 (SNVS sectors)
  int sectors_count; // input
  char sectors[0x20 * sectors_count]; // input: read from NVS.
} data;

0x70002 - sceSblUsSmSnvsDecryptSectors

SCE_SBL_SM_COMM_FID_SM_SNVS_DEC_SECTORS.

The input is XTS encrypted sectors.

Calculates a XTS Decrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. Appears to be intended for up to 0x3E0 in size, but the size in F00D packet +4 derives the XTS size and memcpy.

The result is plain sectors.

Data size is 8 bytes + sectors size.

typedef struct data { // size is variable, at least 0x28 bytes
  int sectors_index; // input: between 1 and 20 (SNVS sectors)
  int sectors_count; // input
  char sectors[0x20 * sectors_count]; // input: read from NVS.
} data;

0x80002 - sceSblUsSmSnvsEncryptMgmtData

SCE_SBL_SM_COMM_FID_SM_SNVS_ENC_MGMT.

The input are the new status and flags, and the current Mgmt Data sector read from NVS at offset 0.

Calculates a XTS Decrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. It then calculates an HMAC using the keyring 0x504 to check the block passed in. If ok, then it uses the seed 0xACA9B1AC to recalculate the block, generate a new hmac, and xts encrypt the block.

The result is a new Mgmt Data sector, which is to be written to NVS at offset 0.

Data size is 0x28 bytes.

typedef struct data { // size is 0x28 bytes
  int status; // input
  char flags[4]; // input
  char sector[0x20]; // input: read from NVS at offset 0. Likely to be 0x10 bytes of data followed by 0x10 bytes of HMAC.
} data;

0x90002 - sceSblUsSmSnvsDecryptMgmtData

SCE_SBL_SM_COMM_FID_SM_SNVS_DEC_MGMT.

The input is the current Mgmt Data sector read from NVS at offset 0.

Calculates a XTS Decrypt using the per console keys in keyring slot 0x502, and 0x503 for the tweak and decryption keys. It then calculates an HMAC using the keyring 0x504 to check the block passed in.

The result is the current status and flags.

Data size is 0x28 bytes.

typedef struct data { // size is 0x28 bytes
  int status; // output
  char flags[4]; // output
  char sector[0x20]; // input: read from NVS at offset 0. Likely to be 0x10 bytes of data followed by 0x10 bytes of HMAC.
} data;
// SCE_SBL_SS_SNVS_FLAGS
#define SCE_SBL_SS_SNVS_UPDATER_FLAG_INDEX 0

If flags[SCE_SBL_SS_SNVS_UPDATER_FLAG_INDEX] is not set, updater init is skipped:

if (((byte)flags & 1) == 0)
        sceKernelPrintfLevelForDriver(2, "skip init for updater\n");
      else {
        sceKernelPrintfLevelForDriver(2, "do init for updater\n");
        if (SpkgInfoUtilInitForUpdater(&status, &flags) != 0)
          sceKernelPrintfLevelForDriver(2,"SpkgInfoUtilInitForUpdater() failure = 0x%x\n",iVar2);
      }

0xA0002 - sceSblUsSmAuthAdditionalSign

SCE_SBL_SM_COMM_FID_SM_AUTH_PUP_AS.

Verify PUP Additional Signatures.

0xB0002 - sceSblUsSmSnvsEncryptDecryptSector

Added on FW 1.03. Usage similar to pm_sm command 8.

Data size is 0x88 bytes.

typedef struct data { // size is 0x88
  uint mode; // 0 before read, 1 after read, 2 before write, 3 after write
  uint sector_index; // between 1 and 20 (SNVS sectors)
  char base_buf[0x20]; // input: full of 0xdeadbeef
  char inter_buf[0x30]; // output: input for nvs_read_special or nvs_write_special
  char final_buf[0x30]; // input: output for nvs_read_special or nvs_write_special
} data;

Usage:

  • 1) sceSblSmCommCallFunc(id, 0xB0002, &f00d_resp, data, 0x88);

For read:

  • 2) nvs_read_special(data + 0x28, 0x10, data + 0x58, 0x30)

For write:

  • 2) nvs_write_special(data + 0x28, 0x30, data + 0x58, 0x10);
  • 3) sceSblSmCommCallFunc(id, 0xB0002, &f00d_resp, data, 0x88);

0xC0002 - sceSblUsSmSnvsEncryptDecryptMgmtData

Added on FW 1.03. Usage similar to pm_sm command 8.

Data size is 0x70 bytes.

typedef struct data { // Size is 0x70 bytes on FW 3.60
  int mode; // ex: 0 before read, 1 after read, 2 before write, 3 after write
  int sector_count; // always 0 (Mgmt Data)
  int status; // not set for read, set for write
  int flags; // not set for read, set for write
  char unk_10[0x30]; // output: input for nvs_read_special or nvs_write_special
  char unk_40[0x30]; // input: output for nvs_read_special or nvs_write_special
} data;

Usage:

  • 1) sceSblSmCommCallFunc(id, 0xC0002, &f00d_resp, data, 0x70);

For write:

  • 2) nvs_write_special(data + 0x10, 0x30, data + 0x40, 0x10);

For read:

  • 2) nvs_read_special(data + 0x10, 0x10, data + 0x40, 0x30);
  • 3) sceSblSmCommCallFunc(id, 0xC0002, &f00d_resp, data, 0x70);

0xD0002

Syscon update related. Usage is to proxy encrypted data F00D <=> Syscon.

Data size is 0x58 bytes.

typedef struct data { // Size is 0x58 bytes on FW 3.60
  int mode; // ex: 0, 1, 2, 3, 4
  int unk_4; // Maybe unused
  char unk_8[0x28]; // input: syscon command 0xD2 output
  char unk_30[0x28]; // output: syscon command 0xD2 input
} data;

Usage:

  • 1) sceSblSmCommCallFunc(id, 0xD0002, &f00d_resp, data, 0x58);

For modes 0, 1 and 3:

  • 2) memcpy(data + 8, data + 0x30, 0x28); SceSysconForDriver_4D03754A(data + 8, 0x28, data + 0x30, 0x28);
  • 3) sceSblSmCommCallFunc(id, 0xD0002, &f00d_resp, data, 0x58);

utoken_sm.self

0x1 - verify_utoken

Verify SceUtoken buffer.

Offset Size Description
0x40 0x4 Paddr of SceUtoken buffer
0x44 0x4 Size of SceUtoken buffer (usually 0x800)
0x48 0x4 Time (got using sceRtcGetCurrentSecureTickForDriver or 0xFFFFFFFF (-1)
0x4C 0x10 OpenPsId

0x2 - decrypt utoken

Decrypt SceUtoken buffer, in order to get UT Flags.

Offset Size Description
0x40 0x4 Paddr of SceUtoken buffer
0x44 0x4 Size of SceUtoken buffer (usually 0x800)
0x48 0x4 Time (got using sceRtcGetCurrentSecureTickForDriver or 0xFFFFFFFF (-1))
0x4C 0x10 OpenPsId

mgkm_sm.self

Magic Gate Key Manager secure module.

Present on 0.931-3.73. Commands are almost the same on any FW, only KEY_31 varies. 0 These commands are used to set keys (as seen on FWs from 0.940 to 3.60) to DMAC5 registers in NS memory. These keys are used in to do encryption stuff with AES-ECB and TripleDES-ECB algorithms through DMAC5.

On FW 0.940, commands 1 and 2 are only called by SceSblMgKeyMgrForDriver_1C5388D0 which consists of:

int SceSblMgKeyMgrForDriver_1C5388D0(void *in, void *out) {
  int ret;
  uint8_t tmp_buffer[16];
  ret = call_cmd_1();
  if ((ret == 0) && (ret = call_cmd_2(), ret == 0)) {
    aesECBDec16B(in, tmp_buffer, 0x1E);
    aesECBEnc16B(tmp_buffer, out, 0x1F);
  }
  return ret;
}

0x1 - set_key_31

memset(buffer, 0, 0x20);
memcpy(buffer, KEY_31, 0x10);
bigmac_memcpy(0xE04E0000 + 0x1F * 0x20, buffer, 0x20);

0x2 - set_key_30

memset(buffer, 0, 0x20);
memcpy(buffer, pOpenPsId, 0x10);
memcpy(buffer + 0x10, KEY_30_SEED, 0x10);
bigmac_sha256(buffer, buffer, 0x20);
bigmac_memcpy(0xE04E0000 + 0x1E * 0x20, buffer, 0x20);

0x3 - unset_key_31

memset(buffer, 0, 0x20);
bigmac_memcpy(0xE04E0000 + 0x1F * 0x20, buffer, 0x20);

0x4 - unset_key_30

memset(buffer, 0, 0x20);
bigmac_memcpy(0xE04E0000 + 0x1E * 0x20, buffer, 0x20);