Certified File: Difference between revisions
CelesteBlue (talk | contribs) |
CelesteBlue (talk | contribs) |
||
(20 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
Certified Files are the most common encrypted files on | Certified Files are the most common encrypted files on PS3 and PS Vita. | ||
= Introduction = | = Introduction = | ||
Line 5: | Line 5: | ||
Not only ELF/PRX files can be signed with this format, other known Certified Files are: | Not only ELF/PRX files can be signed with this format, other known Certified Files are: | ||
* revoke list | * revoke list | ||
* security policy profile | * PS3 security policy profile | ||
* system software package (e.g. .pkg, .spkg_hdr.X) | * system software package (e.g. .pkg, .spkg_hdr.X) | ||
* PS Vita diff file (never met such a file yet) | |||
* PS Vita game cartridge param.sfo (gro0:gc/param.sfo) | |||
= Structure = | = Structure = | ||
It is important to notice that PS3 | It is important to notice that PS3 uses big-endian whilst PS Vita uses little-endian. | ||
== Header == | == Header == | ||
Line 16: | Line 18: | ||
<source lang="C"> | <source lang="C"> | ||
typedef struct { // Size is 0x20 for v2, 0x30 for v3 | typedef struct { // Size is 0x20 for v2, 0x30 for v3 | ||
uint32_t magic; | |||
uint32_t version; | |||
uint16_t attribute; | |||
uint16_t category; | |||
uint32_t ext_header_size; | |||
uint64_t file_offset; | |||
uint64_t file_size; | |||
union { | |||
struct { | |||
uint64_t cf_file_size; | |||
uint64_t padding; | |||
}; | |||
}; | |||
} __attribute__((packed)) cf_header; | } __attribute__((packed)) cf_header; | ||
</source> | </source> | ||
Line 35: | Line 39: | ||
| Magic || 0x0 || u32 || Must be "SCE\0". | | Magic || 0x0 || u32 || Must be "SCE\0". | ||
|- | |- | ||
| Version || 0x4 || u32 || 2 for PS3, 3 for | | Version || 0x4 || u32 || 2 for PS3, 3 for PS Vita. | ||
|- | |- | ||
| Attribute || 0x8 || u16|| Corresponds to the revision of the | | Attribute || 0x8 || u16 || Corresponds to the revision of the encryption key. The [[Certified File Key ID]] is derived from the attribute. | ||
|- | |- | ||
| Category || 0xA || u16 || See [[Certified_File#Category|Category]]. | | Category || 0xA || u16 || See [[Certified_File#Category|Category]]. | ||
|- | |- | ||
| Extended Header size || 0xC || u32 || For SELF category only, set to 0 for other categories. See | | Extended Header size || 0xC || u32 || For SELF category only, set to 0 for other categories. See [[SELF_-_SPRX#Segment_Extended_Header]]. | ||
|- | |- | ||
| File offset || 0x10 || u64 || Offset to encapsulated data. | | File offset || 0x10 || u64 || Offset to encapsulated data. | ||
Line 49: | Line 53: | ||
| CF file size || 0x20 || u64 || Size of the CF file. Present on version 3 only. | | CF file size || 0x20 || u64 || Size of the CF file. Present on version 3 only. | ||
|- | |- | ||
| | | Padding || 0x28 || u64 || Padding. Set to 0. Present on version 3 only. | ||
|} | |} | ||
Line 57: | Line 61: | ||
! Value !! Type !! Name !! Remark | ! Value !! Type !! Name !! Remark | ||
|- | |- | ||
| 1 | | 1 || SELF - SPRX || signed-elf - signed-prx || Used for storing ELF and PRX. Both PS3 and PS Vita. | ||
|- | |- | ||
| 2 | | 2 || SRVK || signed-revoke-list || Used for [[Revokation]]. Both PS3 and PS Vita. | ||
|- | |- | ||
| 3 | | 3 || SPKG || signed-package || Used for [[PKG_files#Firmware_Packages|System Software Packages]]. Both PS3 and PS Vita. | ||
|- | |- | ||
| 4 | | 4 || SSPP || signed-security-policy-profile || The only file of this category is [[Default.spp]]. PS3 only. | ||
|- | |||
| 5 || SDIFF || signed-diff || Used in Prototype PS Vita Applier module. PS Vita only. No sample file available. | |||
|- | |||
| 6 || SPSFO || signed-param-sfo || Spsfo (signed param.sfo) file is located in game cartridge at path gro0:gc/param.sfo. PS Vita only. | |||
|} | |} | ||
== Encryption Root Header == | |||
Temporary name was Metadata Information. Official name is encryption_root_header. | |||
Encryption Root Header is not present in fCF (fSELF, fSPP, etc...). | |||
Encryption Root Header is decrypted using AES256CBC with the key and iv from System Software. | |||
=== Struct === | |||
<source lang="C"> | |||
typedef struct { | |||
uint8_t key[16]; | |||
uint8_t key_pad[16]; | |||
uint8_t iv[16]; | |||
uint8_t iv_pad[16]; | |||
} __attribute__((packed)) cf_encryption_root_header; | |||
</source> | |||
=== Comments === | |||
== Certification Header == | |||
Temporary name was Metadata Header. Official name is certification_header. | |||
Certification Header is only present if the Encryption Root Header is present. In that case, Certification Header is located after the Encryption Root Header. | |||
Certification Header is decrypted using AES128 with the key and iv entries from the Encryption Root Header. | |||
=== Struct === | |||
<source lang="C"> | |||
typedef struct { | |||
uint64_t sign_offset; | |||
uint32_t sign_algorithm; // 1 = ECDSA160, 2 = HMACSHA1, 3 = SHA1, 5 = RSA2048, 6 = HMACSHA256 (?not used?) | |||
uint32_t cert_entry_num; | |||
uint32_t attr_entry_num; | |||
uint32_t optional_header_size; | |||
uint64_t pad; | |||
} __attribute__((packed)) cf_certification_header; | |||
</source> | |||
=== Comments === | |||
== Certification Body == | |||
Certification Body is located just after the Certification Header. | |||
Certification Body is decrypted using AES128 with the key and iv entries from the Encryption Root Header. | |||
=== Segment Certification Header === | |||
Temporary name was Metadata Section Header. Official name is segment_certification_header. | |||
Segment Certification Header is only present if the Certification Header is present. | |||
The number of Segment Certification Headers is indicated by the cert_entry_num field in the Certification Header. | |||
Segment Certification Header is located after the Certification Header. | |||
==== Struct ==== | |||
<source lang="C"> | |||
typedef struct { | |||
uint64_t segment_offset; | |||
uint64_t segment_size; | |||
uint32_t segment_type; // 1 = shdr, 2 = phdr, 3 = sceversion | |||
uint32_t segment_id; // 0,1,2,3,etc for phdr, always 3 for shdrs, sceversion shdr number for sceversion | |||
uint32_t sign_algorithm; // 1 = ECDSA160 (not used), 2 = HMACSHA1, 3 = SHA1, 5 = RSA2048 (not used), 6 = HMACSHA256 | |||
uint32_t sign_idx; | |||
uint32_t enc_algorithm; // 1 = none, 2 = aes128cbccfb, 3 = aes128ctr | |||
uint32_t key_idx; // -1 when enc_algorithm = none | |||
uint32_t iv_idx; // -1 when enc_algorithm = none | |||
uint32_t comp_algorithm; // 1 = plain, 2 = zlib | |||
} __attribute__((packed)) cf_segment_certification_header; | |||
</source> | |||
==== Comments ==== | |||
* Segment data is decrypted using enc_algorithm with the key and iv specified by key_idx and iv_idx, in the Attributes. | |||
* The segment_offset field in the Segment Certification Header usually matches the offset field in the [[SELF_-_SPRX#Segment_Extended_Header|Segment Extended Header]]. | |||
=== Attributes === | |||
Temporary name was Metadata Keys, Section Hash, Segment Certification. Official name is attribute(s), found sub get_attribute(unsigned char *, unsigned int) on spp_verifier which returns pointer to signature/key/iv by its id. | |||
The number of Attributes is indicated by the attr_entry_num field in the Certification Header. | |||
Attributes are located after the Segment Certification Headers. | |||
==== Struct ==== | |||
<source lang="C"> | |||
typedef struct { | |||
union { // size is 0x60 bytes | |||
uint8_t signature[0x20]; // hmac_sha1_hash | |||
uint8_t sign_key[0x40]; | |||
} signature_type2; | |||
union { // size is 0x20 bytes | |||
uint8_t signature[0x20]; // sha1_hash | |||
} signature_type3; | |||
union { // size is 0x40 bytes | |||
uint8_t signature[0x20]; // hmac_sha256_hash | |||
uint8_t sign_key[0x20]; | |||
} signature_type6; | |||
union { // size is 0x20 bytes | |||
uint8_t key[0x10]; | |||
uint8_t iv[0x10]; | |||
} encryption_params; // present for enc_algorithm type 2 and 3 | |||
} __attribute__((packed)) cf_attribute; | |||
</source> | |||
==== Comments ==== | |||
* The signature is calculated on the decrypted data and before the decompression. | |||
=== Optional Header Table === | |||
Temporary name was Signature Info, Capabilities Info. Official name is optional_header_table. | |||
Optional Header Table is only present if optional_header_size in the Certification Header is not zero. In that case, Optional Header Table is located after the Attributes. | |||
==== Struct ==== | |||
<source lang="C"> | |||
typedef struct { | |||
uint32_t type; // 1=capability_header, 2=individual_seed_header, 3=attribute_header | |||
uint32_t size; | |||
uint64_t next; // 1 if another cf_optional_header structure follows else 0 | |||
union { | |||
// type 1 | |||
struct { // 0x20 bytes of data | |||
uint8_t capability[0x20]; | |||
} capability_header; | |||
// type 2 | |||
struct { // 0x100 bytes of data | |||
uint8_t individual_seed[0x100]; | |||
} individual_seed_header; | |||
// type 3 | |||
struct { // 0x20 bytes of data | |||
uint8_t attribute[0x20]; | |||
} attribute_header; | |||
}; | |||
} __attribute__((packed)) cf_optional_header; | |||
</source> | |||
==== Comments ==== | |||
* Optional Header Type 1 contains encrypted_capability (not plaintext capability). See [[Capability Flags]]. | |||
== Signature == | |||
Official name might be Signature. | |||
Signature is located at the Certification Header sign_offset in the Certified File. | |||
Signature is decrypted with the key and iv entries from the Encryption Root Header. | |||
Signature algorithm can be ECDSA160 or RSA2048, according to the Certification Header. | |||
=== Struct === | |||
<source lang="C"> | |||
typedef struct { | |||
union { | |||
uint8_t r[21]; | |||
uint8_t s[21]; | |||
uint8_t padding[6]; | |||
} ECDSA160; | |||
union { | |||
uint8_t rsa[0x100]; | |||
} RSA2048; | |||
} __attribute__((packed)) cf_signature; | |||
</source> | |||
=== Comments === | |||
* sign_offset is the size of the data on which is computed the signature, from the start of the Certified File. The decrypted version of the input data is used for signature. | |||
= Decryption = | = Decryption = | ||
Certified Files are all encrypted using the exact same algorithm. | Certified Files are all encrypted using the exact same algorithm (except for Fake Certified Files). They can be encrypted, hashed and signed. This section only focuses on the encryption layer. | ||
* Step 0: Get Encryption Root Header Master Keys | |||
On PS3, TO DOCUMENT. | |||
On PS Vita, static key and IV are contained within the relevant Secure Module. For example, SPKG keys are located in update_service_sm.self, KPRX keys are located in kprx_auth_sm.self, Security Modules keys and kernel_boot_loader.self keys are located in secure_kernel. | |||
* Step 1: Get | * Step 1: Get Encryption Root Key and IV | ||
Decrypt the Certification Header using AES256CBC on PS Vita (to document for PS3). | |||
This results into the key and IV used in step 2. | |||
* Step 2: Get plain Certification | |||
Use the key and IV decrypted from the Encryption Root Header to decrypt the Certification using AES128CBC on PS Vita (what on PS3?). | |||
* Step 3: Parse Certification | |||
SELF Certification is typically stored in the following format. Below is an example of a 4-segments PS Vita SELF. | |||
SPKG Certification follows the same principles but is slightly different (different Magic/Header). | |||
<source lang = "C"> | <source lang = "C"> | ||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ||
00000000 F0 07 00 00 00 00 00 00 05 00 00 00 04 00 00 00 ð............... <<< | 00000000 F0 07 00 00 00 00 00 00 05 00 00 00 04 00 00 00 ð............... <<< Certification Header | ||
00000010 18 00 00 00 70 01 00 00 00 00 00 00 00 00 00 00 ....p........... | 00000010 18 00 00 00 70 01 00 00 00 00 00 00 00 00 00 00 ....p........... <<< Certification Header | ||
00000020 00 0A 00 00 00 00 00 00 C0 00 00 00 00 00 00 00 ........À....... <<< First | 00000020 00 0A 00 00 00 00 00 00 C0 00 00 00 00 00 00 00 ........À....... <<< First segment address | ||
00000030 02 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 ................ | 00000030 02 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 ................ | ||
00000040 03 00 00 00 04 00 00 00 05 00 00 00 01 00 00 00 ................ | 00000040 03 00 00 00 04 00 00 00 05 00 00 00 01 00 00 00 ................ | ||
00000050 00 0B 00 00 00 00 00 00 FC B4 07 00 00 00 00 00 ........ü´...... <<< | 00000050 00 0B 00 00 00 00 00 00 FC B4 07 00 00 00 00 00 ........ü´...... <<< Second segment address | ||
00000060 02 00 00 00 02 00 00 00 06 00 00 00 06 00 00 00 ................ | 00000060 02 00 00 00 02 00 00 00 06 00 00 00 06 00 00 00 ................ | ||
00000070 03 00 00 00 0A 00 00 00 0B 00 00 00 01 00 00 00 ................ | 00000070 03 00 00 00 0A 00 00 00 0B 00 00 00 01 00 00 00 ................ | ||
00000080 00 C0 07 00 00 00 00 00 98 1E 00 00 00 00 00 00 .À......˜....... <<< | 00000080 00 C0 07 00 00 00 00 00 98 1E 00 00 00 00 00 00 .À......˜....... <<< Third segment address | ||
00000090 02 00 00 00 03 00 00 00 06 00 00 00 0C 00 00 00 ................ | 00000090 02 00 00 00 03 00 00 00 06 00 00 00 0C 00 00 00 ................ | ||
000000A0 03 00 00 00 10 00 00 00 11 00 00 00 01 00 00 00 ................ | 000000A0 03 00 00 00 10 00 00 00 11 00 00 00 01 00 00 00 ................ | ||
000000B0 00 DF 07 00 00 00 00 00 9D BA 02 00 00 00 00 00 .ß.......º...... <<< Fourth | 000000B0 00 DF 07 00 00 00 00 00 9D BA 02 00 00 00 00 00 .ß.......º...... <<< Fourth segment address | ||
000000C0 02 00 00 00 04 00 00 00 06 00 00 00 12 00 00 00 ................ | 000000C0 02 00 00 00 04 00 00 00 06 00 00 00 12 00 00 00 ................ | ||
000000D0 03 00 00 00 16 00 00 00 17 00 00 00 01 00 00 00 ................ | 000000D0 03 00 00 00 16 00 00 00 17 00 00 00 01 00 00 00 ................ | ||
000000E0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< First | 000000E0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< First segment Hash | ||
000000F0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< First | 000000F0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< First segment Hash | ||
00000100 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ | 00000100 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ | ||
00000110 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ | 00000110 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ | ||
00000120 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< First | 00000120 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< First segment random key | ||
00000130 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< First | 00000130 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< First segment random IV | ||
00000140 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Second | 00000140 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Second segment Hash | ||
00000150 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Second | 00000150 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Second segment Hash | ||
00000160 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | 00000160 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | ||
00000170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | 00000170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | ||
00000180 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Second | 00000180 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Second segment random key | ||
00000190 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Second | 00000190 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Second segment random IV | ||
000001A0 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Third | 000001A0 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Third segment Hash | ||
000001B0 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Third | 000001B0 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Third segment Hash | ||
000001C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | 000001C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | ||
000001D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | 000001D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | ||
000001E0 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Third | 000001E0 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Third segment random key | ||
000001F0 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Third | 000001F0 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Third segment random IV | ||
00000200 DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ <<< Fourth | 00000200 DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ <<< Fourth segment Hash | ||
00000210 DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ <<< Fourth | 00000210 DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ <<< Fourth segment Hash | ||
00000220 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | 00000220 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | ||
00000230 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | 00000230 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key | ||
00000240 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Fourth | 00000240 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Fourth segment random key | ||
00000250 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Fourth | 00000250 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Fourth segment random IV | ||
00000260 01 00 00 00 30 00 00 00 01 00 00 00 00 00 00 00 ....0........... <<< type (u32), | 00000260 01 00 00 00 30 00 00 00 01 00 00 00 00 00 00 00 ....0........... <<< type (u32), segment size (u32), isMoreSegments (u32) | ||
00000270 80 00 00 00 C0 00 F0 00 00 00 00 00 FF FF FF FF €...À.ð.....ÿÿÿÿ | 00000270 80 00 00 00 C0 00 F0 00 00 00 00 00 FF FF FF FF €...À.ð.....ÿÿÿÿ | ||
00000270 80 00 00 00 C0 00 F0 00 00 00 00 00 FF FF FF FF €...À.ð.....ÿÿÿÿ | 00000270 80 00 00 00 C0 00 F0 00 00 00 00 00 FF FF FF FF €...À.ð.....ÿÿÿÿ | ||
00000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 00000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | ||
00000290 02 00 00 00 10 01 00 00 01 00 00 00 00 00 00 00 ................ <<< type (u32), | 00000290 02 00 00 00 10 01 00 00 01 00 00 00 00 00 00 00 ................ <<< type (u32), segment size (u32), isMoreSegments (u32) | ||
000002A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 000002A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | ||
000002B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 000002B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | ||
Line 149: | Line 341: | ||
00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | ||
00000390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 00000390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | ||
000003A0 03 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... <<< type (u32), | 000003A0 03 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... <<< type (u32), segment size (u32), isMoreSegments (u32) | ||
000003B0 80 09 80 03 00 00 C3 00 00 00 80 09 80 00 00 00 €.€...Ã...€.€... | 000003B0 80 09 80 03 00 00 C3 00 00 00 80 09 80 00 00 00 €.€...Ã...€.€... | ||
000003C0 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF ............ÿÿÿÿ | 000003C0 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF ............ÿÿÿÿ | ||
000003D0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000003D0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000003E0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000003E0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000003F0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000003F0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000400 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000400 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000410 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000410 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000420 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000420 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000430 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000430 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000440 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000440 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000450 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000450 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000460 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000460 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000470 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000470 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000480 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000480 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000490 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000490 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000004A0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000004A0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000004B0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000004B0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000004C0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000004C0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000004D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ <<< | 000004D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ <<< Certification Body end, padding | ||
</source> | </source> | ||
Following the same principles, | Following the same principles, a plain SPKG Certification Body looks like this: | ||
<source lang = "C"> | <source lang = "C"> | ||
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | ||
00000000 00 02 00 00 00 00 00 00 05 00 00 00 03 00 00 00 ................ <<< | 00000000 00 02 00 00 00 00 00 00 05 00 00 00 03 00 00 00 ................ <<< Certification Header | ||
00000010 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 00000010 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ <<< Certification Header | ||
00000020 00 03 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@....... | 00000020 00 03 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@....... | ||
00000030 01 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 ................ | 00000030 01 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 ................ | ||
Line 200: | Line 392: | ||
00000170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random key | 00000170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random key | ||
00000180 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random IV | 00000180 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random IV | ||
00000190 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000190 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000001A0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000001A0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000001B0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000001B0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000001C0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000001C0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000001D0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000001D0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000001E0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000001E0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
000001F0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 000001F0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000200 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000200 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000210 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000210 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000220 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000220 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000230 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000230 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000240 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000240 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000250 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000250 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000260 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000260 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
00000270 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< | 00000270 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048) | ||
</source> | </source> | ||
* Step 4: | * Step 4: Decrypt CF segments if needed | ||
CF segments can be encrypted. This is reported in the Segment Certification Header. Use the keys and IVs from the Attributes with the specified algorithm to decrypt the respective segments. | |||
* Step 5: Uncompress CF segments if needed | |||
CF segments can be compressed. This is reported in the Segment Certification Header. | |||
{{File Formats}} | |||
<noinclude>[[Category:Main]]</noinclude> |
Latest revision as of 04:51, 13 February 2023
Certified Files are the most common encrypted files on PS3 and PS Vita.
Introduction[edit | edit source]
Not only ELF/PRX files can be signed with this format, other known Certified Files are:
- revoke list
- PS3 security policy profile
- system software package (e.g. .pkg, .spkg_hdr.X)
- PS Vita diff file (never met such a file yet)
- PS Vita game cartridge param.sfo (gro0:gc/param.sfo)
Structure[edit | edit source]
It is important to notice that PS3 uses big-endian whilst PS Vita uses little-endian.
Header[edit | edit source]
typedef struct { // Size is 0x20 for v2, 0x30 for v3
uint32_t magic;
uint32_t version;
uint16_t attribute;
uint16_t category;
uint32_t ext_header_size;
uint64_t file_offset;
uint64_t file_size;
union {
struct {
uint64_t cf_file_size;
uint64_t padding;
};
};
} __attribute__((packed)) cf_header;
field | offset | type | notes |
---|---|---|---|
Magic | 0x0 | u32 | Must be "SCE\0". |
Version | 0x4 | u32 | 2 for PS3, 3 for PS Vita. |
Attribute | 0x8 | u16 | Corresponds to the revision of the encryption key. The Certified File Key ID is derived from the attribute. |
Category | 0xA | u16 | See Category. |
Extended Header size | 0xC | u32 | For SELF category only, set to 0 for other categories. See SELF_-_SPRX#Segment_Extended_Header. |
File offset | 0x10 | u64 | Offset to encapsulated data. |
File size | 0x18 | u64 | Size of the encapsulated data. |
CF file size | 0x20 | u64 | Size of the CF file. Present on version 3 only. |
Padding | 0x28 | u64 | Padding. Set to 0. Present on version 3 only. |
Category[edit | edit source]
Value | Type | Name | Remark |
---|---|---|---|
1 | SELF - SPRX | signed-elf - signed-prx | Used for storing ELF and PRX. Both PS3 and PS Vita. |
2 | SRVK | signed-revoke-list | Used for Revokation. Both PS3 and PS Vita. |
3 | SPKG | signed-package | Used for System Software Packages. Both PS3 and PS Vita. |
4 | SSPP | signed-security-policy-profile | The only file of this category is Default.spp. PS3 only. |
5 | SDIFF | signed-diff | Used in Prototype PS Vita Applier module. PS Vita only. No sample file available. |
6 | SPSFO | signed-param-sfo | Spsfo (signed param.sfo) file is located in game cartridge at path gro0:gc/param.sfo. PS Vita only. |
Encryption Root Header[edit | edit source]
Temporary name was Metadata Information. Official name is encryption_root_header.
Encryption Root Header is not present in fCF (fSELF, fSPP, etc...).
Encryption Root Header is decrypted using AES256CBC with the key and iv from System Software.
Struct[edit | edit source]
typedef struct {
uint8_t key[16];
uint8_t key_pad[16];
uint8_t iv[16];
uint8_t iv_pad[16];
} __attribute__((packed)) cf_encryption_root_header;
Comments[edit | edit source]
Certification Header[edit | edit source]
Temporary name was Metadata Header. Official name is certification_header.
Certification Header is only present if the Encryption Root Header is present. In that case, Certification Header is located after the Encryption Root Header.
Certification Header is decrypted using AES128 with the key and iv entries from the Encryption Root Header.
Struct[edit | edit source]
typedef struct {
uint64_t sign_offset;
uint32_t sign_algorithm; // 1 = ECDSA160, 2 = HMACSHA1, 3 = SHA1, 5 = RSA2048, 6 = HMACSHA256 (?not used?)
uint32_t cert_entry_num;
uint32_t attr_entry_num;
uint32_t optional_header_size;
uint64_t pad;
} __attribute__((packed)) cf_certification_header;
Comments[edit | edit source]
Certification Body[edit | edit source]
Certification Body is located just after the Certification Header.
Certification Body is decrypted using AES128 with the key and iv entries from the Encryption Root Header.
Segment Certification Header[edit | edit source]
Temporary name was Metadata Section Header. Official name is segment_certification_header.
Segment Certification Header is only present if the Certification Header is present.
The number of Segment Certification Headers is indicated by the cert_entry_num field in the Certification Header.
Segment Certification Header is located after the Certification Header.
Struct[edit | edit source]
typedef struct {
uint64_t segment_offset;
uint64_t segment_size;
uint32_t segment_type; // 1 = shdr, 2 = phdr, 3 = sceversion
uint32_t segment_id; // 0,1,2,3,etc for phdr, always 3 for shdrs, sceversion shdr number for sceversion
uint32_t sign_algorithm; // 1 = ECDSA160 (not used), 2 = HMACSHA1, 3 = SHA1, 5 = RSA2048 (not used), 6 = HMACSHA256
uint32_t sign_idx;
uint32_t enc_algorithm; // 1 = none, 2 = aes128cbccfb, 3 = aes128ctr
uint32_t key_idx; // -1 when enc_algorithm = none
uint32_t iv_idx; // -1 when enc_algorithm = none
uint32_t comp_algorithm; // 1 = plain, 2 = zlib
} __attribute__((packed)) cf_segment_certification_header;
Comments[edit | edit source]
- Segment data is decrypted using enc_algorithm with the key and iv specified by key_idx and iv_idx, in the Attributes.
- The segment_offset field in the Segment Certification Header usually matches the offset field in the Segment Extended Header.
Attributes[edit | edit source]
Temporary name was Metadata Keys, Section Hash, Segment Certification. Official name is attribute(s), found sub get_attribute(unsigned char *, unsigned int) on spp_verifier which returns pointer to signature/key/iv by its id.
The number of Attributes is indicated by the attr_entry_num field in the Certification Header.
Attributes are located after the Segment Certification Headers.
Struct[edit | edit source]
typedef struct {
union { // size is 0x60 bytes
uint8_t signature[0x20]; // hmac_sha1_hash
uint8_t sign_key[0x40];
} signature_type2;
union { // size is 0x20 bytes
uint8_t signature[0x20]; // sha1_hash
} signature_type3;
union { // size is 0x40 bytes
uint8_t signature[0x20]; // hmac_sha256_hash
uint8_t sign_key[0x20];
} signature_type6;
union { // size is 0x20 bytes
uint8_t key[0x10];
uint8_t iv[0x10];
} encryption_params; // present for enc_algorithm type 2 and 3
} __attribute__((packed)) cf_attribute;
Comments[edit | edit source]
- The signature is calculated on the decrypted data and before the decompression.
Optional Header Table[edit | edit source]
Temporary name was Signature Info, Capabilities Info. Official name is optional_header_table.
Optional Header Table is only present if optional_header_size in the Certification Header is not zero. In that case, Optional Header Table is located after the Attributes.
Struct[edit | edit source]
typedef struct {
uint32_t type; // 1=capability_header, 2=individual_seed_header, 3=attribute_header
uint32_t size;
uint64_t next; // 1 if another cf_optional_header structure follows else 0
union {
// type 1
struct { // 0x20 bytes of data
uint8_t capability[0x20];
} capability_header;
// type 2
struct { // 0x100 bytes of data
uint8_t individual_seed[0x100];
} individual_seed_header;
// type 3
struct { // 0x20 bytes of data
uint8_t attribute[0x20];
} attribute_header;
};
} __attribute__((packed)) cf_optional_header;
Comments[edit | edit source]
- Optional Header Type 1 contains encrypted_capability (not plaintext capability). See Capability Flags.
Signature[edit | edit source]
Official name might be Signature.
Signature is located at the Certification Header sign_offset in the Certified File.
Signature is decrypted with the key and iv entries from the Encryption Root Header.
Signature algorithm can be ECDSA160 or RSA2048, according to the Certification Header.
Struct[edit | edit source]
typedef struct {
union {
uint8_t r[21];
uint8_t s[21];
uint8_t padding[6];
} ECDSA160;
union {
uint8_t rsa[0x100];
} RSA2048;
} __attribute__((packed)) cf_signature;
Comments[edit | edit source]
- sign_offset is the size of the data on which is computed the signature, from the start of the Certified File. The decrypted version of the input data is used for signature.
Decryption[edit | edit source]
Certified Files are all encrypted using the exact same algorithm (except for Fake Certified Files). They can be encrypted, hashed and signed. This section only focuses on the encryption layer.
- Step 0: Get Encryption Root Header Master Keys
On PS3, TO DOCUMENT.
On PS Vita, static key and IV are contained within the relevant Secure Module. For example, SPKG keys are located in update_service_sm.self, KPRX keys are located in kprx_auth_sm.self, Security Modules keys and kernel_boot_loader.self keys are located in secure_kernel.
- Step 1: Get Encryption Root Key and IV
Decrypt the Certification Header using AES256CBC on PS Vita (to document for PS3).
This results into the key and IV used in step 2.
- Step 2: Get plain Certification
Use the key and IV decrypted from the Encryption Root Header to decrypt the Certification using AES128CBC on PS Vita (what on PS3?).
- Step 3: Parse Certification
SELF Certification is typically stored in the following format. Below is an example of a 4-segments PS Vita SELF.
SPKG Certification follows the same principles but is slightly different (different Magic/Header).
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 F0 07 00 00 00 00 00 00 05 00 00 00 04 00 00 00 ð............... <<< Certification Header
00000010 18 00 00 00 70 01 00 00 00 00 00 00 00 00 00 00 ....p........... <<< Certification Header
00000020 00 0A 00 00 00 00 00 00 C0 00 00 00 00 00 00 00 ........À....... <<< First segment address
00000030 02 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 ................
00000040 03 00 00 00 04 00 00 00 05 00 00 00 01 00 00 00 ................
00000050 00 0B 00 00 00 00 00 00 FC B4 07 00 00 00 00 00 ........ü´...... <<< Second segment address
00000060 02 00 00 00 02 00 00 00 06 00 00 00 06 00 00 00 ................
00000070 03 00 00 00 0A 00 00 00 0B 00 00 00 01 00 00 00 ................
00000080 00 C0 07 00 00 00 00 00 98 1E 00 00 00 00 00 00 .À......˜....... <<< Third segment address
00000090 02 00 00 00 03 00 00 00 06 00 00 00 0C 00 00 00 ................
000000A0 03 00 00 00 10 00 00 00 11 00 00 00 01 00 00 00 ................
000000B0 00 DF 07 00 00 00 00 00 9D BA 02 00 00 00 00 00 .ß.......º...... <<< Fourth segment address
000000C0 02 00 00 00 04 00 00 00 06 00 00 00 12 00 00 00 ................
000000D0 03 00 00 00 16 00 00 00 17 00 00 00 01 00 00 00 ................
000000E0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< First segment Hash
000000F0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< First segment Hash
00000100 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
00000110 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
00000120 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< First segment random key
00000130 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< First segment random IV
00000140 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Second segment Hash
00000150 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Second segment Hash
00000160 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key
00000170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key
00000180 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Second segment random key
00000190 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Second segment random IV
000001A0 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Third segment Hash
000001B0 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Third segment Hash
000001C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key
000001D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key
000001E0 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Third segment random key
000001F0 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Third segment random IV
00000200 DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ <<< Fourth segment Hash
00000210 DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ <<< Fourth segment Hash
00000220 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key
00000230 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< HMAC key
00000240 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Fourth segment random key
00000250 EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE îîîîîîîîîîîîîîîî <<< Fourth segment random IV
00000260 01 00 00 00 30 00 00 00 01 00 00 00 00 00 00 00 ....0........... <<< type (u32), segment size (u32), isMoreSegments (u32)
00000270 80 00 00 00 C0 00 F0 00 00 00 00 00 FF FF FF FF €...À.ð.....ÿÿÿÿ
00000270 80 00 00 00 C0 00 F0 00 00 00 00 00 FF FF FF FF €...À.ð.....ÿÿÿÿ
00000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000290 02 00 00 00 10 01 00 00 01 00 00 00 00 00 00 00 ................ <<< type (u32), segment size (u32), isMoreSegments (u32)
000002A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000370 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003A0 03 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 ....0........... <<< type (u32), segment size (u32), isMoreSegments (u32)
000003B0 80 09 80 03 00 00 C3 00 00 00 80 09 80 00 00 00 €.€...Ã...€.€...
000003C0 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF ............ÿÿÿÿ
000003D0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000003E0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000003F0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000400 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000410 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000420 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000430 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000440 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000450 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000460 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000470 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000480 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000490 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000004A0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000004B0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000004C0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000004D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ <<< Certification Body end, padding
Following the same principles, a plain SPKG Certification Body looks like this:
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 00 02 00 00 00 00 00 00 05 00 00 00 03 00 00 00 ................ <<< Certification Header
00000010 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ <<< Certification Header
00000020 00 03 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......
00000030 01 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 ................
00000040 01 00 00 00 FF FF FF FF FF FF FF FF 01 00 00 00 ....ÿÿÿÿÿÿÿÿ....
00000050 40 03 00 00 00 00 00 00 40 00 00 00 00 00 00 00 @.......@.......
00000060 02 00 00 00 02 00 00 00 06 00 00 00 04 00 00 00 ................
00000070 01 00 00 00 FF FF FF FF FF FF FF FF 01 00 00 00 ....ÿÿÿÿÿÿÿÿ....
00000080 80 03 00 00 00 00 00 00 00 00 80 00 00 00 00 00 €.........€.....
00000090 03 00 00 00 03 00 00 00 06 00 00 00 08 00 00 00 ................
000000A0 03 00 00 00 0C 00 00 00 0D 00 00 00 01 00 00 00 ................
000000B0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< Hash
000000C0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA ªªªªªªªªªªªªªªªª <<< Hash
000000D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
000000E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
000000F0 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Hash
00000100 BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB BB »»»»»»»»»»»»»»»» <<< Hash
00000110 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
00000120 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
00000130 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Hash
00000140 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ <<< Hash
00000150 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random key
00000160 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random IV
00000170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random key
00000180 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ <<< Random IV
00000190 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000001A0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000001B0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000001C0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000001D0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000001E0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
000001F0 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000200 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000210 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000220 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000230 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000240 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000250 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000260 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
00000270 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ................ <<< Signature (RSA2048)
- Step 4: Decrypt CF segments if needed
CF segments can be encrypted. This is reported in the Segment Certification Header. Use the keys and IVs from the Attributes with the specified algorithm to decrypt the respective segments.
- Step 5: Uncompress CF segments if needed
CF segments can be compressed. This is reported in the Segment Certification Header.
|