Rights Information Files
The PS4 content license files are, like on PSP, PS3, PS Vita and PS5, the .rif files.
But for the first time, the format has changed a lot:
- Since System Software 5.00 at least, there is only one .rif file (and .idx) per Service ID instead of one per Content ID. Concretely, on PSP, PS3 and PS Vita, there was one .rif per content (one for the game and one for each additional content), whilst on PS4, the .rif files contains many RIF structures (one for the game, and one for each additional content).
- This is handled by adding each DLC license to the game .rif. To determine where the license for a specific content is in the .rif, the PS4 generates a .idx file (RIF index).
- When a .rif is downloaded from PSN by SceShellCore, it is added to the current .rif (RIFA) file of the game,if existing. Then the .idx is generated. SceShellCore calls npdrm_ioctl to get a 0x10 bytes HMAC-SHA256 per-console key from SAMU. A HMAC-SHA256 digest is computed over the RIF data and is written to the .idx entry. The aim of this procedure is both to ensure license integrity and to make sure that the licenses cannot be copied to another PS4 console.
See also PSP, PS3 and PS Vita RIF files.
See also Sample RIF files.
Location[edit | edit source]
The PS4 Rights Information Files and associated files can be found in:
/user/license/*.rif
,/user/license/*.idx
for fake/free RIFs, for all users/user/home/<User ID>/license/*.rif
,/user/home/<User ID>/license/*.idx
for per-account RIFs (KDS)/mnt/disc/license/rif
on Bluray Disc, for per-disc RIFs, for all users/preinst2/app/CUSA00001/app.rif
on internal HDD, for The Playroom free RIF, for all usersSc0/license.dat
, in PKG entries
RIF[edit | edit source]
For a RIF file that is paired with an IDX file, see RIFA file.
RIF Structure[edit | edit source]
Fields are big-endian.
Name | Offset | Size | Example | Remark |
---|---|---|---|---|
Magic | 0x000 |
4 | 52 49 46 00 ('RIF\0') |
|
Version | 0x004 |
2 | 00 01 , 00 02 , 00 03 |
See Type |
Unknown | 0x006 |
2 | FF FF , 00 02 |
FF FF on fake and disc, 00 02 on KDS. |
NP Account ID | 0x008 |
8 | AB CD EF 01 02 34 78 91 |
Zeroed if not KDS: fake, disc, etc. |
Start Timestamp | 0x010 |
8 | 00 00 00 00 00 00 00 00 , 00 00 00 00 52 85 64 00 , 00 00 00 00 67 57 64 B3 |
Start timestamp (unix/epoch). Zeroed on fake. |
End Timestamp | 0x018 |
8 | 7F FF FF FF FF FF FF FF |
End timestamp (unix/epoch). When no expire date, set to INT64_MAX (7F FF FF FF FF FF FF FF ).
|
Content ID | 0x020 |
0x30 | IP9100-CUSA00001_00-PLAYROOM00000000 |
The actual Content ID is 0x24 bytes and the rest is usually zeroed. |
Type | 0x050 |
2 | 01 01 |
See Type |
DRM Type | 0x052 |
2 | 00 0F (Local (PS4)) |
Same as PKG DRM Type. PS5 uses 00 10 for Local (PS5). |
Content Type | 0x054 |
2 | 00 1A (PS4GD), 00 1B (PS4AC) |
Same as PKG Content Type. PS5 uses 00 20 for PS5GD. |
SKU Flag | 0x056 |
2 | 00 00 , 00 01 , 00 03 |
Not Bootable: 0, Trial: 1, Full Game: 3 |
Extra Flags | 0x058 |
4 | 00 00 00 00 |
|
Unknown Flags | 0x05C |
4 | 00 00 00 00 , 00 04 00 00 |
00 04 00 00 on free RIF, 00 00 00 00 on disc and debug |
Unknown | 0x060 |
4 | 00 02 00 00 |
00 00 00 00 on PS5 |
Unknown | 0x064 |
4 | 00 00 00 00 , 00 00 00 01 |
00 00 00 01 on a Kiosk demo, KDS, debug, 00 00 00 00 on disc, on a debug, on a free |
Unknown | 0x068 |
3 | 00 00 00 , 00 4A 00 |
00 4A 00 on a debug, KDS, 00 00 00 usually. Maybe related to Network. |
Unknown | 0x06B |
1 | 01 , 02 , 03 |
01 on a debug, KDS, 02 on some old RIFs (3.55), 03 on some new RIFs (5.00) |
Unknown | 0x06C |
0x2 | 00 00 , 00 02 |
00 02 on a debug, KDS, 00 00 usually. Maybe related to Network. |
Unknown | 0x06E |
0x1D2 | - | |
Disc Key | 0x240 |
0x20 | - | Present on disc. zeroed on demo, debug and KDS. |
Secret Encryption IV | 0x260 |
0x10 | - | On debug for fPKG RIF, it is the first 16 bytes of the SHA-256 hash of the 0x30 bytes of Content ID. On debug for PKG, demo, KDS and disc, the algorithm is unknown. On debug for finalized PKG RIF, it is independent of the Content ID as it is the same for a game in two regions. |
Encrypted Secret | 0x270 |
0x90 | - | See Secret for when decrypted. Present even on debug. |
Signature | 0x300 |
0x100 | - | RSA2048 signature. Verified using the public key depending on the Type. |
Type[edit | edit source]
Type | Platform | Min Version | Max Version | Name | Description | Remarks |
---|---|---|---|---|---|---|
0x000
|
All | 1 | 1 | KDS (NPDRM) | Used for digital content | Revoked in at least 4.05 |
0x001
|
All | 2 | 2 | |||
0x002
|
All | 3 | 3 | |||
0x101
|
All | 1 | 1 | Isolated ("free" RIF) | Used for truly free content (Playroom, Omsk, Kiosk Demo, Vue, Spotify). For OMSK Daemon, the RIF is copied and renamed to "free" from a .rif file in the same folder as the .pkg. | |
0x302
| ||||||
0x102
|
All | 1 | 1 | Disc | Used for Blu-ray content | |
0x200
|
DEX/TEST | 1 | 1 | Debug ("fake" RIF) | Used for testing/debugging on DEX/TEST ?and for all users?. The fake RIF is ?extracted from Sc0/license.dat in ?f?PKG or? when installing a fPKG without any RIF through the Package Installer.
|
|
0x201
| ||||||
0x202
| ||||||
0x303
|
CEX | 1 | 1 | ? | ||
0x304
|
? (not CEX) | 1 | 1 | ? | ||
0x305
|
DEX/TEST | 1 | 1 | ? |
Secret[edit | edit source]
PS4 RIF Secret size is 0x90 bytes. The last 0x70 bytes of the RIF Secret may be what maxton call "Derived Keys".
- See also maxton's LibOrbisPkg wiki
- See also PS Vita shared secret on PS3 Dev Wiki contained in some PS Vita SELF headers.
On debug for fPKG RIF, the decrypted secret is empty except the first 16 bytes, which are the second 16 bytes of the Content ID hash.
The following structure corresponds to the decrypted form.
Name | Offset | Size | Example | Remark |
---|---|---|---|---|
Content ID Hash Part 2 | 0x00 |
16 | - | On debug for fPKG RIF, this is the second 16 bytes of the Content ID hash. |
Padding | 0x10 |
16 | - | Zero byte padding (16 bytes) |
Reserved (?dk0, overwritten with passcode or RSA-encrypted passcode?) | 0x20 |
16 | - | Zero byte padding (16 bytes) |
Content Key Seed (?dk1/EKPFS?) | 0x30 |
16 | - | Used to generate PFS key |
SELF Key Seed (?dk2?) | 0x40 |
16 | - | Used to generate SELF key |
Unknown (?dk3?) | 0x50 |
16 | - | Random 16 bytes of unknown purpose |
Unknown (?dk4?) | 0x60 |
16 | - | Random 16 bytes of unknown purpose |
Entitlement Key (?dk5?) | 0x70 |
16 | - | Usually all zeroes. Used on Additional Content. On debug for finalized PKG RIF, it is independent of the Content ID as it is the same for a game in two regions. |
Padding (?dk6?) | 0x80 |
16 | - | Zero byte padding (16 bytes) |
RIFA File[edit | edit source]
This RIF form is paired with a .idx file. See also RIDX structure for the paired IDX file.
When in this form, a RIFA header is present, followed by sequential RIFs.
RIFA Header[edit | edit source]
Fields are big-endian. Size is 0x400 bytes.
Name | Offset | Size | Example | Remark |
---|---|---|---|---|
Magic | 0x000 |
4 | 72 69 66 61 ("rifa") |
|
Service ID | 0x004 |
0x14 | IP9100-CUSA00001_00\0 |
Size assumed |
Unknown | 0x018 |
0x3D8 | full of zeroes |
RIDX File[edit | edit source]
RIDX Structure[edit | edit source]
Fields are little-endian. Size is 0x20 bytes (header) + entries_count * 0x30 bytes (entry_size).
Name | Offset | Size | Example | Remark |
---|---|---|---|---|
Magic | 0x00 |
4 | 78 64 69 72 ('xdir', standing for RIF Index) |
|
Entries Count | 0x04 |
4 | code>01 00 00 00, 03 00 00 00 |
|
Version | 0x08 |
1 | 01 |
1 (current) |
Service ID | 0x09 |
0x13 | IP9100-CUSA00001_00 |
|
Unknown | 0x1C |
4 | 01 00 00 00 , 00 00 00 00 |
|
Entries | 0x20 |
0x30 * Entries_Count | - | See RIDX entry |
RIDX Entry[edit | edit source]
Fields are little-endian. Size is 0x30 bytes.
Name | Offset | Size | Example | Remark |
---|---|---|---|---|
Entitlement Label | 0x00 |
0x10 | PLAYROOM00000000 |
|
RIF Offset | 0x10 |
8 | 00 04 00 00 00 00 00 00 |
Offset into RIFA file |
RIF Size | 0x18 |
8 | 00 04 00 00 00 00 00 00 |
|
Unknown | 0x20 |
1 | 01 |
|
Unknown | 0x21 |
1 | 00 |
|
RIF Digest | 0x22 |
8 | - | First 8 bytes of HMAC-SHA256 digest of RIF data (?0x400 bytes?) using per-console data as key |
Unknown | 0x2A |
6 | - |