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 unique session AES256-CBC key using a secret phrase and the PSN account id. | + | # 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. |
| | | |
− | === Secrets === | + | === PSVIMG Key Derivation === |
| | | |
− | If you look on your PC at the 16 character hex directory name included in part of the backup path, that is your PSN Account Id.
| + | The AES256-CBC session key is calculated by: |
− | The AES256-CBC session key is calculated by doing a SHA256 hash of the 8 byte hex binary representation of the PSN Account Id followed by the secret phrase: | + | * Creating a 33 byte buffer composed of 8 byte hex binary representation of your account id followed by the 0x19 byte PSVIMG secret passphrase. |
− | <code>Sri Jayewardenepura Kotte</code>
| + | * 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_auth_sm). |
| + | * This decrypted output is the derived PSVIMG AES256-CBC key. |
| | | |
− | ==== Example ==== | + | 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. |
| + | |
| + | ==== Pseudocode ==== |
| + | |
| + | <source lang="C"> |
| + | #define NP_ACCOUNT_ID_LEN 8 |
| + | #define CMA_PASSPHRASE_LEN 25 |
| + | |
| + | static uint8_t passphrase[CMA_PASSPHRASE_LEN] = "Sri Jayewardenepura Kotte"; |
| | | |
− | Buffer of an example of PSN Account Id:
| + | { |
− | <source>
| + | ... |
− | 01 23 45 67 89 AB CD EF 53 72 69 20 4A 61 79 65 77
| + | memcpy(seed, aid, NP_ACCOUNT_ID_LEN); |
− | 61 72 64 65 6E 65 70 75 72 61 20 4B 6F 74 74 65
| + | memcpy(seed + NP_ACCOUNT_ID_LEN, passphrase, CMA_PASSPHRASE_LEN); |
− | </source>
| + | ... |
| + | |
| + | 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); |
| | | |
− | SHA256 of this buffer consists in the AES256-CBC session key:
| + | return session_key; |
− | <source>
| + | } |
− | 02EAAB5A00EC9D4207E8B1F53F8A2F3F91F1A73AAFDD2A81CCFEE3E83E5B101A
| |
| </source> | | </source> |
| | | |
− | To generate the PSVIMG AES key, the buffer is decrypted using AES128-ECB with a 128 bits key located at offset 0x82DC in the 3.60 kprx_auth_sm (Prototype units use another key located at offset 0x7294 in 1.03 kprx_auth_sm ).
| + | ==== Example ==== |
− | | |
− | This key is set though kprx_auth_sm using [[F00D_Commands#0x50001|service 0x50001]]).
| |
| | | |
− | It is then used in conjunction with encdec_w_portability to decrypt/encrypt PSVIMG blocks.
| + | This is an example where we are going to use account id: 0123456789abcdef. |
| | | |
| <source> | | <source> |
| Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | | Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |
| | | |
− | 00000000 00 00 00 00 00 00 00 00 53 72 69 20 4A 61 79 65 ........Sri Jaye | + | 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 | | 00000010 77 61 72 64 65 6E 65 70 75 72 61 20 4B 6F 74 74 wardenepura Kott |
| 00000020 65 e | | 00000020 65 e |
| </source> | | </source> |
| | | |
− | SHA-256: | + | SHA-256 hash of this 32 byte buffer: |
| <source> | | <source> |
− | 186F29050C0D0D99038D86EFA9B6AD332E59564B7FFCA97985C09D64BD4BC442
| + | 02EAAB5A00EC9D4207E8B1F53F8A2F3F91F1A73AAFDD2A81CCFEE3E83E5B101A |
| </source> | | </source> |
| | | |
− | The encrypted above hash produces the following result: | + | The decrypted hash produces the following result after decrypting with AES128-ECB: |
| <source> | | <source> |
| Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | | Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |
| | | |
− | 00000000 65 DE EF DE 3A 14 10 B5 6F 60 D0 AB B9 D9 9D FA eÞïÞ:..µo`Ы¹Ù.ú | + | 00000000 AC A8 2B 25 34 69 8F 3B 3B EB 21 20 69 E8 37 D3 ¬¨+%4i.;;ë! iè7Ó |
− | 00000010 97 45 BF 55 C9 22 E3 44 A1 13 2E EB 67 60 9C 0D —E¿UÉ"ãD¡..ëg`œ. | + | 00000010 9E 85 34 69 73 78 89 8D 0E D7 30 7A D1 30 31 D4 ž…4isx‰..×0zÑ01Ô |
| </source> | | </source> |
| + | |
| + | This 32 byte (256 bits) sized buffer is the PSVIMG AES256-CBC key. |
| | | |
| | | |
| [[Category:Formats]] | | [[Category:Formats]] |