Use ISerialiseablePrimative types in NcaHeader

This commit is contained in:
jakcron 2018-03-17 20:01:19 +08:00
parent c5c71873b9
commit e293b322c0
2 changed files with 50 additions and 90 deletions

View file

@ -13,6 +13,12 @@ namespace nx
public fnd::ISerialiseableBinary
{
public:
enum FormatVersion
{
NCA2_FORMAT,
NCA3_FORMAT
};
enum DistributionType
{
DIST_DOWNLOAD,
@ -133,72 +139,26 @@ namespace nx
struct sNcaHeader
{
private:
u8 signature_[4];
u8 distribution_type_;
u8 content_type_;
u8 key_generation_;
u8 key_area_encryption_key_index_;
u64 nca_size_;
u64 program_id_;
u32 content_index_;
u32 sdk_addon_version_;
u8 reserved_2[0x20];
char signature[4];
byte_t distribution_type;
byte_t content_type;
byte_t key_generation;
byte_t key_area_encryption_key_index;
le_uint64_t nca_size;
le_uint64_t program_id;
le_uint32_t content_index;
le_uint32_t sdk_addon_version;
byte_t reserved_2[0x20];
struct sNcaSection
{
private:
u32 start_; // block units
u32 end_; // block units
u8 enabled_;
u8 reserved[7];
public:
u32 start() const { return le_word(start_); }
void set_start(u32 offset) { start_ = le_word(offset); }
u32 end() const { return le_word(end_); }
void set_end(u32 offset) { end_ = le_word(offset); }
u8 enabled() const { return enabled_; }
void set_enabled(u8 is_enabled) { enabled_ = is_enabled; }
} section_[kSectionNum];
crypto::sha::sSha256Hash section_hash_[kSectionNum];
crypto::aes::sAes128Key enc_aes_keys_[kAesKeyNum];
public:
const char* signature() const { return (const char*)signature_; }
void set_signature(const char* signature) { memcpy(signature_, signature, 4); }
u8 distribution_type() const { return distribution_type_; }
void set_distribution_type(u8 type) { distribution_type_ = type; }
u8 content_type() const { return content_type_; }
void set_content_type(u8 type) { content_type_ = type; }
u8 key_generation() const { return key_generation_; }
void set_key_generation(u8 type) { key_generation_ = type; }
u8 key_area_encryption_key_index() const { return key_area_encryption_key_index_; }
void set_key_area_encryption_key_index(u8 index) { key_area_encryption_key_index_ = index; }
u64 nca_size() const { return le_dword(nca_size_); }
void set_nca_size(u64 nca_size) { nca_size_ = le_dword(nca_size); }
u64 program_id() const { return le_dword(program_id_); }
void set_program_id(u64 program_id) { program_id_ = le_dword(program_id); }
u32 content_index() const { return le_word(content_index_); }
void set_content_index(u32 index) { content_index_ = le_word(index); }
u32 sdk_addon_version() const { return le_word(sdk_addon_version_); }
void set_sdk_addon_version(u32 version) { sdk_addon_version_ = le_word(version); }
const sNcaSection& section(u8 index) const { return section_[index%kSectionNum]; }
sNcaSection& section(u8 index) { return section_[index%kSectionNum]; }
const crypto::sha::sSha256Hash& section_hash(u8 index) const { return section_hash_[index%kSectionNum]; }
crypto::sha::sSha256Hash& section_hash(u8 index) { return section_hash_[index%kSectionNum]; }
const crypto::aes::sAes128Key& enc_aes_key(u8 index) const { return enc_aes_keys_[index%kAesKeyNum]; }
crypto::aes::sAes128Key& enc_aes_key(u8 index) { return enc_aes_keys_[index%kAesKeyNum]; }
le_uint32_t start; // block units
le_uint32_t end; // block units
byte_t enabled;
byte_t reserved[7];
} section[kSectionNum];
crypto::sha::sSha256Hash section_hash[kSectionNum];
crypto::aes::sAes128Key enc_aes_key[kAesKeyNum];
};
#pragma pack (pop)

View file

@ -8,15 +8,15 @@ void NcaHeader::exportBinary()
mBinaryBlob.alloc(sizeof(sNcaHeader));
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
hdr->set_signature(kNcaSig.c_str());
hdr->set_distribution_type(mDistributionType);
hdr->set_content_type(mContentType);
hdr->set_key_generation(mEncryptionType);
hdr->set_key_area_encryption_key_index(mKeyIndex);
hdr->set_nca_size(mNcaSize);
hdr->set_program_id(mProgramId);
hdr->set_content_index(mContentIndex);
hdr->set_sdk_addon_version(mSdkAddonVersion);
strncpy(hdr->signature, kNcaSig.c_str(), 4);
hdr->distribution_type = mDistributionType;
hdr->content_type = mContentType;
hdr->key_generation = mEncryptionType;
hdr->key_area_encryption_key_index = mKeyIndex;
hdr->nca_size = mNcaSize;
hdr->program_id = mProgramId;
hdr->content_index = mContentIndex;
hdr->sdk_addon_version = mSdkAddonVersion;
// TODO: properly reconstruct NCA layout? atm in hands of user
@ -25,15 +25,15 @@ void NcaHeader::exportBinary()
// determine section index
u8 section = mSections.getSize() - 1 - i;
hdr->section(section).set_start(sizeToBlockNum(mSections[i].offset));
hdr->section(section).set_end(sizeToBlockNum(mSections[i].offset) + sizeToBlockNum(mSections[i].size));
hdr->section(section).set_enabled(1);
hdr->section_hash(section) = mSections[i].hash;
hdr->section[section].start = sizeToBlockNum(mSections[i].offset);
hdr->section[section].end = (sizeToBlockNum(mSections[i].offset) + sizeToBlockNum(mSections[i].size));
hdr->section[section].enabled = true;
hdr->section_hash[section] = mSections[i].hash;
}
for (size_t i = 0; i < kAesKeyNum; i++)
{
hdr->enc_aes_key(i) = mEncAesKeys[i];
hdr->enc_aes_key[i] = mEncAesKeys[i];
}
}
@ -51,19 +51,19 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
sNcaHeader* hdr = (sNcaHeader*)mBinaryBlob.getBytes();
if (memcmp(hdr->signature(), kNcaSig.c_str(), 4) != 0)
if (memcmp(hdr->signature, kNcaSig.c_str(), 4) != 0)
{
throw fnd::Exception(kModuleName, "NCA header corrupt");
}
mDistributionType = (DistributionType)hdr->distribution_type();
mContentType = (ContentType)hdr->content_type();
mEncryptionType = (EncryptionType)hdr->key_generation();
mKeyIndex = (EncryptionKeyIndex)hdr->key_area_encryption_key_index();
mNcaSize = hdr->nca_size();
mProgramId = hdr->program_id();
mContentIndex = hdr->content_index();
mSdkAddonVersion = hdr->sdk_addon_version();
mDistributionType = (DistributionType)hdr->distribution_type;
mContentType = (ContentType)hdr->content_type;
mEncryptionType = (EncryptionType)hdr->key_generation;
mKeyIndex = (EncryptionKeyIndex)hdr->key_area_encryption_key_index;
mNcaSize = *hdr->nca_size;
mProgramId = *hdr->program_id;
mContentIndex = *hdr->content_index;
mSdkAddonVersion = *hdr->sdk_addon_version;
for (size_t i = 0; i < kSectionNum; i++)
{
@ -71,7 +71,7 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
u8 section = kSectionNum - 1 - i;
// skip sections that don't exist
if (hdr->section(section).start() == 0 && hdr->section(section).end() == 0) continue;
if (*hdr->section[section].start == 0 && *hdr->section[section].end == 0) continue;
EncryptionType encType = mEncryptionType;
if (encType == CRYPT_AUTO)
@ -87,12 +87,12 @@ void NcaHeader::importBinary(const u8 * bytes, size_t len)
}
// add high level struct
mSections.addElement({ blockNumToSize(hdr->section(section).start()), blockNumToSize(hdr->section(section).end() - hdr->section(section).start()), encType, hdr->section_hash(section) });
mSections.addElement({ blockNumToSize(*hdr->section[section].start), blockNumToSize(hdr->section[section].end.get() - hdr->section[section].start.get()), encType, hdr->section_hash[section] });
}
for (size_t i = 0; i < kAesKeyNum; i++)
{
mEncAesKeys.addElement(hdr->enc_aes_key(i));
mEncAesKeys.addElement(hdr->enc_aes_key[i]);
}
}