Editing PSSE

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 2: Line 2:
== What is PSSE? ==
== What is PSSE? ==


PSSE stands for PlayStation Suite Encrypted. It is an encryption layer that encrypts the PSM game's filesystem.
PSSE Stands for PlayStation Suite Encrypted, its an encryption layer that encrypts a PSM game's filesystem, its comparable to PFS in alot of ways, however it seems there was a bug at sony where besides executable files, the first directory level of a PSM app is not encrypted with PSSE, its only directory levels below the root of RO/


The encryption layer is comparable to the PS Vita Protected [[Filesystem]] (PFS) in many ways; however, it seemed that there was a bug at Sony, where besides executable files, the first directory level of a PSM app is not encrypted with PSSE, whose directory level is below the root of RO/. Similarly, the PSM SaveData is not encrypted by such layer either.
also PSM SaveData does not get PSSE Encryption applied.


== Data Structure ==
== Data Structure ==
{| class="wikitable" style="font-size:small; text-align: center;border;"
{| class="wikitable" style="font-size:small; text-align: center;border:3px ridge #123AAA;"
|-
|-
|'''offset'''  
| style="background-color:#FFFFFF; color:#123AAA;" |'''offset'''  
|'''value'''  
| style="background-color:#FFFFFF; color:#123AAA;" |'''value'''  
|'''description'''  
| style="background-color:#FFFFFF; color:#123AAA;" |'''description'''  
|-
|-
|0x00||0x50535345 (ASCII "PSSE" / "PSME")||Magic Number / File Header
|0x00||0x50535345 (ASCII "PSSE")||Magic Number / File Header
|-
|-
|0x4|| int32 || Version
|0x14||[[System_File_Object_(SFO)_(PSF)#CONTENT_ID|CONTENT_ID]]||Contents of /RW/System/content_id
|-
|-
|0x8 || int64 || Decrypted file size
|0x40||Signature||Generated by PSMSDK 'publisher key'? - Similar to sce_sys/[[clearsign]] file of NpDrm-Encrypted apps
|-
|-
|0x10 || int32 || PSSE Type (always 0x1)
|0x180||Encrypted Keys||Generated by PSMSDK 'app key' and 'app seed'? - Similar to sce_sys/[[keystone]] file of NpDrm-Encrypted apps
|-
|-
|0x14|| char[0x24] [[System_File_Object_(SFO)_(PSF)#CONTENT_ID|CONTENT_ID]]||Contents of /RW/System/content_id
|0x680||Encrypted Data||Actual cipher-text for the encrypted file
|-
|0x40|| char[0x10] || MD5 Of Original File (Plaintext)
|-
|0x50 || char[0x20] || Encrypted Filename
|-
|0x70|| char[0x10] ||Encrypted IV
|-
|0x80|| char[0x200] ||RSA Signature?
|-
|0x280|| char[0x20] || HMAC hash of (encrypted) first block, (Vita), key is in RIF
|-
|0x2A0||char[0x1E0] || Reserved (all 0's)
|-
|0x480|| char[0x20] || HMAC hash of (encrypted) first block, (Android) key is in RIF
|-
|0x4A0|| char[0x1E0] || Reserved (all 0's)
|-
|0x680|| char[until next multiple of 0x8000] || encrypted block data
|-
|-
|}
|}


== Decryption ==
== Decryption ==
 
PSSE Can be decrypted using the http://bitbucket.org/SilicaAndPina/FuckPSSE plugin by [[SilicaAndPina]]
AES-128-CBC decrypt 0x10 bytes from 0x70 using [[Keys#PSSE_Header_IV|PSSE Header IV]] and [[Keys#PSSE_Header_Key|PSSE Header Key]]
the resulting decryption is the Contents IV, now take 0x10 bytes from 0x120 of the game's NoPsmDrm RIF, this is the Content Key
(if its one of the DLL's in the PSM Runtime Package, then the content key is [[Keys#Runtime_PSSE_App_Key|Runtime PSSE App Key]])
 
 
the content data section (0x680 onwards) is made up of blocks, each 0x8000 bytes in size
however the first block is only 0x7980 bytes, (0x8000 - 0x680) as if the block started at 0x00, however you start reading from 0x680
all subsequent blocks are 0x8000 bytes, so block 0 is at 0x680, block 1 at 0x8000, block 2 at 0x10000 etc,
and, at every interval of 0x80000 bytes there is an 0x400 byte gap before the next block starts
 
(that next block is then 0x7C00 bytes long, as if the block started at 0x80000, even though it starts at 0x800400)
and of course all subsequent ones are then 0x8000 past there again,
 
when reading each block the IV used to decrypt it changes slightly, usually just the first byte changes.
to calculate the IV for any given block, take that block's number (counting sequentially from 0x800, following all above rules)
as an int32, little endain, put it into a byte-array. and make that byte array be 0x10 bytes long, with the block number at the very start
eg, for block 4 it would be 0x04000000000000000000000000000000
then, XOR the original IV from the PSSE Header, with that byte array,
 
Decrypt each block using AES-128-CBC with the content IV you calculated earlier from header + block ID and the content KEY from the rif,
 
to decrypt the entire file, decrypt each block in-order.
 
A script that implements the above algorithm can be found here:
https://github.com/KuromeSan/psse-decrypt
it is in the public domain, so feel free to use it for whatever you want
Please note that all contributions to Vita Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see Vita Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)