Secure Modules Functions
Depending on the F00D SELF that is currently loaded, different commands are handled.
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 shut down the currently loaded F00D SELF.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Size of buffer |
0x4 | 0x4 | Command ID |
0x8 | 0x4 | Return value (output) |
0xC | 0x34 | Unknown/Unused |
0x40 | Variable (max 0xFC0) | Command specific buffer |
Physical Address List
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 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 paddr list is generated from it.
0x10001 sceSblAuthMgrAuthHeaderForKernel
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 sceSblAuthMgrLoadSegmentForKernel
Used by sceSblAuthMgrLoadSegmentForKernel.
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 sceSblAuthMgrLoadBlockForKernel
Used by sceSblAuthMgrLoadBlockForKernel.
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 sceSblAuthMgrGetEKcForDriver
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 sceSblAuthMgrSetDmac5KeyForKernel
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 sceSblAuthMgrClearDmac5KeyForKernel
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 sceSblAuthMgrVerifySpsfoForDriver
Used by sceSblAuthMgrVerifySpsfoForDriver.
act_sm.self
0x1 check_activation_code_1
Only on pre 2.10.
Verify SceKitActivationData derived from AFV.
Use "internal" keys (?internal kits maybe? Not used on PDEL kernel).
Offset | Size | Description |
---|---|---|
0x40 | 0x80 | SceKitActivationData |
0x2 check_activation_code_2
Only on pre 2.10.
Verify SceKitActivationData derived from AFV.
Use PDEL/PTEL keys. (maybe also latest DEM)
Offset | Size | Description |
---|---|---|
0x40 | 0x80 | SceKitActivationData |
0x4 check_cmac
Verify ?NVS? activation data. Maybe checks CMAC.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Magic "act\0" |
0x44 | 0x4 | Issue number |
0x48 | 0x4 | Start validity time unix timestamp |
0x4C | 0x4 | End validity time unix timestamp |
0x50 | 0x10 | Unknown. Maybe CMAC. |
0x5 gen_act_cmac
Only on pre 2.10.
Get activation data. The returned data is written to NVS at offset 0x520 or 0x530.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Magic "act\0" |
0x44 | 0x4 | Issue number |
0x48 | 0x4 | Start validity time unix timestamp |
0x4C | 0x4 | End validity time unix timestamp |
0x50 | 0x10 | Unknown (returned data) ?CMAC? |
0x7
Only on pre 2.10.
Check if activation is valid. The input activation data is read from NVS at offset 0x520.
Offset | Size | Description |
---|---|---|
0x40 | 0x10 | SceKitNVSActivationData without CMAC |
0x50 | 0x20 | SceKitNVSActivationData |
0xA gen_activation_with_sig
Introduced in 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 |
---|---|---|
0x40 | 0x80 | SceKitActivationData (new activation data) |
0xC0 | 0x100 | RSA signature over new activation data |
0x1C0 | 0x80 | SceKitActivationData (previous activation data) |
0x240 | 0x100 | RSA signature over previous activation data |
0x340 | 0x20 | Output: SceKitNVSActivationData (same as command 0x4) |
0xB check_activation_with_sig
Introduced in 2.10.
Check if current activation is valid. Extended activation check with signature. This is ran on boot.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Unknown |
0x44 | 0x4 | Current time |
0x48 | 0x8 | Some return value |
0x50 | 0x8 | Unknown |
0x58 | 0x20 | SceKitNVSActivationData (same as command 0x4) |
0x78 | 0x80 | AFV data |
0xF8 | 0x100 | RSA signature over activation data |
aimgr_sm.self
0x1 ConsoleId
Returns the console's ConsoleId.
Used in sceSblSsGetConsoleIdForDriver.
0x2 OpenPsId
Returns the console's OpenPsId.
Used in sceSblSsGetOpenPsIdForDriver.
0x3 VisibleId/FuseId
Returns the console's VisibleId.
Used in sceSblSsGetVisibleIdForDriver.
0x4 PsCode
Returns the console's PsCode.
Used in sceSblSsGetPscode2ForDriver.
0x5 PassPhrase
Used in sceSblSsCreatePassPhraseForDriver.
compat_sm.self
0x10006
Seems to be called on init and before resume of PSP
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Unknown |
0x44 | 0x4 | Set to 0 |
0x20006
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Set to 0 |
0x44 | 0x4 | Set to 0 |
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
Encrypt data? Actually it always returns 0x800F1725
, so it does nothing.
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 of 0x800f0002 means invalid service ID. For encdec_w_portability_sm, only 0x1000A and 0x2000A are supported.
Return of 0x800f1716 means invalid argument such as invalid key ID. Valid key IDs are only 1-20.
gcauthmgr_sm.self
0x1000B
check sm_comm_context
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Set to 1 |
0x44 | 0x4 | GC Command |
0x48 | 0x800 | GC Buffer (Input/Output) |
0x848 | 0x4 | Unknown GC param |
0x84C | 0x4 | GC Buffer Length/Written |
0x850 | 0x4 | Set to 0 |
Supported GC commands and structures
0x4
Original PSP Kirk 4 service for encrypting data
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Set to 5 |
0x4 | 0x4 | 0 |
0x8 | 0x4 | 0 |
0xC | 0x4 | Key Slot (1-0x7F not all available) |
0x10 | 0x4 | Data Length |
0x14 | 0x7EC | Data to encrypt |
0x7
Original PSP Kirk 7 service for decrypting data
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Set to 4 |
0x4 | 0x4 | 0 |
0x8 | 0x4 | 0 |
0xC | 0x4 | Key Slot (1-0x7F not all available) |
0x10 | 0x4 | Data Length |
0x14 | 0x7EC | Data to encrypt |
0xC
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.
Offset | Size | Description |
---|---|---|
0x0 | 0x14 | Private Key |
0x14 | 0x14 | Public Key X component |
0x28 | 0x14 | Public Key Y component |
0xD
Original PSP Kirk 0xD service for multiplying a 160bit ECC curve point with a value. Call with a multiplier, then a x and y point value.
Offset | Size | Description |
---|---|---|
0x0 | 0x14 | Multiplier Value |
0x14 | 0x14 | Point X component |
0x28 | 0x14 | Point Y component |
Result
Offset | Size | Description |
---|---|---|
0x0 | 0x14 | New Point X component |
0x14 | 0x14 | New Point Y component |
0xE
Original PSP Kirk 0xE service for 160bit Random number generation. Call with an empty buffer, the result structure is below.
Offset | Size | Description |
---|---|---|
0x0 | 0x14 | Cryptographic Random Number |
0x10
Original PSP Kirk 0x10 service for 160bit ECC signing. Call and return structure below.
Offset | Size | Description |
---|---|---|
0x0 | 0x20 | Encrypted private key (see kirk-engine implementation for fuse_id process for encryption) |
0x20 | 0x14 | SHA1 hash of the content you want signed |
Result
Offset | Size | Description |
---|---|---|
0x0 | 0x14 | ECC Signature R component |
0x14 | 0x14 | ECC Signature S component |
0x11
Original PSP Kirk 0x11 service for 160bit ECC signature verification. Call with the below structure, then function will return pass or fail.
Offset | Size | Description |
---|---|---|
0x0 | 0x14 | Public Key X component |
0x14 | 0x14 | Public Key Y component |
0x28 | 0x14 | SHA1 hash of the content that is signed |
0x3C | 0x14 | ECC Signature R component |
0x50 | 0x14 | ECC Signature S component |
Result
Offset | Size | Description |
---|---|---|
0x0 | 0x14 | ECC Signature R component |
0x14 | 0x14 | ECC Signature S component |
0x14
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.
Offset | Size | Description |
---|---|---|
0x0 | 0x1C | Private Key |
0x1C | 0x1C | Public Key X component |
0x38 | 0x1C | Public Key Y component |
0x15
New Vita Kirk 0x15 service for multiplying a 224bit ECC curve point with a value. Call with a multiplier, then a x and y point value.
Offset | Size | Description |
---|---|---|
0x0 | 0x1C | Multiplier Value |
0x1C | 0x1C | Point X component |
0x38 | 0x1C | Point Y component |
Result
Offset | Size | Description |
---|---|---|
0x0 | 0x1C | New Point X component |
0x1C | 0x1C | New Point Y component |
0x16
New Vita Kirk 0x16 service for 224bit Random number generation. Call with an empty buffer, the result structure is below.
Offset | Size | Description |
---|---|---|
0x0 | 0x1C | Cryptographic Random Number |
0x17
New Vita Kirk 0x17 service. Unknown, but buffer length is 0x3C. Almost certainly a 224bit version of 0x10
0x18
New Vita Kirk 0x18 service. Unknown, but buffer length is 0x8C. Almost certainly a 224bit version of 0x11
0x19
New Vita Kirk 0x19 service. Unknown, but buffer length is 0xE8. Related to IdStorage somehow. Almost certainly a 224bit version of 0x12
0x1B
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.
Offset | Size | Description |
---|---|---|
0x00 | 0x20 | cmd56 packet6 chunk |
0x20 | 0x10 | cmd56 packet7 chunk |
0x30 | 0x23 | cmd56 packet8 chunk |
0x1C
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.
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 | data |
0x1D
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.
Offset | Size | Description |
---|---|---|
0x00 | 0x20 | cmd56 packet6 chunk |
0x20 | 0x30 | cmd56 packet9 chunk |
0x50 | 0x10 | cmd56 packet13 chunk |
0x60 | 0x43 | cmd56 packet14 chunk |
0x1E
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.
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 | data |
0x1F
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.
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 | unknown |
0x20
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 sceSblAuthMgrDecBindData
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 | some signature that should be same as rif data at offset 0xE0 |
0x21
New Vita Kirk 0x21 service. Unknown, but buffer length is 0x34.
0x22
New Vita Kirk 0x22 service. Unknown, but buffer length is 0x3C.
0x23
New Vita Kirk 0x23 service. Unknown, but buffer length is 0x20.
pm_sm.self
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.
0x1 get_product_mode
Used by sceSblPmMgrGetProductModeFromNVS.
Data size is 0x28 bytes. (0x20 bytes used)
Input: 0x20 buffer read from NVS at offset 0.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Output: product mode |
0x44 | 0x4 | zeroed |
0x48 | 0x20 | input only: NVS data read at offset 0 |
0x2 set_product_mode
Used by sceSblPmMgrSetProductMode.
Data size is 0x28 bytes. (0x20 bytes used)
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 | new product mode |
0x44 | 0x1C | output only |
0x3 gen_req_hello
Input: 0x30 bytes buffer.
This is the first JIG auth command. The 0x28 buffer content is for the first time set by this service.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | arg1 (6 or 14) |
0x44 | 0x4 | arg2 (1 when arg1 in [4, 6, 12]; 2 when arg in [14]; otherwise undefined) |
0x48 | 0x28 | output only |
0x4 gen_challenge
Input: 0x30 bytes buffer.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | arg1 (6 or 14) |
0x44 | 0x4 | arg2 (1 when arg1 in [4, 6, 12]; 2 when arg in [14]; otherwise undefined) |
0x48 | 0x28 | input and output |
0x5 check_response
Input: 0x30 bytes buffer.
Returns 0 on success, doesn't modify the input buffer.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | arg1 (6 or 14) |
0x44 | 0x4 | arg2 (1 when arg1 in [4, 6, 12]; 2 when arg in [14]; otherwise undefined) |
0x48 | 0x28 | input only |
0x6 gen_req_result
Input: 0x30 bytes buffer.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | arg1 (6 or 14) |
0x44 | 0x4 | arg2 (1 when arg1 in [4, 6, 12]; 2 when arg in [14]; otherwise undefined) |
0x48 | 0x28 | input and output |
0x7 check_result
Input: 0x30 bytes buffer.
Returns 0 on success, doesn't modify the input buffer.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | arg1 (6 or 14) |
0x44 | 0x4 | arg2 (1 when arg1 in [4, 6, 12]; 2 when arg in [14]; otherwise undefined) |
0x48 | 0x28 | input only |
0x8
Used on 1.03+ by sceSblPmMgrGetProductModeFromNVS.
Input: 0x70 bytes buffer.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | new product mode |
0x44 | 0x4 | 0 |
0x48 | 0x4 | out1: current product mode |
0x4C | 0x4 | out2 |
0x50 | 0x60 | unk |
0x9 gen_jig_message
Only on 1.03+.
Input: 0x10C bytes buffer.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | arg1: flag. |
0x44 | 0x4 | arg2 |
0x48 | 0x104 | output |
0xA check_jig_response
Only on 1.03+.
Input: 0x10C bytes buffer.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | arg1: flag. |
0x44 | 0x4 | arg2 |
0x48 | 0x104 | input |
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
0xE0002
Used to decrypt lists stored in updates. Same format as 0x40002.
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 AuthPupHeader
Verify PUP header.
Input data size: 0xFF0.
0x20002 AuthPupSegment
Verify PUP segment.
Input data size: 0xFF0.
0x30002 AuthPupWatermark
Verify PUP watermark.
Input data size: 0xFF0.
0x40002 AuthSpkg
Decrypt SPKG package. 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 0xF48) | Copy of paddr list for pkg buffer (contents described at 0x50) |
0x50002 ENCIND_SLSK
Re-encrypt 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) | 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 (sceSblSsSNVSEncryptSectors) SNVS_ENC_SECTORS
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 in size, but the size in F00D packet +4 derives the xts size and memcpy.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Block size (0x20?) gets << 5 before memcpy use |
0x44 | 0x4 | Block size (0x20?) gets << 5 before memcpy use |
0x48 | ?? | buffer with size defined above |
?Input data size is 0x28?
0x70002 (sceSblUsSmSnvsDecryptSectors) SNVS_DEC_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.
?Input data size is 0x28?
0x80002 (sceSblUsSmSnvsEncryptMgmtData)
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.
0x90002 (sceSblUsSmSnvsDecryptMgmtData)
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 a 8 byte buffer returned in the main F00D packet.
0xA0002
Verify additional data.
0xB0002
0xC0002
0xD0002
Syscon update related. Usage is to proxy encrypted data F00D <=> Syscon.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | 0, 1, 3, or 4 |
0x44 | 0x4 | Unused |
0x48 | 0x28 | F00D input, syscon command 0xD2 output |
0x70 | 0x28 | F00D output, syscon command 0xD2 input |
utoken_sm.self
0x1
Get utoken.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Output buffer |
0x44 | 0x4 | Output buffer size (set to 0x800) |
0x48 | 0x4 | Time or 0xFFFFFFFF |
0x4C | 0x10 | Console ID (use sceSblSsMgrGetOpenPsIdForDriver) |
0x2
Decrypt utoken.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Output buffer |
0x44 | 0x4 | Output buffer size (set to 0x800) |
0x48 | 0x4 | Time or 0xFFFFFFFF |
0x4C | 0x10 | Console ID (use sceSblSsMgrGetOpenPsIdForDriver) |
mgkm_sm.self
These commands seems 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. This key seems to be used to do stuff with TripleDES and another unknown encrypt algorithm.