Editing PKG files

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
See also {{talk}} page, [http://www.psdevwiki.com/ps4/PKG_files PS4 PKG], [[PKG_DIGEST.DAT]], [https://psdevwiki.com/vita/index.php?title=System_File_Object_(SFO)_(PSF)].
See also {{talk}} page


There are two kinds of SCE package files (.pkg):
= Firmware Packages =
* System Software Update Packages (.pkg)
* NPDRM Packages (.pkg)


= System Software Update Packages =
== File Header ==  


System Software Update files are packed into .pkg files then encrypted into .spkg, a sort of [[Certified File]].
All values are in big endian format.


A System Update package contains 3 segments:
   typedef struct {
1) update_package_header
     u32 0x00, 0x53434500// magic
2) update_package_contents_header
    u32 0x04, 2 // version
3) update_package itself
    u16 0x08, 0 // sdk type?
 
    u16 0x0a, 3 // SCE header type; pkg
= NPDRM Packages =
    u32 0x0c, 0 // meta offset
 
    u64 0x10,           // size of sce_hdr + sizeof meta_hdr
== Security ==
    u64 0x18, 0x80      // + content_size_real
 
   }
The security of .pkg consists in some hashes and signatures.
 
All NPDRM packages are signed with an ECDSA signature. Usually NPDRM packages are signed with two signatures - one for the header and the other for the entry table.
 
PS3: file SHA-1 + QA digest + ECDSA signature.
 
PSP: PS3 securities + Extended Header (3 [[PKG_files#PKG_HMAC_algorithm|PKG HMAC]] hashes of the headers).
 
PS Vita: PSP securities + more Metadata (0xD-0x12) that embed digests of files embedded into the .pkg.
 
=== PKG Digest ===
 
See [[Keys#NPDRM_PKG.2FSELF_ECDSA_Public_Key]].
 
{| class="wikitable"
|-
! Name !! Offset !! Size !! Remark
|-
| cmac_hash || 0x0 || 0x10 || AES-CMAC hash. Using always npdrm_pkg_ps3_aes_key / npdrm_pkg_ps3_idu_aes_key, whatever the platform is.
|-
| npdrm_signature || 0x10 || 0x28 || PKG header NPDRM ECDSA signature (R_sig, S_sig).
|-
| sha1_hash || 0x38 || 0x8 || Last 8 bytes of sha1 hash.
|}
 
<source lang="C">
   typedef struct pkg_digest { // size is 0x40
    u8 cmac_hash[0x10];
    u8 npdrm_signature[0x28];
     u8 sha1_hash[0x8];
  } pkg_digest;
</source>
 
=== PKG HMAC algorithm ===
 
This is a 16 bytes hash using SHA-1 algorithm. Used in Extended Header hashes.
 
<source lang="C">
static void pkg_hmac(const uint8_t *data, unsigned int len, uint8_t hmac[16]) {
  SHA1_CTX ctx;
  uint8_t sha1[20];
  uint8_t buf[64];
 
  // Do SHA-1 of the actual data
  sha1_init(&ctx);
  sha1_update(&ctx, data, len);
  sha1_final(&ctx, sha1);
 
  // Setup the intermediate buffer
  memset(buf, 0, 64);
  memcpy(&buf[0], &sha1[4], 8);
  memcpy(&buf[8], &buf[0], 8);
  memcpy(&buf[16], &sha1[12], 4);
   buf[20] = sha1[16];
  buf[21] = sha1[1];
  buf[22] = sha1[2];
  buf[23] = sha1[3];
  memcpy(&buf[24], &buf[16], 8);


  // Do SHA-1 of the intermediate buffer
= Game Packages =
  sha1_init(&ctx);
All game packages are signed with the ECDSA signature. The public key for it can be found in '''download_plugin.prx''' or in '''nas_plugin.prx''' (this also applies to NPDRM SELFs). Usually game packages are signed with two signatures - one for the header and the other for the entry table.
  sha1_update(&ctx, buf, 64);
  sha1_final(&ctx, sha1);
 
  // Returns 16 first bytes from the 20 bytes SHA-1
  memcpy(hmac, sha1, 16);
}
</source>
 
=== Decryption ===
 
See also [[#Package_Tools]] and [[Keys#NPDRM PKG AES Keys]].
 
==== Finalized Packages ====
 
Finalized (retail) packages are encrypted using AES128CTR with a key derived from a constant key (NPDRM PKG AES key).
 
===== PS3 / PSP Finalized Packages =====
 
For PS3 / PSP NPDRM packages, the file table and the data are AES128CTR encrypted/decrypted using pkg_data_riv as the IV along with the PS3/PSP constant AES Key.
 
<source lang="C">
static void decrypt_finalized_npdrm_pkg(void) {
u8 key[0x10];
u8 iv[0x10];
 
if (be16(pkg->pkg_type) != 1)
fail("invalid pkg type: %x", be16(pkg + 0x06));
 
if (key_get_simple("npdrm-pkg-key", key, 0x10) < 0)
fail("failed to load the package key.");
 
memcpy(iv, pkg->digest, 0x10);
aes128ctr(key, iv, pkg + offset, size, pkg + offset);
}
</source>
 
===== PS Vita / PSM Finalized Packages =====
 
For PS Vita / PSM NPDRM packages type 2, 3 and 4, pkg_data_riv is AES128ECB encrypted with the constant per-platform AES128 key to create an AES session key. Then it does the normal AES128CTR with pkg_data_riv as the IV and the session key as the AES128CTR key.
 
<source lang="C">
// Source code to add here
</source>
 
==== Non Finalized Packages ====
 
Non Finalized packages use a key which is derived from the digest field of the package header, then used in a CBC like-mode which is then sha1'ed to get the final XOR key.
 
The derivation of the key differs between standard Non Finalized packages and arcade Non Finalized packages, e.g. [[Namco_System_357]].
 
<source lang="C">
static void decrypt_non_finalized_npdrm_pkg(void) {
u8 key[0x40];
u8 bfr[0x1c];
u64 i;
 
memset(key, 0, sizeof key);
memcpy(key, pkg->pkg_header_digest, 8);
memcpy(key + 0x08, pkg->pkg_header_digest, 8);
if (isArcade)
memcpy(key + 0x10, pkg->pkg_header_digest, 8);
else
memcpy(key + 0x10, pkg->pkg_header_digest + 0x08, 8);
memcpy(key + 0x18, pkg->pkg_header_digest + 0x08, 8);
if (isArcade)
memset(key + 0x20, 0xA0, 0x18);
 
sha1(key, sizeof key, bfr);
 
for (i = 0; i < size; i++) {
if (i != 0 && (i % 16) == 0) {
wbe64(key + 0x38, be64(key + 0x38) + 1);
sha1(key, sizeof key, bfr);
}
pkg[offset + i] ^= bfr[i & 0xf];
}
}
</source>
 
Source: SSL and zecoxao via [https://www.arcade-projects.com/forums/index.php?thread/6132-system-357-pkg-decryption/&postID=195720#post195720].


== File Header ==
== File Header ==


Header consists of main header that points to metadata header. PSP and PS Vita .pkg also have .ext header right after main header.
=== Example from a retail PS3 .pkg ===
 
=== Example from a finalized PS3 .pkg ===


*Example: Scott Pilgrim VS. The World Unlock .pkg [http://zeus.dl.playstation.net/cdn/UP0001/NPUB30162_00/bG751I62Aych0U2E7hsxD5vKS28NurYg8CmJln6oQV4LUDAfXGSOyQHE45reFxIuwD5Qjo1xnQleHqulmmx9HmjNnXX8P5O5jcXlD.pkg file]:
*Example: Scott Pilgrim VS. The World Unlock .pkg [http://zeus.dl.playstation.net/cdn/UP0001/NPUB30162_00/bG751I62Aych0U2E7hsxD5vKS28NurYg8CmJln6oQV4LUDAfXGSOyQHE45reFxIuwD5Qjo1xnQleHqulmmx9HmjNnXX8P5O5jcXlD.pkg file]:
Line 181: Line 39:
  '''000000B0'''  <span style="background-color:#3f48cc; color:#FFFFFF">CC 02 B4 35 2B 70 47 D6</span> <span style="background-color:#a349a4; color:#FFFFFF;">EC 61 40 39 A6 5B DC BD</span>  М.ґ5+pGЦмa@9¦[ЬЅ
  '''000000B0'''  <span style="background-color:#3f48cc; color:#FFFFFF">CC 02 B4 35 2B 70 47 D6</span> <span style="background-color:#a349a4; color:#FFFFFF;">EC 61 40 39 A6 5B DC BD</span>  М.ґ5+pGЦмa@9¦[ЬЅ


=== Header ===
=== PKG header ===


All values are in big-endian format.
{| class="wikitable sortable"
 
{| class="wikitable"
|-
|-
! Name !! Offset !! Size !! Example !! Remark
| style="background-color:#515243; color:#FFFFFF;" |'''Name'''
| style="background-color:#515243; color:#FFFFFF;" |'''Offset'''
| style="background-color:#515243; color:#FFFFFF;" |'''Size'''
| style="background-color:#515243; color:#FFFFFF;" |'''Example'''
| style="background-color:#515243; color:#FFFFFF;" |'''Remark'''
|-
|-
| <span style="background:#ff0000;">magic || 0x00 || 0x04 || 7F 50 4B 47 || ".PKG"
| <span style="background:#ff0000;">magic || 0x00 || 0x04 || 7F 50 4B 47 || '.PKG'
|-
|-
| <span style="background-color:#008000; color:#FFFFFF;">pkg_revision || 0x04 || 0x02 || 80 00 || 80 00 for finalized (retail), 00 00 for non finalized (debug)
| <span style="background-color:#008000; color:#FFFFFF;">pkg_revision || 0x04 || 0x02 || 80 00 || 80 00 for retail (finalized), 00 00 for debug (non finalized)
|-
|-
| <span style="background-color:#3F48CC; color:#FFFFFF;">pkg_type    || 0x06 || 0x02 || 00 01 || 00 01 for PS3, 00 02 for PSP and PS Vita
| <span style="background-color:#3F48CC; color:#FFFFFF;">pkg_type    || 0x06 || 0x02 || 00 01 || 00 01 for PS3, 00 02 for PSP and PSVita
|-
|-
| <span style="background-color:#B5E61D;">pkg_metadata_offset        || 0x08 || 0x04 || 00 00 00 C0 || usually 0xC0 for PS3, usually 0x280 for PSP and PS Vita
| <span style="background-color:#B5E61D;">pkg_metadata_offset        || 0x08 || 0x04 || 00 00 00 C0 || 0xC0, usually 0x280 for PSP and PSVita
|-
|-
| <span style="background-color:#B97A57;">pkg_metadata_count          || 0x0C || 0x04 || 00 00 00 08 || metadata item count
| <span style="background-color:#B97A57;">pkg_metadata_count          || 0x0C || 0x04 || 00 00 00 08 || item count
|-
|-
| <span style="background-color:#ff7f27;">pkg_metadata_size          || 0x10 || 0x04 || 00 00 00 C0 || usually 0xC0 for PSP and PS3, usually 0x160 for PS Vita
| <span style="background-color:#ff7f27;">pkg_metadata_size          || 0x10 || 0x04 || 00 00 00 C0 || usually 0xC0 for PSP and PS3, usually 0x160 for PSVita
|-
|-
| <span style="background-color:#fff200;">item_count        || 0x14 || 0x04 || 00 00 00 02 || files and folders into the encrypted data
| <span style="background-color:#fff200;">item_count        || 0x14 || 0x04 || 00 00 00 02 || files and folders into the encrypted data
Line 215: Line 75:
| <span style="background-color:#000000; color:#ffffff;">digest || 0x60 || 0x10 || 09 8B A2 CA 2D 30 30 1F 8B 5B 82 79 C6 70 35 F3 || sha1 from debug files and attributes together merged in one block
| <span style="background-color:#000000; color:#ffffff;">digest || 0x60 || 0x10 || 09 8B A2 CA 2D 30 30 1F 8B 5B 82 79 C6 70 35 F3 || sha1 from debug files and attributes together merged in one block
|-
|-
| <span style="background-color:#ed1c24;">pkg_data_riv          || 0x70 || 0x10 || D5 FA 15 9E 7F AC 82 70 BB 3E 0C EB 97 3D 30 11 || AES-128-CTR IV. Used with npdrm_pkg_PLATFORM_aes_key to decrypt data.
| <span style="background-color:#ed1c24;">pkg_data_riv          || 0x70 || 0x10 || D5 FA 15 9E 7F AC 82 70 BB 3E 0C EB 97 3D 30 11 || aes-128-ctr iv. Used with gpkg_key to decrypt data.
|-
| <span style="background-color:#808000;">header_cmac_hash      || 0x80 || 0x10 || 48 0D 86 60 9F 26 8E 7F 4F B4 DA A4 33 1E 9A A1 || CMAC OMAC hash from 0x00-0x7F. PS3 gpkg_key used as key.
|-
| <span style="background-color:#3f48cc; color:#FFFFFF;">header_npdrm_signature || 0x90 || 0x28 || || PKG header NPDRM ECDSA (R_sig, S_sig)
|-
|-
| <span style="background-color:#808000;">pkg_header_digest     || 0x80 || 0x40 || || PKG Digest structure signing data at 0x00-0x7F.
| <span style="background-color:#a349a4; color:#FFFFFF;">header_sha1_hash     || 0xB8 || 0x08 || EC 61 40 39 A6 5B DC BD || last 8 bytes of sha1 hash of 0x00-0x7F
|}
|}


<source lang="C">
 
All values are in big endian format.
 
   typedef struct {
   typedef struct {
     u32 magic;
     u32 magic;
Line 235: Line 101:
     u8 digest[0x10];
     u8 digest[0x10];
     u8 pkg_data_riv[0x10];
     u8 pkg_data_riv[0x10];
     pkg_digest pkg_header_digest;
     u8 header_cmac_hash[0x10];
    u8 header_npdrm_signature[0x28];
    u8 header_sha1_hash[0x8];
   } PKG_HEADER;
   } PKG_HEADER;
</source>
=== Extended Header ===
Not present on PS3 .pkg. Only present on PSP and PS Vita .pkg. It was certainly a security improvement implemented in PS Vita Pkg Installer.
HMAC pointed by this header are generated using [[PKG_files#PKG_HMAC_algorithm|PKG HMAC algorithm]].
<source lang="C">
  typedef struct {
    u32 magic;                            // 0x7F657874 (".ext")
    u32 unknown_1;                        // Maybe version. Always 1.
    u32 ext_hdr_size;                      // Extended header size. ex: 0x40
    u32 ext_data_size;                    // ex: 0x180
    u32 main_and_ext_headers_hmac_offset;  // ex: 0x100
    u32 metadata_header_hmac_offset;      // ex: 0x360, 0x390, 0x490
    u64 tail_offset;                      // Tail size seems to be always 0x1A0
    u32 padding1;
    u32 pkg_key_id;                        // Id of the AES key used for decryption. PSP = 0x1, PS Vita = 0xC0000002, PSM = 0xC0000004
    u32 full_header_hmac_offset;          // ex: none (old pkg): 0, 0x930
    u8 padding2[0x14];
  } PKG_EXT_HEADER;
</source>


=== PKG Metadata ===
=== PKG Metadata ===


<source lang="C">
   typedef struct {
   typedef struct {
   union {
   union{
     u32 packet_identifier; // 0-0x12
     u32 packet_identifier; // 0-0x12
     u32 data_size;
     u32 data_size;
     {
     {
     // data
     data
     }
     }
   } ...
   } ...
   // u8 padding[variable];
   // u8 padding[variable];
   pkg_digest pkg_metadata_digest; // [[PKG_files#PKG_digest]]
   u8 unknown[0x40];
   } PKG_METADATA;
   } PKG_METADATA;
</source>


{| class="wikitable"
{| class="wikitable"
! Identifier !! PKG type !! Category name !! Possible size !! Possible values
! Identifier !! category name !! Possible size !! Possible values
|-
|-
|0x1 || All || [[NPDRM#DRM_Type|DRMType]] || 4 || See [[NPDRM#DRM_Type|DRMType]].
|0x1 || DRM Type || 4 || 0/5/6/7/8/9/0xA/0xB/0xC (unknown), 0x1 (network), 0x2 (local), 0x3 (DRMfree no license), 0x4 (PSP), 0xD (DRMfree with license), 0xE (PSM)
|-
|-
|0x2 || All || [[PKG_files#ContentType|ContentType]] || 4 || 00 00 00 07
|0x2 || [[PKG_files#ContentType|ContentType]] || 4 || 00 00 00 07
|-
|-
|0x3 || All || [[PKG_files#PackageType|PackageType]] / [[PKG_files#PackageFlag|PackageFlag]] / [[PKG_files#StorageType|StorageType]] (PS Vita) || 4 ||
|0x3 || [[PKG_files#PackageType|PackageType]] / [[PKG_files#PackageFlag|PackageFlag]] / [[PKG_files#StorageType|StorageType]] (PSVita) || 4 ||
|-
|-
|0x4 || All || Package Size || 8 || 00 00 00 00 0E 77 40 00
|0x4 || Package Size || 8 || 00 00 00 00 0E 77 40 00
|-
|-
|0x5 || All || make_package_npdrm Revision (2 bytes) + Package Version (2 bytes) || 4 || 00 00 00 00 (0, 0.00), 09 11 00 00 (911, 0.00), 09 56 00 00 (956, 0.00), 09 60 00 00 (960, 0.00), 10 09 00 00 (1009, 0.00), 10 12 00 00 (1012, 0.00), 10 61 00 00 (1061, 0.00), 12 03 00 00 (1203, 0.00), 12 12 00 00 (1212, 0.00), 12 73 01 01 (1273, 1.01), 15 00 01 00 (1500, 1.00), 16 81 01 00 (1681, 1.00),19 53 01 00 (1953, 1.00), 19 63 01 00 (1963, 01.00), 19 66 01 00 (1966, 01.00), 19 70 01 01 (1970, 1.01),19 72 01 02 (1972, 1.02), 99 00 00 00 (9900, 0.00), 99 01 00 00 (9901, 0.00)
|0x5 || make_package_npdrm Revision (2 bytes) + Package Version (2 bytes) || 4 || 09 60 00 00 (960, 0.00), 12 03 00 00 (1203, 0.00), 12 12 00 00 (1212, 0.00), 12 73 01 01 (1273, 1.01), 19 53 01 00 (1953, 1.00), 19 63 01 00, 19 66 01 00, 19 72 01 02 (1972, 1.02)
|-
|-
|0x6 || PSP || Version + App Version / [[TitleID]] (on size 0xC) || 0xC || "NPEG00005\0\0\0"
|0x6 || Version + App Version / [[TitleID]] (on size 0xC) || 0xC || "NPEG00005\0\0\0"
|-
|-
|0x7 || PSP, PS3 and PS Vita before rev 1949 || QA Digest (described as "This is a digest of packaged files and attributes.") || 0x18 || 00 00 00 00 00 00 00 00 B5 76 E1 D9 00 EE 9B BC 8E 24 17 91 5D BC 5A CB
|0x7 || QA Digest (described as "This is a digest of packaged files and attributes.")|| 0x18 || 00 00 00 00 00 00 00 00 B5 76 E1 D9 00 EE 9B BC 8E 24 17 91 5D BC 5A CB
|-
|-
|0x8 || All || unk (1 byte) + PS3/PSP/PSP2 System Version (3 bytes) + Package Version (2 bytes) + App Version (2 bytes) || 8 || 00 00 00 00 00 00 00 00, 00 00 00 00 01 00 01 00, 44 01 70 00 01 01 00 00, 81 01 90 00 01 00 01 00, 81 04 75 00 01 02 01 00 (4.7500, 1.02, 1.00) --> unk: 44 maybe PSP and 02/80/81 PS3
|0x8 || unk (1 byte) + PS3/PSP/PSP2 System Version (3 bytes) + Package Version + App Version || 8 || 00 00 00 00 00 00 00 00, 00 00 00 00 01 00 01 00, 44 01 70 00 01 01 00 00, 81 01 90 00 01 00 01 00, 81 04 75 00 01 02 01 00 (4.7500, 1.02, 1.00) --> 44 maybe PSP and 80/81 PS3
|-
|-
|0x9 || All || unk || 8 || 00 00 00 00 00 00 00 00 / 00 00 00 00 00 24 00 00 / 00 00 00 10 00 00 00 00 / 00 00 00 01 00 00 00 00 / 00 00 00 00 00 02 00 00 / 00 00 00 04 00 00 00 00 / 00 00 00 00 00 04 00 00
|0x9 || unk || 8 || either 00 00 00 00 00 00 00 00 or 00 00 00 00 00 24 00 00
|-
|-
|0xA || PSP and PS3|| InstallDirectory || 0x28 || 8 zeroed bytes + directory: ........UCES01264_FANTASY...............
|0xA || InstallDirectory || 0x28 || 8 zeroed bytes + directory: ........UCES01264_FANTASY...............
|-
|-
|0xB || All || unk seen in PSP cumulative patch || 0x8 || 00 00 00 00 00 00 00 01
|0xB || unk seen in PSP cumulative patch || 0x8 || 00 00 00 00 00 00 00 01
|-
|-
|0xC || All || unk ||  ||
|0xC || unk ||  ||
|-
|-
|0xD || PS Vita || [[PKG_files#PKG Item Record|Item Entries+Names Info]] || 0x28 || Offset in encrypted data (4 Bytes) + Size (4 Bytes) + SHA256 of decrypted data (32 Bytes)<br /> 00 00 00 00 / 00 00 05 A0 / 18 8B B1 8A E5 E8 40 FD EE 71 E2 27 60 55 E6 39 06 94 5B 65 89 04 B2 88 61 DA BB A3 B2 55 C5 C1
|0xD || ?ECDSA sig (or hash)? || 0x28 || always 6 zeroed chars at the beginning
00 00 00 00 00 00 05 A0 18 8B B1 8A E5 E8 40 FD EE 71 E2 27 60 55 E6 39 06 94 5B 65 89 04 B2 88 61 DA BB A3 B2 55 C5 C1
|-
|-
|0xE || PS Vita || [[PKG_files#sfo_info|PARAM.SFO Info]] || 0x38 || Offset (4 Bytes) + Size (4 Bytes)  + Flags? (4 Bytes)  + Firmware (?4 Bytes?) + Unknown (?8 Bytes?) + SHA256 (32 Bytes)<br />00 00 0C 10 / 00 00 05 0C / 00 00 00 14 / 01 67 00 00 / 00 00 00 00 00 00 00 00 / FC 3D 1E 32 FA F7 A6 11 90 46 A6 34 BE 98 9A 78 65 A8 92 25 3C 49 D7 69 73 53 32 E7 8E 06 1E 60
|0xE || [[PKG_files#PARAM_SFO_info|PARAM.SFO Info]] || 0x38 || 00 00 0C 10 00 00 05 0C 00 00 00 14 01 67 00 00 00 00 00 00 00 00 00 00 FC 3D 1E 32 FA F7 A6 11 90 46 A6 34 BE 98 9A 78 65 A8 92 25 3C 49 D7 69 73 53 32 E7 8E 06 1E 60
|-
|-
|0xF || PS Vita || [[PKG_files#unknown_data_info|unknown_data_info]] || 0x48 || 00 00 05 60 00 00 03 20 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 0F 26 BD 5C 2F 13 95 EB 16 E6 62 07 8D 9A E3 DC 0B AC 25 11 1C 19 39 B9 40 06 4E 82 AF 1E C3
|0xF || [[PKG_files#unknown_data0_info|unknown_data0_info]] || 0x48 || 00 00 05 60 00 00 03 20 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 0F 26 BD 5C 2F 13 95 EB 16 E6 62 07 8D 9A E3 DC 0B AC 25 11 1C 19 39 B9 40 06 4E 82 AF 1E C3
00 00 06 10 00 00 03 20 00 00 01 F4 00 00 01 F7 00 00 00 00 01 01 01 01 A5 74 D5 71 00 03 00 01 00 00 00 00 00 00 00 00 79 52 B2 3F 78 3B 9D F4 C0 BB 26 C0 EC 14 1B 37 8B 9B 69 71 1C 22 C3 49 57 97 B6 DE 78 0A D0 00
00 00 06 10 00 00 03 20 00 00 01 F4 00 00 01 F7 00 00 00 00 01 01 01 01 A5 74 D5 71 00 03 00 01 00 00 00 00 00 00 00 00 79 52 B2 3F 78 3B 9D F4 C0 BB 26 C0 EC 14 1B 37 8B 9B 69 71 1C 22 C3 49 57 97 B6 DE 78 0A D0 00
|-
|-
|0x10 || PS Vita || [[PKG_files#entirety_info|Entirety Info]] || 0x38 || 00 00 0A 00 00 00 00 A0 D3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 4D AD EB 44 67 51 C1 2D 69 95 46 8C 82 A9 3D 74 AD F4 62 49 90 BD EE F0 75 97 A3 B6 5B 17 48
|0x10 || [[PKG_files#entirety_info| Entirety Info]] || 0x38 || 00 00 0A 00 00 00 00 A0 D3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 4D AD EB 44 67 51 C1 2D 69 95 46 8C 82 A9 3D 74 AD F4 62 49 90 BD EE F0 75 97 A3 B6 5B 17 48
00 00 0A B0 00 00 01 60 FF D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D2 7F 9E EF 38 F7 61 6E C1 C5 CC B1 E1 83 12 0C 6F 38 4C 8C 22 84 8B A4 3B 7B 47 57 77 C9 F9 C9
00 00 0A B0 00 00 01 60 FF D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D2 7F 9E EF 38 F7 61 6E C1 C5 CC B1 E1 83 12 0C 6F 38 4C 8C 22 84 8B A4 3B 7B 47 57 77 C9 F9 C9
|-
|-
|0x11 || PS Vita || PublishingTools version (4 Bytes) + PFSBuilder version (4 Bytes) + padding (0x20 Bytes) || 0x28 || 01 60 00 00 00 06 23 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|0x11 || PublishingTools version (4 Bytes) + PFSBuilder version (4 Bytes) + padding (0x20 Bytes) || 0x28 || 01 60 00 00 00 06 23 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
02 07 00 00 00 07 60 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
02 07 00 00 00 07 60 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|-
|-
|0x12 || PS Vita || [[PKG_files#self_info|self_info]] || 0x38 || 00 00 11 20 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CF 74 D5 30 04 99 F0 57 E8 65 20 5C 3D 71 12 36 F1 E4 EF BC 98 EA 52 F1 F0 60 E8 7C 8A 53 B8 A4
|0x12 || [[PKG_files#unknown_data2_info|unknown_data2_info]] (points to a 0x10 bytes buffer)|| 0x38 || 00 00 11 20 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CF 74 D5 30 04 99 F0 57 E8 65 20 5C 3D 71 12 36 F1 E4 EF BC 98 EA 52 F1 F0 60 E8 7C 8A 53 B8 A4
|}
|}


Line 323: Line 167:


{| class="wikitable"
{| class="wikitable"
! Content type !! Type name !! Install path (on PS3) !! Install path (on PS Vita) !! Notes
! content type !! type name !! install path (on ps3) !! notes
|-
|-
|0x1 || ? || /dev_hdd0/game/ || || Found in UP0700-NPUJ00213_00-0000000000000002 (so old that it does not embed make_package_npdrm revision)
|0x00000001 || || ||
|-
|-
|0x2 ||  || ||  ||
|0x00000002 ||  ||  ||
|-
|-
|0x3 ||  || ||  ||
|0x00000003 ||  ||  ||
|-
|-
|0x4 || GameData || /dev_hdd0/game/ || || Also concerns game patches.
|0x00000004 || GameData (also patches) || /dev_hdd0/game/ ||
|-
|-
|0x5 || GameExec || /dev_hdd0/game/ || ||
|0x00000005 || GameExec || /dev_hdd0/game/ ||
|-
|-
|0x6 || PS1emu || /dev_hdd0/game/ || ux0:pspemu/PSP/GAME/ ||
|0x00000006 || PS1emu || /dev_hdd0/game/ ||
|-
|-
|0x7 || PSP || /dev_hdd0/game/ || ?ux0:pspemu/PSP/GAME/? || Also concerns PCEngine.
|0x00000007 || PSP & PCEngine || /dev_hdd0/game/ ||
|-
|-
|0x8 || || ||  ||
|0x00000008 || || ||
|-
|-
|0x9 || Theme || /dev_hdd0/theme || || e.g. contains a .p3t wrapped into a .edat
|0x00000009 || Theme || /dev_hdd0/theme ||
|-
|-
|0xA || Widget || /dev_hdd0/widget || ||
|0x0000000A || Widget || /dev_hdd0/widget ||
|-
|-
|0xB || License || /dev_hdd0/home/<current user>/exdata || || e.g. contains a .edat to unlock game demos
|0x0000000B || License || /dev_hdd0/home/<current user>/exdata ||
|-
|-
|0xC || VSHModule || /dev_hdd0/vsh/modules/ || ||
|0x0000000C || VSHModule || /dev_hdd0/vsh/modules/ ||
|-
|-
|0xD || PSN Avatar || /dev_hdd0/home/<current user>/psn_avatar || || e.g. contains a .png wrapped into a .edat
|0x0000000D || PSN Avatar || /dev_hdd0/home/<current user>/psn_avatar ||
|-
|-
|0xE || PSPgo || /dev_hdd0/game/ || || Displayed as Unknown Album: Corrupted Data
|0x0000000E || PSPgo || /dev_hdd0/game/ || Displayed as Unknown Album: Corrupted Data
|-
|-
|0xF || minis || /dev_hdd0/game/ || ux0:pspemu/PSP/GAME/ ||
|0x0000000F || minis || /dev_hdd0/game/ ||
|-
|-
|0x10 || NEOGEO || /dev_hdd0/game/ || ux0:pspemu/PSP/GAME/ ||
|0x00000010 || NEOGEO || /dev_hdd0/game/ ||
|-
|-
|0x11 || VMC || /dev_hdd0/tmp/vmc/ || ||
|0x00000011 || VMC || /dev_hdd0/tmp/vmc/ ||
|-
|-
|0x12 || ?PS2Classic? Seen on PS2 classic || || /dev_hdd0/game/ ||
|0x00000012 || ?PS2Classic? Seen on PS2 classic || /dev_hdd0/game/ ||
|-
|-
|0x13 || || ||  ||
|0x00000013 || || ||
|-
|-
|0x14 || Seen on PSP remastered || /dev_hdd0/game/ || ||
|0x00000014 || Seen on PSP remastered || /dev_hdd0/game/ ||
|-
|-
|0x15 || PSP2GD (PS Vita Game Data) || e.g. dev_bdvd/PS3_GAME/CROSSDIR/DATA000.PKG || ux0:app/ || e.g. PS3 Cross controller, PS VITA gd/gdc games/apps
|0x00000015 || PSP2GD (PSVita Game Data) || ||
|-
|-
|0x16 || PSP2AC (PS Vita Additional Content) || || ux0:addcont/ ||
|0x00000016 || PSP2AC (PSVita Additional Content) || ||
|-
|-
|0x17 || PSP2LA (PS Vita LiveArea) || || ?ux0:livearea/? ||
|0x00000017 || PSP2LA (PSVita LiveArea) || ||
|-
|-
|0x18 || ?PSM? (PS Vita PSM) || || ux0:psm/ || [https://www.playstation.com/en-ca/explore/playstation-mobile/ PlayStation Mobile]
|0x00000018 || ?PSM? (PSVita PSM) || ||
|-
|-
|0x19 || WT || /dev_hdd0/game/ || || Probably Web TV.
|0x00000019 || WT (Web TV?) || /dev_hdd0/game/ ||
|-
|-
|0x1D || ?PSM? (PS Vita PSM) || || ||
|0x0000001D || ?PSM? (PSVita PSM) || ||
|-
|-
|0x1F || PSP2Theme (PS Vita Theme) || || ux0:theme/ ||
|0x0000001F || PSP2Theme (PSVita Theme) || ||
|}
|}


Line 385: Line 229:
! Identifier !! type name !! usage !! notes
! Identifier !! type name !! usage !! notes
|-
|-
| 0x10 || Patch || for PSP game updates, to use with CumulativePatch, IncrementalPatch, HybridPatch ||
| unk || Patch || for PSP game updates, to use with CumulativePatch, IncrementalPatch, HybridPatch ||
|-
|-
| DiscBinded + Game + Patch || DiscGamePatch || for PS3 BD games ||
| unk || DiscGamePatch || for PS3 BD games ||
|-
|-
| Game + Patch || HDDGamePatch || for PS3 HDD games (NPDRM) ||
| unk || HDDGamePatch || for PS3 HDD games (NPDRM) ||
|-
|-
| ?when 2 is not set? || NoEBOOTBIN ||  ||
| unk || NoEBOOTBIN ||  ||
|-
|-
| ex: 00 00 00 0A || Demo ||  ||
| unk || Demo ||  ||
|-
|-
| ex: 00 00 00 0C || Key ||  ||
| unk || Key ||  ||
|-
|-
| ? || Upgradable ||  ||
| unk || Upgradable ||  ||
|}
|}
To class : DiscBinded, NonGame


=== PackageFlag ===
=== PackageFlag ===


{| class="wikitable"
{| class="wikitable"
! Flag !! Name !! Usage !! Notes
! Identifier !! type name !! usage !! notes
|-
| unk || RenameDirectory ||  ||
|-
| unk || NoRenameDirectory ||  ||
|-
|-
| 0 || NO FLAGS ||  || It exists e.g. in IP9100-NPIA00001_00-PS2HDDSYSDAT0001 built with revision 960 (very old)!
| unk || Finalized ||  ||
or even in UP0700-NPUJ00213_00-0000000000000002 (so old that it does not embed make_package_npdrm revision).
|-
|-
| 0x2 || ?EBOOT? || || Minis have it.
| unk || CumulativePatch || Embeds the previous patches || to use with Patch StorageType
|-
|-
| 0x4 || ?Require License? || ||  
| unk || IncrementalPatch || Requires the previous patches to be installed first || to use with Patch StorageType
|-
|-
| 0x8 || ?HDD/MC? ||  || NON Finalized flagged PS3 package (DLC)
| unk || HybridPatch ||  || to use with Patch StorageType
|}
 
=== StorageType ===
 
Seams to be PSVita only.
 
{| class="wikitable"
! Identifier !! type name !! usage !! notes
|-
|-
| 0x10 || CumulativePatch || Embeds the previous patches || To use with Patch PackageType.
| 00 00 20 0E, 00 00 20 1E || VC-MC || ||
|-
|-
| ? || IncrementalPatch || Requires the previous patches to be installed first || To use with Patch PackageType.
| 00 00 00 0E || VC-VC || ||
|}
 
=== package.conf (PS3/PSVita), NPDRM.CONF (PSP) ===
 
{| class="wikitable"
! Config name !! usage !! expected value !! example
|-
|-
| ? || HybridPatch || || To use with Patch PackageType.
| Content_ID (PS3) / Content-ID (PSP) || needed || XXYYYY-XXXXYYYYY_00-XXXXXXXXXXXXXXXX || EP4153-NPEZ00314_00-0000111122223333
|-
|-
| 0x40 || RenameDirectory || ||
| K_licensee (PS3) / K-Licensee (PSP) || needed (can be set to 0x00000...) || 0x00000000000000000000000000000000 || 0x0123456789ABCDEF0123456789ABCDEF
|-
|-
| When 0x40 is not set (default) || NoRenameDirectory || ||
| DRMType || needed || Network / Free / Local || Free
|-
|-
| 0x80 || ?EDAT? || || Theme (.p3t.edat) / License package (.edat)
| ContentType || needed || See [[PKG_files#ContentType]] || minis
|-
|-
| 0x200 || ?Emulator? || || All PS1 and PSP packages, minis.
| PackageType || || See [[PKG_files#PackageType]] || DiscGamePatch
|-
|-
| 0x400 || VSH Module || || PS3 only.
| PackageFlag || || See [[PKG_files#PackageFlag]] || RenameDirectory
|-
|-
| 0x800 || DiscBinded || || PS3 only.
| StorageType || needed for PSVita gamedata || See [[PKG_files#StorageType]] || VC-MC
|-
|-
| 0x1000 || ? || ||  
| PackageVersion || needed || XX.XX || 01.02
|-
|-
| 0x2000 || See Storage Type. || ||  
| TitleID || used only for PSP and PS1 games || XXXXYYYYY || NPEZ00314
|-
|-
| 0x4000 || NonGame || Used for most PS Vita NPDRM apps ||
| LimitedTimeStart || || YYYY-MM-DDThh:mmTZD || 2018-10-30T11:55T32
|}
|-
 
| LimitedTimeEnd || || YYYY-MM-DDThh:mmTZD || 2019-10-30T11:55T32
=== StorageType ===
 
It seems to be PS Vita only.
 
{| class="wikitable"
! Flag !! Name !! Usage !! Notes
|-
|-
| 8 / 4 / 2 || MC || This application can be distributed by network and installed onto memory card(MC). ||  
| InstallDirectory || used in PSP patches ?and DLCs? || ? || UCUS98744_LBPPDLCSONYPA002
|-
|-
| 0x2000 || VC || This application can be distributed by PS Vita card(VC). ||
| ForcedInstallTo || Allows installing packages to any hdd directory (and even flash memory if it's mounted RW). ||  ||
|}
|}


=== sfo_info ===
=== PARAM_SFO_info ===
Only seen in PSV packages.


   typedef struct { // size is 0x38
   typedef struct { // size is 0x38
     u32 param_offset;
     u32 param_offset;
     u16 param_size;
     u16 param_size;
     u32 unk_int; // seen values: 0x00000001-0x00000018, 0x0000001b-0x0000001c
     u32 unk_int; // ex: 0x2, 0x14, 0x4, 0x9
     u32 PSP2_SYSTEM_VER; // BCD encoded
     u32 PSP2_DISP_VER; // or may be PSP2_SYSTEM_VER
     u8 unk[0x8];
     u8 unk[0x8];
     u8 param_digest[0x20]; // SHA256 of param_data. Called ParamDigest: This is sha256 digest of param.sfo.
     u8 param_digest[0x20]; // SHA256 of param_data. Called ParamDigest: This is sha256 digest of param.sfo.
   } sfo_info;
   } PARAM_SFO_info;


=== unknown_data_info ===
=== unknown_data0_info ===


   typedef struct { // size is 0x48
   typedef struct { // size is 0x48
Line 470: Line 326:
     u8 unk[0x20];
     u8 unk[0x20];
     u8 unknown_data_sha256[0x20];
     u8 unknown_data_sha256[0x20];
   } unknown_data_info;
   } unknown_data0_info;


=== entirety_info ===
=== entirety_info ===


<source lang="C">
   typedef struct { // size is 0x38
   typedef struct { // size is 0x38
     u32 entirety_data_offset; // located just before SFO
     u32 entirety_data_offset; // located just before SFO
     u32 entirety_data_size; // ex: 0xA0, C0, 0x100, 0x120, 0x160
     u32 entirety_data_size; // ex: 0xA0, 0x100, 0x160
     u16 flags; // ex: EE 00, FE 10, FE 78, FE F8, FF 10, FF 90, FF D0, flags indicating which digests it embeds
     u32 unk_int1; // ex: FE 10 00 00, FF D0 00 00, FE 78 00 00 (patch), certainly a flag indicating which digests it embeds
    u16 unk; // always 00 00
     u32 unk_int2; // ex: 1, 0
     u32 unk2_int; // ex: 1, 0
     u8 unk[0x8];
     u8 unk3[0x8];
     u8 entirety_digest[0x20]; // SHA256 of entirety_data. Called EntiretyDigest: This is a digest of above digests.
     u8 entirety_digest[0x20];
   } entirety_info;
   } entirety_info;
</source>
==== Digests table ====
{| class="wikitable"
! Official Name !! Official Description !! Description !! Flags
|-
| EntiretyDigest || This is a digest of above digests. || SHA256 of entirety_data. ||
|-
| ContentDigest || This is a digest of content unique value. || May be located at offset 0x0 under encrypted form... ||
|-
| GameDigest || This is a digest of Header/Program/System/MajorParam Digests. || SHA256 of a buffer embedding Program/System/MajorParam/Header Digests in this order. ||
|-
| ProgramDigest || This is a digest of contents except sce_sys files. ||  ||
|-
| SystemDigest || This is a digest of sce_sys files except param.sfo. ||  ||
|-
| MajorParamDigest || This is a digest of param.sfo that affect behavior. ||  ||
|-
| ParamDigest || This is sha256 digest of param.sfo. || SHA256 of param.sfo. ||
|-
| HeaderDigest || This is a digest of package header. ||  ||
|-
| LiveareaDigest || This is a digest of sce_sys/livearea(&retail) files. ||  ||
|-
| ManualDigest || This is a digest of sce_sys/manual files. ||  ||
|-
| TrophyDigest || This is a digest of sce_sys/trophy files. ||  ||
|-
| ChangeInfoDigest || This is a digest of sce_sys/changeinfo files. ||  ||
|-
| OthersDigest || This is a digest of sce_sys files except above files. ||  ||
|-
| OriginDigest || This is the ContentDigest of base game package. ||  ||
|-
| TargetDigest || This is the ContentDigest of previous patch package. ||  ||
|-
| OriginGameDigest || This is the GameDigest of base game package. ||  ||
|-
| TargetGameDigest || This is the GameDigest of previous patch package. ||  ||
|}
==== entirety_data possible structures ====
<source lang="C">
  typedef struct { // size is 0xA0
    u8 enc_content_digest[0x20];
    u8 game_digest[0x20];
    u8 system_digest[0x20];
    u8 header_digest[0x20];
    u8 livearea_digest[0x20]; // ?SHA256? of ??
  } entirety_data_A0_NOPARAM_LA_D300; // 1101 0011 0000 0000 -> 5
  typedef struct { // size is 0xC0
    u8 enc_content_digest[0x20];
    u8 game_digest[0x20];
    u8 program_digest[0x20];
    u8 system_digest[0x20];
    u8 major_param_digest[0x20];
    u8 param_digest[0x20];
    u8 header_digest[0x20];
  } entirety_data_C0_EE00; // 1110 1110 0000 0000 -> 6


   typedef struct { // size is 0x100
   typedef struct { // size is 0x100
     u8 enc_content_digest[0x20];
     u8 unk_digest[0x20]; // ????
    u8 game_digest[0x20];
     u8 game_digest[0x20]; // ?SHA256? of ??. Called GameDigest: This is a digest of Header/Program/System/MajorParam Digests.
    u8 program_digest[0x20];
     u8 program_digest[0x20]; // ?SHA256? of ??. Called ProgramDigest: This is a digest of contents except sce_sys files.
    u8 system_digest[0x20];
     u8 system_digest[0x20]; // ?SHA256? of ??. Called SystemDigest: This is a digest of sce_sys files except param.sfo.
    u8 major_param_digest[0x20];
     u8 majorparam_digest[0x20]; // ?SHA256? of ??. Called MajorParamDigest: This is a digest of param.sfo that affect behavior.
    u8 param_digest[0x20];
     u8 param_digest[0x20]; // SHA256 of param.sfo. Called ParamDigest: This is sha256 digest of param.sfo.
    u8 header_digest[0x20];
     u8 header_digest[0x20]; // ?SHA256? of ??. Called HeaderDigest: This is a digest of package header.
    u8 others_digest[0x20]; // ?SHA256? of ??
     u8 others_digest[0x20]; // ?SHA256? of ??. Called OthersDigest: This is a digest of sce_sys files except above files.
  } entirety_data_100_OTH_FE10; // 1111 1110 0001 0000 -> 8
   } entirety_data_100;
 
  typedef struct { // size is 0x120
    u8 enc_content_digest[0x20];
     u8 game_digest[0x20];
    u8 program_digest[0x20];
    u8 system_digest[0x20];
    u8 major_param_digest[0x20];
    u8 param_digest[0x20];
    u8 header_digest[0x20];
    u8 livearea_digest[0x20]; // ?SHA256? of ??
    u8 others_digest[0x20]; // ?SHA256? of ??
  } entirety_data_120_LA_OTH_FF10; // 1111 1111 0001 0000 -> 9
 
  typedef struct { // size is 0x140
    u8 enc_content_digest[0x20];
    u8 game_digest[0x20];
     u8 program_digest[0x20];
    u8 system_digest[0x20];
    u8 major_param_digest[0x20];
    u8 param_digest[0x20];
    u8 header_digest[0x20];
    u8 change_info_digest[0x20]; // ?SHA256? of ??
     u8 others_digest[0x20]; // ?SHA256? of ??
     u8 enc_origin_digest[0x20]; // ?SHA256? of ??. ENCRYPTED FORM !!
  } entirety_data_140_CHG_OTH_ORI_FE38; // 1111 1110 0011 1000 -> 10
 
  typedef struct { // size is 0x140
    u8 enc_content_digest[0x20];
    u8 game_digest[0x20];
    u8 program_digest[0x20];
    u8 system_digest[0x20];
    u8 major_param_digest[0x20];
     u8 param_digest[0x20];
    u8 header_digest[0x20];
    u8 livearea_digest[0x20]; // ?SHA256? of ??
     u8 manual_digest[0x20]; // ?SHA256? of ??
     u8 others_digest[0x20]; // ?SHA256? of ??
   } entirety_data_140_LA_MAN_OTH_FF90; // 1111 1110 1001 0000 -> 9


   typedef struct { // size is 0x160
   typedef struct { // size is 0x160
     u8 enc_content_digest[0x20];
     u8 unk_digest[0x20]; // ???? May be an encrypted form of the not found: # ContentDigest: This is a digest of content unique value.
     u8 game_digest[0x20];
     u8 game_digest[0x20]; // SHA256 of a buffer embedding Program/System/MajorParam/Header Digests in this order. Called GameDigest: This is a digest of Header/Program/System/MajorParam Digests.
     u8 program_digest[0x20];
     u8 program_digest[0x20]; // ?SHA256? of ??. Called ProgramDigest: This is a digest of contents except sce_sys files.
     u8 system_digest[0x20];
     u8 system_digest[0x20]; // ?SHA256? of ??. Called SystemDigest: This is a digest of sce_sys files except param.sfo.
     u8 major_param_digest[0x20];
     u8 majorparam_digest[0x20]; // ?SHA256? of ??. Called MajorParamDigest: This is a digest of param.sfo that affect behavior.
     u8 param_digest[0x20];
     u8 param_digest[0x20]; // SHA256 of param.sfo. Called ParamDigest: This is sha256 digest of param.sfo.
     u8 header_digest[0x20];
     u8 header_digest[0x20]; // ?SHA256? of ??. Called HeaderDigest: This is a digest of package header.
     u8 livearea_digest[0x20]; // ?SHA256? of ??
     u8 livearea_digest[0x20]; // ?SHA256? of ??. Called LiveareaDigest: This is a digest of sce_sys/livearea(&retail) files.
     u8 manual_digest[0x20]; // ?SHA256? of ??
     u8 manual_digest[0x20]; // ?SHA256? of ??. Called ManualDigest: This is a digest of sce_sys/manual files.
     u8 trophy_digest[0x20]; // ?SHA256? of ??
     u8 trophy_digest[0x20]; // ?SHA256? of ??. Called TrophyDigest: This is a digest of sce_sys/trophy files.
     u8 others_digest[0x20]; // ?SHA256? of ??
     u8 others_digest[0x20]; // ?SHA256? of ??. Called OthersDigest: This is a digest of sce_sys files except above files.
   } entirety_data_160_LA_MAN_TRP_OTH_FFD0; // 1111 1111 1101 0000 -> 11
   } entirety_data_160;


   typedef struct { // size is 0x160
   typedef struct { // size is 0x160
     u8 enc_content_digest[0x20];
     u8 unk_digest[0x20]; // ???? May be an encrypted form of the not found: # ContentDigest: This is a digest of content unique value.
     u8 game_digest[0x20];
     u8 game_digest[0x20]; // SHA256 of a buffer embedding Program/System/MajorParam/Header Digests in this order. Called GameDigest: This is a digest of Header/Program/System/MajorParam Digests.
     u8 program_digest[0x20];
     u8 program_digest[0x20]; // ?SHA256? of ??. Called ProgramDigest: This is a digest of contents except sce_sys files.
    u8 system_digest[0x20];
     u8 system_digest[0x20]; // ?SHA256? of ??. Called SystemDigest: This is a digest of sce_sys files except param.sfo.
    u8 major_param_digest[0x20];
     u8 majorparam_digest[0x20]; // ?SHA256? of ??. Called MajorParamDigest: This is a digest of param.sfo that affect behavior.
    u8 param_digest[0x20];
     u8 param_digest[0x20]; // SHA256 of param.sfo. Called ParamDigest: This is sha256 digest of param.sfo.
    u8 header_digest[0x20];
     u8 header_digest[0x20]; // ?SHA256? of ??. Called HeaderDigest: This is a digest of package header.
    u8 trophy_digest[0x20]; // ?SHA256? of ??
     u8 livearea_digest[0x20]; // ?SHA256? of ??. Called LiveareaDigest: This is a digest of sce_sys/livearea(&retail) files.
     u8 change_info_digest[0x20]; // ?SHA256? of ??
     u8 manual_digest[0x20]; // ?SHA256? of ??. Called ManualDigest: This is a digest of sce_sys/manual files.
     u8 others_digest[0x20]; // ?SHA256? of ??
     u8 trophy_digest[0x20]; // ?SHA256? of ??. Called TrophyDigest: This is a digest of sce_sys/trophy files.
     u8 enc_origin_digest[0x20]; // ?SHA256? of ??. ENCRYPTED FORM !!
     u8 others_digest[0x20]; // ?SHA256? of ??. Called OthersDigest: This is a digest of sce_sys files except above files.
  } entirety_data_160_TRP_CHG_OTH_ORI_FE78; // 1111 1110 0111 1000 -> 11
   } entirety_data_160_patch;
 
  typedef struct { // size is 0x180
    u8 enc_content_digest[0x20];
    u8 game_digest[0x20];
    u8 program_digest[0x20];
    u8 system_digest[0x20];
    u8 major_param_digest[0x20];
    u8 param_digest[0x20];
     u8 header_digest[0x20];
    u8 manual_digest[0x20]; // ?SHA256? of ??
     u8 trophy_digest[0x20]; // ?SHA256? of ??
     u8 change_info_digest[0x20]; // ?SHA256? of ??
     u8 others_digest[0x20]; // ?SHA256? of ??
     u8 enc_origin_digest[0x20]; // ?SHA256? of ??. ENCRYPTED FORM !!
   } entirety_data_180_MAN_TRP_CHG_OTH_ORI_FEF8; // 1111 1110 1111 1000 -> 12
</source>
 
==== Entirety digests bitflags table ====
 
<source lang="text">
1000 0000 0000 0000 : Content
0100 0000 0000 0000 : Game
0010 0000 0000 0000 : Program
0001 0000 0000 0000 : System
 
0000 1000 0000 0000 : MajorParam
0000 0100 0000 0000 : Param
0000 0010 0000 0000 : Header
0000 0001 0000 0000 : LiveArea
 
0000 0000 1000 0000 : Manual
0000 0000 0100 0000 : Trophy
0000 0000 0010 0000 : ChangeInfo
0000 0000 0001 0000 : Others
 
0000 0000 0000 1000 : Origin
0000 0000 0000 0100 : unk1
0000 0000 0000 0010 : unk2
0000 0000 0000 0001 : unk3
 
MISSING : OriginGameDigest, TargetDigest, TargetGameDigest
</source>


=== self_info ===
=== unknown_data2_info ===


<source lang="C">
   typedef struct { // size is 0x38
   typedef struct { // size is 0x38
     u32 self_info_offset; // offset to the first self_info_data_element
     u32 unknown_data_offset;
     u32 self_info_size; // usually 0x10 or 0x20
     u32 unknown_data_size; // usually 0x10
    u32 unk_int; // ex: 00 00 00 43
     u8 unk[0x10];
     u8 unk[0x10];
     u8 self_sha256[0x20];
     u8 unknown_data_sha256[0x20];
   } self_info;
   } unknown_data2_info;
 
  typedef struct { // size is 0x10
    u64 unk; // ex: 00 00 00 00 00 00 00 01, 80 00 00 00 00 00 00 00
    u64 authid; // warning: big endian
  } self_info_data_element;
</source>


== File Body ==
=== File Entry ===
 
=== PKG Item Record ===


All values are in big endian format.
All values are in big endian format.
Line 696: Line 398:
     u32 flags;
     u32 flags;
     u32 padding;
     u32 padding;
   } PKG_ITEM_RECORD;
   } PKG_FILE_HEADER;


{| class="wikitable"
{| class="wikitable"
Line 709: Line 411:
| data_size || 0x10 || u64 ||
| data_size || 0x10 || u64 ||
|-
|-
| flags || 0x18 || u32 || The file type. Item_key_type = (flags >> 0x1C)&7 (key type 0 - ps3-aes-key, key type 1 - psp-aes-key)
| flags || 0x18 || u32 || The file type
|-
|-
| padding || 0x1C || u32 || zero
| padding || 0x1C || u32 || zero
|}
|}
=== Misc/Note ===
<s>
From FW 4.00, install PKG from root device (but not as "bubble") for PS1 classic if not containing [[EDAT_files|.EDAT files]] license type Free will abort or install directly as bubble according to the cfw.
</s>


== File Footer ==
== File Footer ==
Line 718: Line 426:
=== PackageDigest ===
=== PackageDigest ===


Official description: This is SHA1 digest of package without last 32 bytes.
This is SHA1 digest of package without last 32 bytes.


The last 32 bytes of the package contain a hash (sha1sum) of the package (sha1 of the whole file minus the last 32 bytes). Or in other words... to verify the integrity of a package it is needed to crop the 0x20 bytes at the end, then calculate the SHA1 of the resulting file, then compare with the SHA1 that was cropped.
The last 0x20 bytes of the package contains a hash (sha1sum) of the package (sha1 of the whole file minus the last 0x20 bytes). Or in other words... to verify the integrity of a package is needed to crop the 0x20 bytes at the end, then calculate the SHA1 of the resulting file, then compare with the SHA1 that was cropped.


It is also used as part of the package identification info inside the '''TITLE_ID-ver.xml''' files in PSN servers that lists the available game patches for each game. See: [[Online_Connections#Game_Updating_Procedure|Game Updating Procedure]] page and the '''sha1sum''' in the .xml examples
It is also used as part of the package identification info inside the '''TITLE_ID-ver.xml''' files in PSN servers that lists the available game patches for each game. See: [[Online_Connections#Game_Updating_Procedure|Game Updating Procedure]] page and the '''sha1sum''' in the .xml examples


*Notes
*Notes
**This footer area is considered part of the package and is included when counting the '''total_size''' of the package (in the header at offset 0x18), and the header is hashed too by '''header_sha1_hash ''' (at offset 0xB8), this is important in the sequence of actions needed when building the package and updating/adding the PackageDigest.
**This footer area is considered part of the package and is included when counting the '''total_size''' of the package (in the header at offset 0x18), and the header is hashed too by '''header_sha1_hash ''' (at offset 0xB8), this is important in the sequence of actions needed when building the package and updating/adding the sha1 footer at the end
**PS3 homebrew packages (at least some of them) doesnt includes PackageDigest
**Homebrew packages (at least some of them) doesnt includes this footer


== Package Tools ==
== Package Tools ==
Line 732: Line 440:
=== PKG builder / infos / extractor ===
=== PKG builder / infos / extractor ===


==== package.conf (PSP/PS3/PS Vita) ====
==== PSP SDK official tool : make_package_npdrm (2006-2014) ====
 
Note that for convenience and backward compatibility with NPDRM.CONF, the package.conf parser (make_package_npdrm) is not case-sensitive and in some cases considers underscore as dash.
 
{| class="wikitable"
! Configuration name !! Usage !! Expected value !! Example !! Notes
|-
| ContentID || needed || XXYYYY-XXXXYYYYY_00-XXXXXXXXXXXXXXXX || EP4153-NPEZ00314_00-0000111122223333 ||
|-
| Klicensee || needed on PS3 (can be set to 0x00000...) || 0x00000000000000000000000000000000 || 0x0123456789ABCDEF0123456789ABCDEF ||
|-
| DRMType || needed || Network / Free / Local / DiscBind || Free ||
|-
| ContentType || needed || See [[PKG_files#ContentType]] || minis ||
|-
| PackageVersion || needed || xx.yy || 01.02 ||
|-
| PackageType || || See [[PKG_files#PackageType]] || DiscGamePatch ||
|-
| PackageFlag || || See [[PKG_files#PackageFlag]] || RenameDirectory ||
|-
| StorageType || needed for PS Vita gamedata || See [[PKG_files#StorageType]] || VC-MC ||
|-
| TitleID || used only for PSP and PS1 games || XXXXYYYYY || NPEZ00314 ||
|-
| LimitedTimeStart || || YYYY-MM-DDThh:mmTZD || 2018-10-30T11:55T32 ||
|-
| LimitedTimeEnd || || YYYY-MM-DDThh:mmTZD || 2019-10-30T11:55T32 ||
|-
| InstallDirectory || used in PSP patches ?and DLCs? || ? || UCUS98744_LBPPDLCSONYPA002 ||
|-
| ForcedInstallTo || Allows installing packages to any HDD directory (and even flash memory if it is mounted RW). ||  || ||
|-
| APP_VER || If the APP_VER value in PARAM.SFO is to be updated, set the new value in the format "xx.yy" (2 integer digits and 2 decimal digits). ||  || ||
|-
| PS3_SYSTEM_VER || If the PS3_SYSTEM_VER value in PARAM.SFO is to be updated with a patch package, set the new value in the format "xx.yyyy" (2 integer digits and 4 decimal digits). ||  || ||
|}
 
==== NPDRM.CONF (PSP) ====
 
{| class="wikitable"
! Configuration name !! Usage !! Expected value !! Example !! Notes
|-
| Content-ID || needed || XXYYYY-XXXXYYYYY_00-XXXXXXXXXXXXXXXX || EP4153-NPEZ00314_00-0000111122223333 ||
|-
| K-Licensee || needed (can be set to 0x00000...) || 0x00000000000000000000000000000000 || 0x0123456789ABCDEF0123456789ABCDEF ||
|-
| PackageVersion || needed || XX.XX || 01.02 ||
|-
| ProtectDocument || used in PSP Downloadable Game Package (PSP .pkg)
Game Manual Protection
To use NPDRM to protect the game manual, include the line "ProtectDocument = TRUE" in
the configuration file. Like the downloadable game itself, once protected, the relevant game
manual can only be browsed on a PSP™ that was authenticated with the user account used
to purchase the downloadable game package. If "ProtectDocument = FALSE" is specified or
if no specification is made, the game manual will not be protected by NPDRM.
|| FALSE/TRUE || FALSE ||
|-
| [[PKG_files#HealthWarning|HealthWarning]] || used in PSP Downloadable Game Package (PSP .pkg)
Startup Warning
You can specify that a startup warning be displayed when the game is started up. Specify
"HealthWarning = " followed by the specification word shown in the following table, which
indicates the region or language where the downloadable game package will be released.
See Chapter 7 for the corresponding text that is displayed.
If "HealthWarning = NONE" is specified or if no specification is made, no startup warning
will be displayed.
|| NONE/[[PKG_files#HealthWarning|specification word]] || NONE ||
|-
| ZIPThreshold || used in PSP Downloadable Game Package (PSP .pkg)
Compression Rate Specification
During authoring of a downloadable game package, the data in the associated UMD™
image file is compressed. You can change the compression rate by specifying
"ZIPThreshold=" followed by the compression rate (0 to 100). If there is no "ZIPThreshold="
specification, the compression rate will default to 80. If "ZIPThreshold=0" is specified, the
data will not be compressed and there will no longer be any load for expanding the
compressed data. However, the file size will increase and it will take longer for the user to
download the package. Unless you specifically need to change the compression rate, do not
include this specification.
|| 0 to 100 || 80 ||
|-
| OptimizeLevel || used in PSP Downloadable Game Package (PSP .pkg)
The SCE authoring service may change the optimization level to improve processing
performance when the system reads data in a downloadable game. If this change hinders
the behavior of a program that is being developed, you can include the specification
"OptimizeLevel=" followed by the optimization level that was used previously during
authoring. If there is no impediment to program behavior, you should not enter this
specification.
When the authoring service changes, refer to details that are publically available in the
Technical Notes.
|| ?0 to 100? || ?80? ||
|-
| BootablePlatform || used in PSP minis Package (PSP minis .pkg)
When creating a package for minis, in addition to the necessary parameters for downloadable
games, "BootablePlatform = minis" must be set in NPDRM.CONF that is a configuration file
for packaging.
|| minis || minis ||
|-
| BootablePlatformDetails || used in PSP minis Package (PSP minis .pkg)
Game applications created via the Simple Authoring Service(SAS) having the above parameter
specified can be executed on PlayStation®3. When it is required to prohibit a minis game
application from running on the PlayStation®3 execution environment explicitly, set
"BootablePlatformDetails=onlyPSP" to NPDRM.CONF in addition to the setting
"BootablePlatform = minis".
|| onlyPSP || onlyPSP ||
|}
 
==== PSP SDK official tool: make_package_npdrm (2006-2014) ====
 
* latest version: rev 1642 in 6.60 PSP SDK
 
==== PS3 SDK official tool: make_package_npdrm (2006-2014) ====
 
* oldest known version: rev 1061 in ?.?? PS3 SDK
* rev 1203 in 1.92 PS3 SDK
* rev 1588 in 3.00 PS3 SDK
* most famous version: rev 1732 in 3.40 PS3 SDK (also found under unofficial patched form)
* rev 1754 in 3.60 PS3 SDK
* rev 1962 in 4.00 PS3 SDK
* rev 1966 in 4.?? PS3 SDK (seen in TrueAncestor tools)
* latest version: rev 1972 in 4.75 PS3 SDK
 
<pre>
make_package_npdrm.exe --informal-help
 
usage: [revision 1972]
 
    THIS IS INFORMAL HELP. ONLY FOR INTERNAL USE! NEVER USE FOR RELEASING!
 
    make_package_npdrm [options] config-file target-directory
        -v | --verbose          increases verbose messages.
        -f | --nofindlimit      no limitation to file find.
        -o | --output DIR      output package to DIR.
        -C | --directory DIR    change to DIR before doing anything.
        --find-path PATH        set find command path to file find.
        --content-id STRING    set ContentID.
        --k-licensee HEX        set KLicensee.
        --drm-type STRING      set DRMType.
        --content-type STRING  set ContentType.
        --package-version NUM  set PackageVersion.
        --patch-for-discgame    generate patch package for DiscGame.
        --patch-for-hddgame    generate patch package for HDDGame.
        --patch-for-psstore    generate patch package for PSSTORE (pay patch).
        --force-info            overwrite content information files.
        --weak-info            no overwrite content information files.
        --force-user            overwrite user directory files.
        --weak-user            no overwrite user directory files.
 
    make_package_npdrm [options] target-directory
        generate package with 'target-directory/package.conf'.
        [options]              same as the above.
 
    make_package_npdrm [options] npdrm-package [target]
        [default]              print package informations.
        -c | --check            check package format.
        -l | --list            print [target] files/dirs information.
        -x | --extract          extract [target] files/dirs.
        --extract-tropdir      extract trophy files.
        --extract-rootdir      extract system files.
        --no-entitlement        generate debuging package.
 
    make_package_npdrm [options]
        --version              print revision.
        --help                  print help message.
        --informal-help        print this message.
</pre>
 
==== PS Vita SDK official tool: make_package_npdrm.exe (2011) ====


* oldest known version: make_package_npdrm.exe rev 1840 (2011-04-05) from PublishingTools version 0.16.0.283 in ?0.945? PS Vita SDK.
* latest version: rev 1642 from 6.60 PSP SDK
* make_package_npdrm.exe rev 1949 (2011-07-22) from PublishingTools version 0.50.0.585 in 0.996 PS Vita SDK.
* make_package_npdrm.exe rev 1957 (2011-09-14) from PublishingTools version 1.41.0.958 in ?1.00? PS Vita SDK.
* make_package_npdrm.exe rev 1962 (2011-12-02) from PublishingTools version 1.41.0.958 in ?1.50? PS Vita SDK.
* make_package_npdrm.exe rev 1963 (2011-12-26) from PublishingTools version 1.50.0.1026 in ?1.60? PS Vita SDK.


==== PS Vita SDK official tool: make_pkg.exe (2014) ====
==== PSVita SDK official tool : make_pkg (2011-2015) ====


At some point, SCE renamed make_package_npdrm to make_pkg. The reason is certainly that on PS Vita, .pkg are used for many types of contents not just NPDRM protected contents.
* latest version: rev 1972 from 3.55 PSVita SDK


* latest version: make_pkg.exe rev 1972 (2014-06-29) from PublishingTools version 2.31.0.1669 in 3.55/3.57 PS Vita SDK.
==== PS3 SDK official tool : make_package_npdrm (2006-2017) ====


<pre>
* latest version: rev 1972 from 4.75 PS3 SDK
make_pkg.exe --help
* common version: rev 1732 from 3.40 PS3 SDK (also found under patched form)
 
* oldest leaked version: rev 1061 from X.XX PS3 SDK
usage: [revision 1972]
 
    make_package_npdrm [options] config-file target-directory
        -v | --verbose          increases verbose messages.
        -f | --nofindlimit      no limitation to file find.
        -o | --output DIR      output package to DIR.
        -C | --directory DIR    change to DIR before doing anything.
        --find-path PATH        set find command path to file find.
        --content-id STRING    set ContentID.
        --k-licensee HEX        set KLicensee.
        --drm-type STRING      set DRMType.
        --content-type STRING  set ContentType.
        --package-version NUM  set PackageVersion.
</pre>


==== Make Package Npdrm Patcher (revision 1732) by SubZero Dezigns (2012) ====
==== Make Package Npdrm Patcher (revision 1732) by SubZero Dezigns (2012) ====
Line 1,022: Line 546:
==== PkgDecrypt by St4rk (2017) ====
==== PkgDecrypt by St4rk (2017) ====


PS Vita .pkg
PSVita .pkg
 
[https://github.com/st4rk/PkgDecrypt Source code]
 
==== PKGrip by qwikrazor87 (2018) ====
 
Fast linux alternative for decrypting PS3/PSP NPDRM PKG files.
 
[https://github.com/qwikrazor87/pkgrip Source code]
 
==== PSN_get_pkg_info.py by windsurfer1122 (2018-2020) ====
 
Extracts information from package file as text or JSON for further analysis.<br />
Provides Linux shell scripts for mass creation of analysis data and to quickly grep through them.<br />
Analysis data of 10.000+ packages already directly downloadable [https://mega.nz/#F!cyxSVACA!Lp8VFpFz4K-DQLb221d83A here].<br />
Decrypts package to an unencrypted raw package.<br />
Planned feature is package extraction like PkgDecrypt and pkg2zip.
 
PS3/PS1/PSP/PSV/PSM .pkg
 
[https://github.com/windsurfer1122/PSN_get_pkg_info Source code]
 
==== LibOrbisPkg by Maxton ====
 
PS4 Tool but could help to understand PFS.
 
[https://github.com/maxton/LibOrbisPkg Source code]
 
==== PS4 PFS Tool by flatz (2020) ====
 
PS4 Tool but could help to understand PFS.
 
[https://github.com/flatz/pkg_pfs_tool Source code]


== Package links ==
== Package links ==
* sqlite3 db of .pkg files (pkg links, file infos, signatures, etc): [https://mega.co.nz/#!f5QhWCTB!EzxEaMNKJ3zJ40c_qfGtZTVD3a1uis645Hffj_W3hpc pkg_harvester_db.7z 6.7 MB] (includes PS3, PSP) - uncompressed pkg_harvester.db: 24.5 MB


=== links by Hackinformer ===
several constants used in pkg_harvester.db:  
 
https://hackinformer.com/PlayStationGuide/misc/zeuslinks.txt
 
=== pkgharvester ===
 
* sqlite3 db of .pkg files (pkg links, file infos, signatures, etc):
 
[https://mega.co.nz/#!f5QhWCTB!EzxEaMNKJ3zJ40c_qfGtZTVD3a1uis645Hffj_W3hpc pkg_harvester_db.7z 6.7 MB] (includes PS3, PSP)
 
uncompressed pkg_harvester.db size: 24.5 MB
 
several constants used in pkg_harvester.db:
 
<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
enum class ProductEnvironment
enum class ProductEnvironment
Line 1,106: Line 586:
};
};
</syntaxhighlight>
</syntaxhighlight>




{{File Formats}}<noinclude>[[Category:Main]]</noinclude>
{{File Formats}}<noinclude>[[Category:Main]]</noinclude>
Please note that all contributions to PS3 Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see PS3 Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)