AFV: Difference between revisions
CelesteBlue (talk | contribs) |
No edit summary |
||
(8 intermediate revisions by one other user not shown) | |||
Line 15: | Line 15: | ||
Syntax of the header is as follows: | Syntax of the header is as follows: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 36: | Line 35: | ||
# code_num=1 | # code_num=1 | ||
# code_size=199 | # code_size=199 | ||
open_psid, start_date(epoch decimal), end_date(epoch decimal), issue_no, encrypted_activation_token | |||
</pre> | </pre> | ||
== Crafting | == Crafting an AFV file == | ||
=== Base token buffer === | |||
Build a 0x70 token buffer as follows: | |||
<pre> | <pre> | ||
Line 53: | Line 54: | ||
00000050 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª | 00000050 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª | ||
00000060 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ | 00000060 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ | ||
00000070 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX CMAC will be there | |||
</pre> | </pre> | ||
=== Macro Structure === | === Macro Structure === | ||
{| class="wikitable" | {| class="wikitable" | ||
! Offset !! Description | ! Offset !! Size !! Description | ||
|- | |- | ||
| | | 0x00 || 0x30 || Activation Data (as seen in act.dat) | ||
|- | |- | ||
| 0x30 | | 0x30 ||0x10 || Padding, zeroed | ||
|- | |- | ||
| 0x40 | | 0x40 || 0x30 || Encrypted Activation Data (in decrypted form), can be a 100% copy of the data from 0x0 to 0x30 | ||
|- | |- | ||
| 0x70 | | 0x70 || 0x10 || CMAC of 0 thru 0x70 | ||
|} | |} | ||
Line 73: | Line 76: | ||
! Offset !! Size !! Description | ! Offset !! Size !! Description | ||
|- | |- | ||
| | | 0x00 || 4 || Magic "act\0" | ||
|- | |- | ||
| 0x04 || 4 || | | 0x04 || 4 || Format version (always 0x1) | ||
|- | |- | ||
| 0x08 || 4 || | | 0x08 || 4 || Issue No (increments for each activation, it needs to be higher than the current token/activation counter, you may need to keep incrementing it until it works, or use a higher value like 0x20) | ||
|- | |- | ||
| 0x0C || 4 || Start date (Unix time, hex, little-endian) | | 0x0C || 4 || Start date (Unix time, hex, little-endian) | ||
Line 83: | Line 86: | ||
| 0x10 || 4 || End date (Unix time, hex, little-endian) | | 0x10 || 4 || End date (Unix time, hex, little-endian) | ||
|- | |- | ||
| 0x14 || 0x10 || | | 0x14 || 0x10 || OpenPSID | ||
|- | |- | ||
| 0x24 || | | 0x24 || 0x1C || Padding | ||
|- | |- | ||
| 0x40 || 4 || unk | | 0x40 || 4 || unk | ||
Line 100: | Line 101: | ||
It is speculated that on later sony's own encrypted token bytes 0x05 to 0x07 (0x45 to 0x47 in the buffer) are set to avoid having the first encrypted CBC block data repeat across multiple devices. Those bytes are ignored by act_sm and can be all set to 0x00. | It is speculated that on later sony's own encrypted token bytes 0x05 to 0x07 (0x45 to 0x47 in the buffer) are set to avoid having the first encrypted CBC block data repeat across multiple devices. Those bytes are ignored by act_sm and can be all set to 0x00. | ||
=== | === AES256-CMAC === | ||
Take the 0x70 first bytes of the base token buffer: | |||
<pre> | |||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
00000000 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ | |||
00000010 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª | |||
00000020 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ | |||
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
00000040 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ | |||
00000050 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª | |||
00000060 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ | |||
</pre> | |||
Calculate the CMAC of | Calculate the AES256-CMAC hash of this buffer using the following command: | ||
<code> | <code> | ||
openssl dgst -mac cmac -macopt cipher:aes-256-cbc -macopt hexkey:846D2DFD77D3C2E5F0E17EB18CC786928B881E2E17AE0CD8FDE88809D0D033C5 | openssl dgst -mac cmac -macopt cipher:aes-256-cbc -macopt hexkey:846D2DFD77D3C2E5F0E17EB18CC786928B881E2E17AE0CD8FDE88809D0D033C5 base_token_buffer.bin | ||
</code> | </code> | ||
For that particular buffer the return value is: | For that particular buffer the return value is: | ||
<code> | <code>aes256_cmac(base_token_buffer.bin) = e555fe806c33978b4694af72b5597b1d</code> | ||
This 0x10 byte result must be written to offset 0x70. | |||
<pre> | |||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |||
00000000 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ | |||
00000010 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª | |||
00000020 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ | |||
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | |||
00000040 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ | |||
00000050 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª | |||
00000060 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ | |||
00000070 E5 55 FE 80 6C 33 97 8B 46 94 AF 72 B5 59 7B 1D åUþ€l3—‹F”¯rµY{. | |||
</pre> | |||
=== Intermediate Token === | |||
Create a 0x40 buffer using data of your previous buffer from 0x40 to 0x80: | |||
<pre> | <pre> | ||
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 | ||
Line 123: | Line 154: | ||
</pre> | </pre> | ||
Encrypt | Encrypt this 0x40 byte buffer with the following command: | ||
<code> | <code> | ||
openssl aes-256-cbc -in step2.bin -K 846D2DFD77D3C2E5F0E17EB18CC786928B881E2E17AE0CD8FDE88809D0D033C5 -iv C8A040662B10A1986A1894E94FBEFCF0 -e > | openssl aes-256-cbc -in step2.bin -K 846D2DFD77D3C2E5F0E17EB18CC786928B881E2E17AE0CD8FDE88809D0D033C5 -iv C8A040662B10A1986A1894E94FBEFCF0 -e > intermediate_token.bin | ||
</code> | </code> | ||
Below is the result for that particular token: | |||
<pre> | <pre> | ||
Line 139: | Line 172: | ||
</pre> | </pre> | ||
=== Final Token === | |||
Get the first 0x40 bytes of that encrypted buffer (disregard the last 0x10 bytes of CBC padding). That will be your final token. | |||
<pre> | <pre> | ||
Line 151: | Line 184: | ||
00000030 27 0B 51 F5 5D 59 21 EA 50 C7 FE B5 71 67 5A 88 '.Qõ]Y!êPÇþµqgZˆ | 00000030 27 0B 51 F5 5D 59 21 EA 50 C7 FE B5 71 67 5A 88 '.Qõ]Y!êPÇþµqgZˆ | ||
</pre> | </pre> | ||
=== Final AFV === | |||
You can now create your afv file as shown below: | You can now create your afv file as shown below: | ||
Line 161: | Line 196: | ||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 1546297725, 2082758400, 1, f32fe2cc3a6346714949b219e68391d13766e467053b265d110241c33c7d8e58d4466c84a9d2422511b11a450b34c6db270b51f55d5921ea50c7feb571675a88 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 1546297725, 2082758400, 1, f32fe2cc3a6346714949b219e68391d13766e467053b265d110241c33c7d8e58d4466c84a9d2422511b11a450b34c6db270b51f55d5921ea50c7feb571675a88 | ||
</pre> | </pre> | ||
[[Category:Formats]] |
Latest revision as of 22:08, 1 May 2023
Activation File Verification
AFV are activation files used for/by development unit, they follow this format
Below format is as parsed by firmware 1.692 or below, firmware 1.800 or later expect a newer AFV format.
# VITA/ActivationCode # format_version=1 # code_num=2 # code_size=199 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 1546297725, 2082758400, 1, f32fe2cc3a6346714949b219e68391d13766e467053b265d110241c33c7d8e58d4466c84a9d2422511b11a450b34c6db270b51f55d5921ea50c7feb571675a88 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, 1546297725, 2082758400, 1, f32fe2cc3a6346714949b219e68391d149cadd26411291837b62c98ad5a7cd8b64dff1c0a224273c9de99327b3a5f6524db261536fe60f657056be94d0ee08d0
Syntax of the header is as follows:
Value | Description |
---|---|
# VITA/ActivationCode | MAGIC |
# format_version=1 | AFV format version |
# code_num=2 | Number of activation codes, can be incremented to add multiple devices per activation file |
# code_size=199 | Number of characters per code + 1 |
# extra_data_size=513 | Only in later activation files using signatures (for firmware 2.10+) |
# VITA/ActivationCode # format_version=1 # code_num=1 # code_size=199 open_psid, start_date(epoch decimal), end_date(epoch decimal), issue_no, encrypted_activation_token
Crafting an AFV file
Base token buffer
Build a 0x70 token buffer as follows:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ 00000010 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª 00000020 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ 00000050 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª 00000060 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ 00000070 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX CMAC will be there
Macro Structure
Offset | Size | Description |
---|---|---|
0x00 | 0x30 | Activation Data (as seen in act.dat) |
0x30 | 0x10 | Padding, zeroed |
0x40 | 0x30 | Encrypted Activation Data (in decrypted form), can be a 100% copy of the data from 0x0 to 0x30 |
0x70 | 0x10 | CMAC of 0 thru 0x70 |
Detailed Structure
Offset | Size | Description |
---|---|---|
0x00 | 4 | Magic "act\0" |
0x04 | 4 | Format version (always 0x1) |
0x08 | 4 | Issue No (increments for each activation, it needs to be higher than the current token/activation counter, you may need to keep incrementing it until it works, or use a higher value like 0x20) |
0x0C | 4 | Start date (Unix time, hex, little-endian) |
0x10 | 4 | End date (Unix time, hex, little-endian) |
0x14 | 0x10 | OpenPSID |
0x24 | 0x1C | Padding |
0x40 | 4 | unk |
0x45 | 1 | set to 0x1 on later encrypted token (ignored on the vita side) |
0x46 | 1 | set to the first AID byte in later encrypted tokens (ignored on the vita side) |
0x47 | 1 | set to the second AID byte in later encrypted tokens (ignored on the vita side) |
It is speculated that on later sony's own encrypted token bytes 0x05 to 0x07 (0x45 to 0x47 in the buffer) are set to avoid having the first encrypted CBC block data repeat across multiple devices. Those bytes are ignored by act_sm and can be all set to 0x00.
AES256-CMAC
Take the 0x70 first bytes of the base token buffer:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ 00000010 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª 00000020 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ 00000050 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª 00000060 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............
Calculate the AES256-CMAC hash of this buffer using the following command:
openssl dgst -mac cmac -macopt cipher:aes-256-cbc -macopt hexkey:846D2DFD77D3C2E5F0E17EB18CC786928B881E2E17AE0CD8FDE88809D0D033C5 base_token_buffer.bin
For that particular buffer the return value is:
aes256_cmac(base_token_buffer.bin) = e555fe806c33978b4694af72b5597b1d
This 0x10 byte result must be written to offset 0x70.
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ 00000010 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª 00000020 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000040 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ 00000050 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª 00000060 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ 00000070 E5 55 FE 80 6C 33 97 8B 46 94 AF 72 B5 59 7B 1D åUþ€l3—‹F”¯rµY{.
Intermediate Token
Create a 0x40 buffer using data of your previous buffer from 0x40 to 0x80:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 61 63 74 00 01 00 00 00 01 00 00 00 7D A1 2A 5C act.........}¡*\ 00000010 00 5F 24 7C AA AA AA AA AA AA AA AA AA AA AA AA ._$|ªªªªªªªªªªªª 00000020 AA AA AA AA 00 00 00 00 00 00 00 00 00 00 00 00 ªªªª............ 00000030 E5 55 FE 80 6C 33 97 8B 46 94 AF 72 B5 59 7B 1D åUþ€l3—‹F”¯rµY{.
Encrypt this 0x40 byte buffer with the following command:
openssl aes-256-cbc -in step2.bin -K 846D2DFD77D3C2E5F0E17EB18CC786928B881E2E17AE0CD8FDE88809D0D033C5 -iv C8A040662B10A1986A1894E94FBEFCF0 -e > intermediate_token.bin
Below is the result for that particular token:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 F3 2F E2 CC 3A 63 46 71 49 49 B2 19 E6 83 91 D1 ó/âÌ:cFqII².æƒ‘Ñ 00000010 37 66 E4 67 05 3B 26 5D 11 02 41 C3 3C 7D 8E 58 7fäg.;&]..AÃ<}ŽX 00000020 D4 46 6C 84 A9 D2 42 25 11 B1 1A 45 0B 34 C6 DB ÔFl„©ÒB%.±.E.4ÆÛ 00000030 27 0B 51 F5 5D 59 21 EA 50 C7 FE B5 71 67 5A 88 '.Qõ]Y!êPÇþµqgZˆ 00000040 77 06 44 05 52 64 1C 21 33 91 DB 1B 07 50 67 18 w.D.Rd.!3‘Û..Pg.
Final Token
Get the first 0x40 bytes of that encrypted buffer (disregard the last 0x10 bytes of CBC padding). That will be your final token.
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 F3 2F E2 CC 3A 63 46 71 49 49 B2 19 E6 83 91 D1 ó/âÌ:cFqII².æƒ‘Ñ 00000010 37 66 E4 67 05 3B 26 5D 11 02 41 C3 3C 7D 8E 58 7fäg.;&]..AÃ<}ŽX 00000020 D4 46 6C 84 A9 D2 42 25 11 B1 1A 45 0B 34 C6 DB ÔFl„©ÒB%.±.E.4ÆÛ 00000030 27 0B 51 F5 5D 59 21 EA 50 C7 FE B5 71 67 5A 88 '.Qõ]Y!êPÇþµqgZˆ
Final AFV
You can now create your afv file as shown below:
# VITA/ActivationCode # format_version=1 # code_num=1 # code_size=199 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 1546297725, 2082758400, 1, f32fe2cc3a6346714949b219e68391d13766e467053b265d110241c33c7d8e58d4466c84a9d2422511b11a450b34c6db270b51f55d5921ea50c7feb571675a88