Crypto: PSVita metadata and missing entry type

This commit is contained in:
Megamouse 2020-04-18 17:30:37 +02:00
parent 22d01e4d05
commit d35a29bbe4
2 changed files with 214 additions and 20 deletions

View File

@ -308,7 +308,16 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
}
case 0x7:
{
// QA Digest (24 bytes)
if (packet.size == sizeof(metadata.qa_digest))
{
archive_read(&metadata.qa_digest, sizeof(metadata.qa_digest));
pkg_log.notice("Metadata: QA Digest = 0x%x", metadata.qa_digest);
continue;
}
else
{
pkg_log.error("Metadata: QA Digest size mismatch (0x%x)", packet.size);
}
break;
}
case 0x8:
@ -328,7 +337,16 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
}
case 0x9:
{
// Unknown (8 bytes)
if (packet.size == sizeof(metadata.unk_0x9))
{
archive_read(&metadata.unk_0x9, sizeof(metadata.unk_0x9));
pkg_log.notice("Metadata: unk_0x9 = 0x%x = %d", metadata.unk_0x9, metadata.unk_0x9);
continue;
}
else
{
pkg_log.error("Metadata: unk_0x9 size mismatch (0x%x)", packet.size);
}
break;
}
case 0xA:
@ -352,7 +370,16 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
}
case 0xB:
{
// Unknown (8 bytes)
if (packet.size == sizeof(metadata.unk_0xB))
{
archive_read(&metadata.unk_0xB, sizeof(metadata.unk_0xB));
pkg_log.notice("Metadata: unk_0xB = 0x%x = %d", metadata.unk_0xB, metadata.unk_0xB);
continue;
}
else
{
pkg_log.error("Metadata: unk_0xB size mismatch (0x%x)", packet.size);
}
break;
}
case 0xC:
@ -360,14 +387,87 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
// Unknown
break;
}
case 0xD:
case 0xE:
case 0xF:
case 0x10:
case 0x11:
case 0x12:
case 0xD: // PSVita stuff
{
// PSVita stuff
if (packet.size == sizeof(metadata.item_info))
{
archive_read(&metadata.item_info, sizeof(metadata.item_info));
pkg_log.notice("Metadata: PSVita item info = %s", metadata.item_info.to_string());
continue;
}
else
{
pkg_log.error("Metadata: Item info size mismatch (0x%x)", packet.size);
}
break;
}
case 0xE: // PSVita stuff
{
if (packet.size == sizeof(metadata.sfo_info))
{
archive_read(&metadata.sfo_info, sizeof(metadata.sfo_info));
pkg_log.notice("Metadata: PSVita sfo info = %s", metadata.sfo_info.to_string());
continue;
}
else
{
pkg_log.error("Metadata: SFO info size mismatch (0x%x)", packet.size);
}
break;
}
case 0xF: // PSVita stuff
{
if (packet.size == sizeof(metadata.unknown_data_info))
{
archive_read(&metadata.unknown_data_info, sizeof(metadata.unknown_data_info));
pkg_log.notice("Metadata: PSVita unknown data info = %s", metadata.unknown_data_info.to_string());
continue;
}
else
{
pkg_log.error("Metadata: unknown data info size mismatch (0x%x)", packet.size);
}
break;
}
case 0x10: // PSVita stuff
{
if (packet.size == sizeof(metadata.entirety_info))
{
archive_read(&metadata.entirety_info, sizeof(metadata.entirety_info));
pkg_log.notice("Metadata: PSVita entirety info = %s", metadata.entirety_info.to_string());
continue;
}
else
{
pkg_log.error("Metadata: Entirety info size mismatch (0x%x)", packet.size);
}
break;
}
case 0x11: // PSVita stuff
{
if (packet.size == sizeof(metadata.version_info))
{
archive_read(&metadata.version_info, sizeof(metadata.version_info));
pkg_log.notice("Metadata: PSVita version info = %s", metadata.version_info.to_string());
continue;
}
else
{
pkg_log.error("Metadata: Version info size mismatch (0x%x)", packet.size);
}
}
case 0x12: // PSVita stuff
{
if (packet.size == sizeof(metadata.self_info))
{
archive_read(&metadata.self_info, sizeof(metadata.self_info));
pkg_log.notice("Metadata: PSVita self info = %s", metadata.self_info.to_string());
continue;
}
else
{
pkg_log.error("Metadata: Self info size mismatch (0x%x)", packet.size);
}
break;
}
default:
@ -521,6 +621,7 @@ bool pkg_install(const std::string& path, atomic_t<double>& sync)
case 0x13:
case 0x15:
case 0x16:
case 0x18:
case 0x19:
{
const bool did_overwrite = fs::is_file(path);

View File

@ -66,7 +66,7 @@ struct PKGExtHeader
be_t<u32> padding1;
be_t<u32> pkg_key_id; // Id of the AES key used for decryption. PSP = 0x1, PSVita = 0xC0000002, PSM = 0xC0000004
be_t<u32> full_header_hmac_offset; // ex: none (old pkg): 0, 0x930
u8 padding2[0x14];
u8 padding2[20];
};
struct PKGEntry
@ -106,14 +106,18 @@ public:
be_t<u32> content_type{ 0 };
be_t<u32> package_type{ 0 };
be_t<u64> package_size{ 0 };
u8 qa_digest[24]{ 0 };
be_t<u64> unk_0x9{ 0 };
be_t<u64> unk_0xB{ 0 };
struct package_revision
{
struct package_revision_data
{
u8 make_package_npdrm_ver[2];
u8 version[2];
} data {};
u8 make_package_npdrm_ver[2]{ 0 };
u8 version[2]{ 0 };
} data{};
std::string make_package_npdrm_ver;
std::string version;
@ -133,11 +137,11 @@ public:
{
struct software_revision_data
{
u8 unk[1];
u8 firmware_version[3];
u8 version[2];
u8 app_version[2];
} data {};
u8 unk[1]{ 0 };
u8 firmware_version[3]{ 0 };
u8 version[2]{ 0 };
u8 app_version[2]{ 0 };
} data{};
std::string unk; // maybe hardware id
std::string firmware_version;
@ -153,12 +157,101 @@ public:
}
std::string to_string()
{
return fmt::format("unk: %s, firmware version: %s, version: %s, app version: %s", unk, firmware_version, version, app_version);
return fmt::format("unk: %s, firmware version: %s, version: %s, app version: %s",
unk, firmware_version, version, app_version);
}
} software_revision;
std::string title_id;
std::string install_dir;
// PSVita stuff
struct vita_item_info // size is 0x28 (40)
{
be_t<u32> offset{ 0 };
be_t<u32> size{ 0 };
u8 sha256[32]{ 0 };
std::string to_string()
{
return fmt::format("offset: 0x%x, size: 0x%x, sha256: 0x%x", offset, size, sha256);
}
} item_info;
struct vita_sfo_info // size is 0x38 (56)
{
be_t<u32> param_offset{ 0 };
be_t<u16> param_size{ 0 };
be_t<u32> unk_1{ 0 }; // seen values: 0x00000001-0x00000018, 0x0000001b-0x0000001c
be_t<u32> psp2_system_ver{ 0 }; // BCD encoded
u8 unk_2[8]{ 0 };
u8 param_digest[32]{ 0 }; // SHA256 of param_data. Called ParamDigest: This is sha256 digest of param.sfo.
std::string to_string()
{
return fmt::format("param_offset: 0x%x, param_size: 0x%x, unk_1: 0x%x, psp2_system_ver: 0x%x, unk_2: 0x%x, param_digest: 0x%x",
param_offset, param_size, unk_1, psp2_system_ver, unk_2, param_digest);
}
} sfo_info;
struct vita_unknown_data_info // size is 0x48 (72)
{
be_t<u32> unknown_data_offset{ 0 };
be_t<u16> unknown_data_size{ 0 }; // ex: 0x320
u8 unk[32]{ 0 };
u8 unknown_data_sha256[32]{ 0 };
std::string to_string()
{
return fmt::format("unknown_data_offset: 0x%x, unknown_data_size: 0x%x, unk: 0x%x, unknown_data_sha256: 0x%x",
unknown_data_offset, unknown_data_size, unk, unknown_data_sha256);
}
} unknown_data_info;
struct vita_entirety_info // size is 0x38 (56)
{
be_t<u32> entirety_data_offset{ 0 }; // located just before SFO
be_t<u32> entirety_data_size{ 0 }; // ex: 0xA0, C0, 0x100, 0x120, 0x160
be_t<u16> flags{ 0 }; // ex: EE 00, FE 10, FE 78, FE F8, FF 10, FF 90, FF D0, flags indicating which digests it embeds
be_t<u16> unk_1{ 0 }; // always 00 00
be_t<u32> unk_2{ 0 }; // ex: 1, 0
u8 unk_3[8]{ 0 };
u8 entirety_digest[32]{ 0 };
std::string to_string()
{
return fmt::format("entirety_data_offset: 0x%x, entirety_data_size: 0x%x, flags: 0x%x, unk_1: 0x%x, unk_2: 0x%x, unk_3: 0x%x, entirety_digest: 0x%x",
entirety_data_offset, entirety_data_size, flags, unk_1, unk_2, unk_3, entirety_digest);
}
} entirety_info;
struct vita_version_info // size is 0x28 (40)
{
be_t<u32> publishing_tools_version{ 0 };
be_t<u32> psf_builder_version{ 0 };
u8 padding[32]{ 0 };
std::string to_string()
{
return fmt::format("publishing_tools_version: 0x%x, psf_builder_version: 0x%x, padding: 0x%x",
publishing_tools_version, psf_builder_version, padding);
}
} version_info;
struct vita_self_info // size is 0x38 (56)
{
be_t<u32> self_info_offset{ 0 }; // offset to the first self_info_data_element
be_t<u32> self_info_size{ 0 }; // usually 0x10 or 0x20
u8 unk[16]{ 0 };
u8 self_sha256[32]{ 0 };
std::string to_string()
{
return fmt::format("self_info_offset: 0x%x, self_info_size: 0x%x, unk: 0x%x, self_sha256: 0x%x",
self_info_offset, self_info_size, unk, self_sha256);
}
} self_info;
};
bool pkg_install(const std::string& path, atomic_t<double>&);