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 SceSysmem#get_paddr_list 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 and load SELFs for F00D. The SELF header is passed into a page aligned buffer and a paddr list is generated from it.
0x10001
Parses 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 | 0x4 | Unknown |
0x44 | 0x4 | 0x1 if user SELF, otherwise 0x0 |
0x48 | 0x8 | 0x2808000000000001LL
|
0x50 | 0x8 | 0xF000C000000080LL
|
0x58 | 0x8 | 0xFFFFFFFF00000000LL
|
0x60 | 0x10 | Unknown |
0x70 | 0x8 | 0xC300003800980LL
|
0x78 | 0x8 | 0x8009800000LL
|
0x80 | 0x8 | Unknown |
0x88 | 0x8 | 0xFFFFFFFF00000000LL
|
0x90 | 0x8 | Unknown |
0x98 | 0x40 | Not used |
0xD8 | 0x60 | Return data (0x90 length overwriting) ? |
0x138 | 0x10 | Copy of data at 0x68
|
0x148 | 0x10 | Unknown |
0x158 | 0x4 | 0x10
|
0x15C | 0xC | Unknown |
0x168 | 0x4 | SELF path code |
0x16C | 0x4 | Unknown |
0x170 | 0x4 | Number of paddr list entries for buffer |
0x174 | 0x4 | Physical address of paddr list |
SELF Path Code
This code is found by the path the SELF was loaded from. It's used by F00D to check if the SELF being loaded from an allowed partition. A path that does not start with any of the following will have 0
returned as the code. It could also be used to select the key used in decryption.
Path | Code |
---|---|
sd0: | 1 |
os0: | 2 |
vs0: | 3 |
vd0: | 4 |
tm0: | 5 |
ur0: | 6 |
host0: | 7 |
ud0: | 11 |
ux0:app | 23 |
ux0:patch | 24 |
ux0:data | 25 |
ux0:user | 0 |
ux0: | 12 |
gro0:app | 13 |
grw0:patch | 14 |
sa0: | 15 |
mfa0: | 16 |
mfb0: | 17 |
lma0: | 18 |
lmb0: | 19 |
lmc0: | 20 |
lmd0: | 21 |
pd0: | 22 |
0x20001
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
Decrypt a buffer from the SELF corresponding to the program segment number passed in above. The segment is read in 0x10000
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
Used by SceSblAuthMgr for decryption maybe?
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
Used by SceSblAuthMgr to set key for decryption (?).
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 | Set to 0 |
0x60001
Used by SceSblAuthMgr for decryption maybe?
0x70001
Used by SceSblAuthMgr for some kind of decryption process related to ACT.DAT
0x80001
Used by SceSblAuthMgr for used by the VSH function _vshSblAuthMgrVerifySpsfo.
act_sm.self
0x2
Verify afv data
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Magic "act\0" |
0x44 | 0x1 | Format version |
0x45 | 0x3 | Unused |
0x48 | 0x4 | Issue number (increment each activation, prevent rollback) |
0x4C | 0x4 | Start validity time unix timestamp |
0x50 | 0x4 | End validity time unix timestamp |
0x54 | 0x10 | Activation key |
0x64 | 0x1C | Unused |
0x80 | 0x40 | Encrypted Data (I think 0x20 byte data + 0x20 byte HMAC) |
0x4
Verify activation data
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 (see below) |
0x5
Get activation data. The returned data is sent to Syscon at offset 0x520.
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) |
0x7
Check if activation is valid. The activation data is read from Syscon at offset 0x520.
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Unknown |
0x44 | 0x4 | Current time unix timestamp |
0x48 | 0x8 | Unknown |
0x50 | 0x20 | Activation data |
0xA
Introduced in 2.12. 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 | Same buffer as command 0x2 (new activation data) |
0xC0 | 0x100 | Signature over new activation data |
0x1C0 | 0x80 | Same buffer as command 0x2 (previous activation data) |
0x240 | 0x100 | Signature over previous activation data |
0x340 | 0x20 | Same buffer as command 0x4 (new activation buffer from syscon) |
0xB
Introduced in 2.12. 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 | Same buffer as command 0x4 (activation buffer from syscon) |
0x78 | 0x80 | Same buffer as command 0x2 |
0xF8 | 0x100 | Signature over activation data |
aimgr_sm.self
0x1
Returns 16 byte console id (used in vshSblAimgrGetConsoleId)
0x3
Used in vshSblAimgrGetVisibleId
0x2
Returns the console's OpenPSID. Also known as the "activation key" for PDEL and PTEL.
0x4
Used in vshSblAimgrGetPscode2
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 seem to be used to do some kind of key derivation. May also be used as a general purpose encryption engine.
0x1000A
Encrypt data
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Key ID (max 0x0A) |
0x44 | 0x4 | Output Length |
0x48 | 0x20 | Output |
0x68 | 0x4 | Input Length (max 0x20) |
0x6C | 0x20 | Input |
0x8C | 0x10 | IV |
0x2000A
Decrypt data
Offset | Size | Description |
---|---|---|
0x40 | 0x4 | Key ID (max 0xA) |
0x44 | 0x4 | Input Length (max 0x20) |
0x48 | 0x20 | Input |
0x68 | 0x4 | Output 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 key slot. Valid key slots are only 1-10.
gcauthmgr_sm.self
0x1000B
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 160bit 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 (2) |
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 validation service. Size of request is 0x116. Size of response is 0x34.
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 | 0x34 | unknown |
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
0x1
0x2
0x3
0x4
0x5
0x6
0x7
0x8
0x9
0xA
qaf_sm.self
0x1
0x2
rmauth_sm.self
0x1
0x2
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 SceSblSsUpdateMgr 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
Verify PUP header.
0x20002
Verify PUP segment.
0x30002
Verify watermark.
0x40002
Decrypt package. Allocate a page aligned buffer and read the complete pkg 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
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) | Paddr list to paddr list to encrypt |
0x60002
0x70002
0x80002
0x90002
0xA0002
Verify additional data.