PSVIMG: Difference between revisions
Red-EyeX32 (talk | contribs) |
CelesteBlue (talk | contribs) |
||
Line 8: | Line 8: | ||
# If making a PSVMD file, use the deflate algorithm to compress. | # If making a PSVMD file, use the deflate algorithm to compress. | ||
# Generate a random nonce for the first 0x10 bytes using the RndNumber syscall. | # Generate a random nonce for the first 0x10 bytes using the RndNumber syscall. | ||
# Generate a [[# | # Generate a [[#PSVIMG_Key_Derivation|unique session AES256-CBC key]] using a secret phrase and the account id. | ||
# Generate a SHA256 hash of the plaintext every 0x8000 bytes and insert the hash into the filestream. | # Generate a SHA256 hash of the plaintext every 0x8000 bytes and insert the hash into the filestream. | ||
# Encrypt the stream data using [[SceSblSsMgr#sceSblDmac5EncDecKeyGen|sceSblDmac5EncDecKeyGen]] with the nonce as the header and the AES256-CBC session key. | # Encrypt the stream data using [[SceSblSsMgr#sceSblDmac5EncDecKeyGen|sceSblDmac5EncDecKeyGen]] with the nonce as the header and the AES256-CBC session key. This key is set through kprx_auth_sm using [[F00D_Commands#0x50001|service 0x50001]]. It is then used in conjunction with encdec_w_portability to decrypt/encrypt PSVIMG blocks. | ||
# Transmit to PC or PS3. | # Transmit to PC or PS3. | ||
=== Key Derivation === | === PSVIMG Key Derivation === | ||
The AES256-CBC session key is calculated by: | The AES256-CBC session key is calculated by: | ||
* Creating a 33 byte buffer composed of 8 byte hex binary representation of your account id followed by | * Creating a 33 byte buffer composed of 8 byte hex binary representation of your account id followed by the 0x19 byte PSVIMG secret passphrase. | ||
* Calculating a SHA-256 hash of buffer above. | * Calculating a SHA-256 hash of buffer above. | ||
* | * Decrypting the 32 byte output of the calculated SHA-256 hash with AES128-ECB (128 bit key stored in kprx_sm_auth). | ||
* This decrypted output is the derived PSVIMG AES256-CBC key. | * This decrypted output is the derived PSVIMG AES256-CBC key. | ||
When you backup with CMA, | When you backup with CMA, the files are stored in a directory in your PC that consists of 16 character hex directory name within your backup path. That hex directory name is a representation of your account id. | ||
ex: \Documents\PS Vita\PSAVEDATA\0123456789abcdef\ with '0123456789abcdef' being your account id. | |||
<source lang=" | |||
#define | ==== Source code ==== | ||
<source lang="C"> | |||
#define NP_ACCOUNT_ID_LEN 8 | |||
#define CMA_PASSPHRASE_LEN 25 | #define CMA_PASSPHRASE_LEN 25 | ||
Line 32: | Line 35: | ||
{ | { | ||
... | ... | ||
memcpy(seed, aid, | memcpy(seed, aid, NP_ACCOUNT_ID_LEN); | ||
memcpy(seed + | memcpy(seed + NP_ACCOUNT_ID_LEN, passphrase, CMA_PASSPHRASE_LEN); | ||
... | ... | ||
int seed_len = ( | int seed_len = (NP_ACCOUNT_ID_LEN + CMA_PASSPHRASE_LEN); | ||
sha256((uint8_t*)seed, seed_len, session_key, 0); | sha256((uint8_t*)seed, seed_len, session_key, 0); | ||
aes_ecb_decrypt(session_key, CMA_SESSION_KEY_LEN); | aes_ecb_decrypt(session_key, CMA_SESSION_KEY_LEN); | ||
Line 43: | Line 46: | ||
} | } | ||
</source> | </source> | ||
==== Example ==== | ==== Example ==== | ||
This is an example where we are going to use account id: 0123456789abcdef | This is an example where we are going to use account id: 0123456789abcdef. | ||
<source> | <source> | ||
Line 54: | Line 58: | ||
00000020 65 e e | 00000020 65 e e | ||
</source> | </source> | ||
SHA-256 hash of this 32 byte buffer: | SHA-256 hash of this 32 byte buffer: | ||
<source> | <source> | ||
Line 68: | Line 73: | ||
This 32 byte (256 bits) sized buffer is the PSVIMG AES256-CBC key. | This 32 byte (256 bits) sized buffer is the PSVIMG AES256-CBC key. | ||
[[Category:Formats]] | [[Category:Formats]] |
Revision as of 20:40, 3 February 2019
PSVIMG files are encrypted files generated by CMA in backing up and restoring data from the Vita. The format is documented in this tool [1].
Generating PSVIMG
When CMA is used to backup system, game, or savedata from the PSVita to a PC or PS3, the following algorithm is used:
- Using a tar-like structure, stream all of the file data into a file.
- If making a PSVMD file, use the deflate algorithm to compress.
- Generate a random nonce for the first 0x10 bytes using the RndNumber syscall.
- Generate a unique session AES256-CBC key using a secret phrase and the account id.
- Generate a SHA256 hash of the plaintext every 0x8000 bytes and insert the hash into the filestream.
- Encrypt the stream data using sceSblDmac5EncDecKeyGen with the nonce as the header and the AES256-CBC session key. This key is set through kprx_auth_sm using service 0x50001. It is then used in conjunction with encdec_w_portability to decrypt/encrypt PSVIMG blocks.
- Transmit to PC or PS3.
PSVIMG Key Derivation
The AES256-CBC session key is calculated by:
- Creating a 33 byte buffer composed of 8 byte hex binary representation of your account id followed by the 0x19 byte PSVIMG secret passphrase.
- Calculating a SHA-256 hash of buffer above.
- Decrypting the 32 byte output of the calculated SHA-256 hash with AES128-ECB (128 bit key stored in kprx_sm_auth).
- This decrypted output is the derived PSVIMG AES256-CBC key.
When you backup with CMA, the files are stored in a directory in your PC that consists of 16 character hex directory name within your backup path. That hex directory name is a representation of your account id.
ex: \Documents\PS Vita\PSAVEDATA\0123456789abcdef\ with '0123456789abcdef' being your account id.
Source code
#define NP_ACCOUNT_ID_LEN 8 #define CMA_PASSPHRASE_LEN 25 static uint8_t passphrase[CMA_PASSPHRASE_LEN] = "Sri Jayewardenepura Kotte"; { ... memcpy(seed, aid, NP_ACCOUNT_ID_LEN); memcpy(seed + NP_ACCOUNT_ID_LEN, passphrase, CMA_PASSPHRASE_LEN); ... int seed_len = (NP_ACCOUNT_ID_LEN + CMA_PASSPHRASE_LEN); sha256((uint8_t*)seed, seed_len, session_key, 0); aes_ecb_decrypt(session_key, CMA_SESSION_KEY_LEN); return session_key; }
Example
This is an example where we are going to use account id: 0123456789abcdef.
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 01 23 45 67 89 AB CD EF 53 72 69 20 4A 61 79 65 .#Eg‰«ÍïSri Jaye 00000010 77 61 72 64 65 6E 65 70 75 72 61 20 4B 6F 74 74 wardenepura Kott 00000020 65 e e
SHA-256 hash of this 32 byte buffer:
02EAAB5A00EC9D4207E8B1F53F8A2F3F91F1A73AAFDD2A81CCFEE3E83E5B101A
The decrypted hash produces the following result after decrypting with AES128-ECB:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 AC A8 2B 25 34 69 8F 3B 3B EB 21 20 69 E8 37 D3 ¬¨+%4i.;;ë! iè7Ó 00000010 9E 85 34 69 73 78 89 8D 0E D7 30 7A D1 30 31 D4 ž…4isx‰..×0zÑ01Ô
This 32 byte (256 bits) sized buffer is the PSVIMG AES256-CBC key.