Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions hdk-firmware/src/pkg/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,34 @@ impl<R: Read + Seek> PkgArchive<R> {
return Err(PkgError::DataOutOfBounds);
}

// ---- metadata section (TLV packets) ----
let mut metadata = PkgMetadata {
packets: Vec::new(),
};
if metadata_offset > 0 && metadata_count > 0 {
let is_legacy_debug = release_type & 0x8000 == 0
&& metadata_offset == 0xC0
&& metadata_size == 0x80
&& data_offset == 0x140;

if is_legacy_debug {
inner.seek(SeekFrom::Start(metadata_offset as u64))?;
let mut fixed = [0u8; 0x40];
inner.read_exact(&mut fixed)?;

let packet = |id, range: std::ops::Range<usize>| PkgMetadataPacket {
id,
data: fixed[range].to_vec(),
};
metadata.packets.extend([
packet(metadata_id::DRM_TYPE, 0x08..0x0C),
packet(metadata_id::CONTENT_TYPE, 0x14..0x18),
packet(metadata_id::PACKAGE_TYPE, 0x20..0x24),
PkgMetadataPacket {
id: metadata_id::PACKAGE_SIZE,
data: total_size.to_be_bytes().to_vec(),
},
packet(metadata_id::MAKE_PKG_REV, 0x3C..0x40),
]);
} else if metadata_offset > 0 && metadata_count > 0 {
inner.seek(SeekFrom::Start(metadata_offset as u64))?;
for _ in 0..metadata_count {
let id = inner.read_u32::<BigEndian>()?;
Expand Down
16 changes: 8 additions & 8 deletions hdk-firmware/src/pkg/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
//!
//! A PS3 `.pkg` file has the following high-level layout:
//!
//! | Region | Offset | Notes |
//! |------------------|-----------------|------------------------------------|
//! | Main header | `0x00`–`0xBF` | Always plaintext |
//! | Metadata (TLV) | `0xC0`–variable | Always plaintext, id/size/payload |
//! | File entry table | `data_offset` | Encrypted for retail, plain debug |
//! | File names | (relative) | Encrypted for retail, plain debug |
//! | File data | (relative) | Encrypted for retail, plain debug |
//! | Region | Offset | Notes |
//! |------------------|-----------------|--------------------------------------------|
//! | Main header | `0x00`–`0xBF` | Header plus mode-specific authentication |
//! | Metadata | `0xC0`–variable | Fixed record for debug, TLV for retail |
//! | File entry table | `data_offset` | SHA-1 stream (debug) or AES-CTR (retail) |
//! | File names | (relative) | Encrypted with the selected package mode |
//! | File data | (relative) | Encrypted with the selected package mode |

use core::fmt;

Expand Down Expand Up @@ -232,7 +232,7 @@ impl TryFrom<u32> for PkgEntryType {
/// 0x30 [u8;48] content_id (null-padded ASCII)
/// 0x60 [u8;16] qa_digest (SHA-1 key material for debug crypto)
/// 0x70 [u8;16] klicensee (AES-CTR initial counter)
/// 0x80 [u8;64] header_digest
/// 0x80 [u8;64] mode-specific header authentication
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PkgHeader {
Expand Down
Loading
Loading