Archive.dat

From PS5 Developer wiki
Jump to navigation Jump to search

The archive.dat file format is used to store PS5 Backup and Restore (BAR) data. The backup/restore system will create an archive.dat file(s) on a USB drive which will contain a backup of your entire HDD. The structure has changed from it's predecessor and all data stored in here is in little endian format.

SIECAF File Structure[edit | edit source]

Structure:

  • Header
  • Repeating Section Meta Blocks
  • Repeating Section Hash Blocks

Header[edit | edit source]

Offset Size Description
0x0 0x8 Magic 0x5349454341460000 SIECAF\0\0
0x8 0x8 Version
0x10 0x8 Unknown (0x1)
0x18 0x8 Unknown (0x1)
0x20 0x10 Encryption IV? Since it was removed in the metadata blocks.
0x30 0x4 Unknown size
0x34 0x4 Unknown size
0x38 0x4 Unknown size
0x3C 0x4 Padding
0x40 0x8 Number of Segments
0x48 0x8 File Offset
0x50 0x8 File Size

Section Meta Block[edit | edit source]

Offset Size Description
0x0 0x8 Section ID
0x8 0x8 Section Start Offset
0x10 0x8 Aligned Section Length
0x18 0x8 Hash Key ID (0x0000000000000003)
0x20 0x8 Encryption Key ID (0x0000000000000001)
0x28 0x10 Encryption IV (null bytes)
0x38 0x8 Unaligned Section Length

Section Hash Block[edit | edit source]

Offset Size Description
0x0 0x8 Section ID
0x8 0x10 Hash (128-bit)
0x18 0x18 Padding

Pseudocode[edit | edit source]

#define ARCHIVE_HEADER_MAGIC 		   0x0000464143454953

#define ARCHIVE_HEADER_SIZE 		   0x58
#define ARCHIVE_SEGMENT_TABLE_SIZE 	   0x40
#define ARCHIVE_SEGMENT_SIGNATURE_SIZE 0x30

#define ARCHIVE_MAGIC_SIZE			   0x08

typedef union caf_header_s {
	struct {
		uint8_t magic[ARCHIVE_MAGIC_SIZE]; // SIECAF
		uint64_t version; // 1
		uint64_t unk1; // 1
		uint64_t unk2; // 1
		uint8_t unk3[0x10];
		uint32_t unk4; // 0x75BF88
		uint32_t unk5; // 0x75BF89
		uint32_t unk6; // 0x7FBF8A
		uint32_t padding;
		uint64_t num_segments;
		uint64_t file_offset;
		uint64_t file_size;
	};
	uint8_t raw[ARCHIVE_HEADER_SIZE];
} caf_header_t;

typedef union caf_segment_table_s {
	struct {
		uint64_t index;
		uint64_t data_offset;
		uint64_t aligned_data_size;
		uint64_t signature_key_id // (0x0000000000000003)
		uint64_t enc_key_id; // (0x0000000000000001)
		uint8_t enc_iv[0x10]; // (null) Used to be filled on PS4, maybe replaced from header?
		uint64_t unaligned_data_size;
	};
	uint8_t raw[ARCHIVE_SEGMENT_TABLE_SIZE];
} caf_segment_table_t;

typedef union caf_segment_signature_s {
	struct {
		uint64_t index;
		uint8_t signature[0x10];
		uint8_t padding[0x18];
	};
	uint8_t raw[ARCHIVE_SEGMENT_SIGNATURE_SIZE];
} caf_segment_signature_t;

Updating once further research has been made...