AFV

From Vita Development Wiki
Jump to navigation Jump to search

AFV are activation files used by development/testing PS Vita and PS4 units.

Location

  • By default, the .afv file is downloaded from SCE servers to the host PC that has access to DevNet
  • ux0:activate.afv (to be verified in ss_mgr or in post_ss_mgr if AFV can be loaded from the PS Vita Memory Card)

Structure

Below is the format as parsed by PS Vita on System Software version 2.06 and below.

# VITA/ActivationCode
# format_version=1
# code_num=45
# code_size=199
open_psid_1, start_date_1, end_date_1‬, issue_no_1, encrypted_activation_token_1
...
open_psid_45, start_date_45, end_date_45‬, issue_no_45, encrypted_activation_token_45

Below is the format as parsed by PS Vita on System Software version 2.10 and newer.

# VITA/ActivationCode
# format_version=1
# code_num=45
# code_size=199
# extra_data_size=513
open_psid_1, start_date_1, end_date_1‬, issue_no_1, encrypted_activation_token_1,extra_data_1
...
open_psid_45, start_date_45, end_date_45, issue_no_45, encrypted_activation_token_45,extra_data_45

The AFV file contains a header made of comments that are not parsed by the console. Indeed, lines starting with a number sign (#) are skipped.

Syntax of the AFV header is as follows:

Value Description
# VITA/ActivationCode Magic
# format_version=1 AFV format version
# code_num=2 Number of activation codes. It can be incremented to support multiple devices for a single AFV activation file.
# code_size=199 Number of ASCII characters per activation code plus 1 supposedly for the null-byte terminator (not present in the file)
# extra_data_size=513 Present only in activation files using RSA-2048 signatures (PS4 and PS Vita 2.10+)

Each non-commented line of the AFV file represents an activation code.

Syntax of each activation code line is as follows:

Value Description
open_psid OpenPSID of the PS Vita or PS4 console
start_date Start date of activation in EPOCH Unix time and decimal
end_date End date of activation in EPOCH Unix time and decimal
issue_no 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 32)
encrypted_activation_token Encrypted Activation Token (64 bytes)
extra_data RSA-2048 signature of the Activation Token (256 bytes). Present only in activation files using RSA-2048 signatures (PS4 and PS Vita 2.10+). It is extracted to actsig.dat.

Example (with dummy OpenPSID and extra data):

# VITA/ActivationCode
# format_version=1
# code_num=2
# code_size=199
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 1546297725, ‭‭2082758400‬,          1, f32fe2cc3a6346714949b219e68391d13766e467053b265d110241c33c7d8e58d4466c84a9d2422511b11a450b34c6db270b51f55d5921ea50c7feb571675a88,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, 1546297725, ‭‭2082758400‬,          1, f32fe2cc3a6346714949b219e68391d149cadd26411291837b62c98ad5a7cd8b64dff1c0a224273c9de99327b3a5f6524db261536fe60f657056be94d0ee08d0,bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb

Crafting an AFV file without RSA-2048 Signature

As on PS Vita System Software 2.06 and earlier the RSA signature of the activated token is not verified, and because AES256-CMAC keys are known, it is possible to craft a valid AFV file to activate a PS Vita Dev/Test Kit running such a version of the System Software.

If the PS Vita Dev/Test Kit has arbitrary kernel code execution, it is also possible to directly modify the Activation token in Syscon NVS without the need of any 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  AES256-CMAC hash 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). It can be a 1:1 copy of the data from 0x0 to 0x30.
0x70 0x10 AES256-CMAC hash 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 PS Vita side)
0x47 1 set to the second AID byte in later encrypted tokens (ignored on the PS 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