Filetype:Encrypted PSP Container
This page is a work in progress. As a result, the layout and/or content herein may be subject to change. |
About
Almost all PSP assets are contained within this encrypted container. The only major exception is TGA files (taken during grief reports) and root level resources, which are sent uncompressed and unencrypted to the game server.
Format
The container has no magic, but can be detected by verifying the MD5 hash contained within the file's footer. The whole file including the footer is encrypted using the AES-128-CTR cypher. The encryption key is stored at the address '0x003d9f30' in the decrypted 2.0.5 US EBOOT.BIN, and is stored within a 64-byte long chunk of data. To extract the 128-bit AES-128-CTR key from that 64-byte region, you need to run the following code[1] inside Node.js (or do the same steps manually in a hex editor).
const fs = require("fs"); //key.bin is a file containing the extracted 64-byte region starting from 0x003d9f30 in the decrypted LBP PSP US 2.0.5 EBOOT.BIN let block = fs.readFileSync('key.bin'); let key = Buffer.alloc(16); for (let i = 0; i < 16; ++i) key[i] = block[(i * 4) + (i % 4)]; //psp.key is the output key. fs.writeFileSync('psp.key', key);
The initial counter of the AES-128-CTR cipher (which is 16-bytes long) is the first 8 bytes of the encryption key, followed by 8 null bytes[2]. The contents of the file (minus the footer) may use LZO compression, with a flag in the footer specifying when it is used.
The footer is a 25 byte long region stored at the tail end of the file.
Offset | Name | Data Type |
---|---|---|
0x00 | Uncompressed Data Length | u32 |
0x04 | Compression flag | u8 |
0x05 | File Path | u32 (CRC32 checksum) |
0x09 | Data Hash | u128 (MD5 hash) |
The File Path is a CRC32 checksum generated using the ASCII bytes of the asset's file path. See a list of paths in the official archive here. For remote assets, a CRC32 value of zero will cause the game to error and abort the connection, so the CRC32 must be a non-zero value. Remote assets do not all need to have a unique CRC32 value. The data hash is an MD5 hash of the entire file before encryption plus the first 9 bytes of the footer.