diff --git a/lib/libnx/include/nx/HierarchicalSha256Header.h b/lib/libnx/include/nx/HierarchicalSha256Header.h index 3101096..a165b5b 100644 --- a/lib/libnx/include/nx/HierarchicalSha256Header.h +++ b/lib/libnx/include/nx/HierarchicalSha256Header.h @@ -10,6 +10,27 @@ namespace nx public fnd::ISerialiseableBinary { public: + struct sLayer + { + size_t offset; + size_t size; + + void operator=(const sLayer& other) + { + offset = other.offset; + size = other.size; + } + + bool operator==(const sLayer& other) + { + return (offset == other.offset && size == other.size); + } + + bool operator!=(const sLayer& other) + { + return !(*this == other); + } + }; HierarchicalSha256Header(); HierarchicalSha256Header(const HierarchicalSha256Header& other); @@ -30,7 +51,14 @@ namespace nx // variables void clear(); + const crypto::sha::sSha256Hash& getMasterHash() const; + void setMasterHash(const crypto::sha::sSha256Hash& master_hash); + size_t getHashBlockSize() const; + void setHashBlockSize(size_t hash_block_size); + + const fnd::List& getLayerInfo() const; + void setLayerInfo(const fnd::List& layer_info); private: const std::string kModuleName = "HIERARCHICAL_SHA256_HEADER"; @@ -38,10 +66,10 @@ namespace nx fnd::MemoryBlob mBinaryBlob; // data + crypto::sha::sSha256Hash mMasterHash; + size_t mHashBlockSize; + fnd::List mLayerInfo; - - uint64_t blockNumToSize(uint32_t block_num) const; - uint32_t sizeToBlockNum(uint64_t real_size) const; bool isEqual(const HierarchicalSha256Header& other) const; void copyFrom(const HierarchicalSha256Header& other); }; diff --git a/lib/libnx/include/nx/hierarchicalintegrity.h b/lib/libnx/include/nx/hierarchicalintegrity.h index 50677dd..02a9297 100644 --- a/lib/libnx/include/nx/hierarchicalintegrity.h +++ b/lib/libnx/include/nx/hierarchicalintegrity.h @@ -6,12 +6,12 @@ namespace nx { - // Also known as HierarchicalIntegrity + // Also known to the public as IVFC namespace hierarchicalintegrity { const std::string kStructSig = "IVFC"; - static const size_t kMaxLayerNum = 7; static const uint32_t kTypeId = 0x20000; + static const size_t kMaxLayerNum = 7; static const size_t kMaxMasterHashNum = 3; } diff --git a/lib/libnx/include/nx/hierarchicalsha256.h b/lib/libnx/include/nx/hierarchicalsha256.h index 8db3b26..a4da019 100644 --- a/lib/libnx/include/nx/hierarchicalsha256.h +++ b/lib/libnx/include/nx/hierarchicalsha256.h @@ -19,7 +19,7 @@ namespace nx crypto::sha::sSha256Hash master_hash; le_uint32_t hash_block_size; le_uint32_t layer_num; - struct sLayout + struct sLayer { le_uint64_t offset; le_uint64_t size; diff --git a/lib/libnx/nx.vcxproj b/lib/libnx/nx.vcxproj index 5fde829..1dd00bc 100644 --- a/lib/libnx/nx.vcxproj +++ b/lib/libnx/nx.vcxproj @@ -30,7 +30,7 @@ - + diff --git a/lib/libnx/nx.vcxproj.filters b/lib/libnx/nx.vcxproj.filters index b1e1f7d..c817750 100644 --- a/lib/libnx/nx.vcxproj.filters +++ b/lib/libnx/nx.vcxproj.filters @@ -153,7 +153,7 @@ Header Files - + Header Files diff --git a/lib/libnx/source/HierarchicalIntegrityHeader.cpp b/lib/libnx/source/HierarchicalIntegrityHeader.cpp index e69de29..0830653 100644 --- a/lib/libnx/source/HierarchicalIntegrityHeader.cpp +++ b/lib/libnx/source/HierarchicalIntegrityHeader.cpp @@ -0,0 +1,96 @@ +#include + +nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader() +{ + clear(); +} + +nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const HierarchicalIntegrityHeader & other) +{ + copyFrom(other); +} + +nx::HierarchicalIntegrityHeader::HierarchicalIntegrityHeader(const byte_t * bytes, size_t len) +{ + importBinary(bytes, len); +} + +bool nx::HierarchicalIntegrityHeader::operator==(const HierarchicalIntegrityHeader & other) const +{ + return isEqual(other); +} + +bool nx::HierarchicalIntegrityHeader::operator!=(const HierarchicalIntegrityHeader & other) const +{ + return !isEqual(other); +} + +void nx::HierarchicalIntegrityHeader::operator=(const HierarchicalIntegrityHeader & other) +{ + copyFrom(other); +} + +const byte_t * nx::HierarchicalIntegrityHeader::getBytes() const +{ + return mBinaryBlob.getBytes(); +} + +size_t nx::HierarchicalIntegrityHeader::getSize() const +{ + return mBinaryBlob.getSize(); +} + +void nx::HierarchicalIntegrityHeader::exportBinary() +{ + throw fnd::Exception(kModuleName, "exportBinary() not implemented"); +} + +void nx::HierarchicalIntegrityHeader::importBinary(const byte_t * bytes, size_t len) +{ + throw fnd::Exception(kModuleName, "importBinary() not implemented"); +} + +void nx::HierarchicalIntegrityHeader::clear() +{ + mLayerInfo.clear(); + mMasterHashList.clear(); +} + +const fnd::List& nx::HierarchicalIntegrityHeader::getLayerInfo() const +{ + return mLayerInfo; +} + +void nx::HierarchicalIntegrityHeader::setLayerInfo(const fnd::List& layer_info) +{ + mLayerInfo = layer_info; +} + +const fnd::List& nx::HierarchicalIntegrityHeader::getMasterHashList() const +{ + return mMasterHashList; +} + +void nx::HierarchicalIntegrityHeader::setMasterHashList(const fnd::List& master_hash_list) +{ + mMasterHashList = master_hash_list; +} + +bool nx::HierarchicalIntegrityHeader::isEqual(const HierarchicalIntegrityHeader & other) const +{ + return (mLayerInfo == other.mLayerInfo) \ + && (mMasterHashList == other.mMasterHashList); +} + +void nx::HierarchicalIntegrityHeader::copyFrom(const HierarchicalIntegrityHeader & other) +{ + if (other.getSize() != 0) + { + importBinary(other.getBytes(), other.getSize()); + } + else + { + mLayerInfo = other.mLayerInfo; + mMasterHashList = other.mMasterHashList; + } +} diff --git a/lib/libnx/source/HierarchicalSha256Header.cpp b/lib/libnx/source/HierarchicalSha256Header.cpp index e69de29..de9ca79 100644 --- a/lib/libnx/source/HierarchicalSha256Header.cpp +++ b/lib/libnx/source/HierarchicalSha256Header.cpp @@ -0,0 +1,132 @@ +#include +#include + + +nx::HierarchicalSha256Header::HierarchicalSha256Header() +{ + clear(); +} + +nx::HierarchicalSha256Header::HierarchicalSha256Header(const HierarchicalSha256Header & other) +{ + copyFrom(other); +} + +nx::HierarchicalSha256Header::HierarchicalSha256Header(const byte_t * bytes, size_t len) +{ + importBinary(bytes, len); +} + +bool nx::HierarchicalSha256Header::operator==(const HierarchicalSha256Header & other) const +{ + return isEqual(other); +} + +bool nx::HierarchicalSha256Header::operator!=(const HierarchicalSha256Header & other) const +{ + return !isEqual(other); +} + +void nx::HierarchicalSha256Header::operator=(const HierarchicalSha256Header & other) +{ + copyFrom(other); +} + +const byte_t * nx::HierarchicalSha256Header::getBytes() const +{ + return mBinaryBlob.getBytes(); +} + +size_t nx::HierarchicalSha256Header::getSize() const +{ + return mBinaryBlob.getSize(); +} + +void nx::HierarchicalSha256Header::exportBinary() +{ + throw fnd::Exception(kModuleName, "exportBinary() not implemented"); +} + +void nx::HierarchicalSha256Header::importBinary(const byte_t * bytes, size_t len) +{ + if (len < sizeof(nx::sHierarchicalSha256Header)) + { + throw fnd::Exception(kModuleName, "Header too small"); + } + + const nx::sHierarchicalSha256Header* hdr = (const nx::sHierarchicalSha256Header*)bytes; + + if (hdr->layer_num.get() != nx::hierarchicalsha256::kDefaultLevelNum) + { + std::stringstream ss; + ss.clear(); + ss << "Invalid layer count. "; + ss << "(actual=" << hdr->layer_num.get() << ", expected=" << nx::hierarchicalsha256::kDefaultLevelNum << ")"; + throw fnd::Exception(kModuleName, ss.str()); + } + + mMasterHash = hdr->master_hash; + mHashBlockSize = hdr->hash_block_size.get(); + for (size_t i = 0; i < hdr->layer_num.get(); i++) + { + mLayerInfo.addElement({hdr->layer[i].offset.get(), hdr->layer[i].size.get()}); + } +} + +void nx::HierarchicalSha256Header::clear() +{ + memset(mMasterHash.bytes, 0, sizeof(crypto::sha::sSha256Hash)); + mHashBlockSize = 0; + mLayerInfo.clear(); +} + +const crypto::sha::sSha256Hash & nx::HierarchicalSha256Header::getMasterHash() const +{ + return mMasterHash; +} + +void nx::HierarchicalSha256Header::setMasterHash(const crypto::sha::sSha256Hash & master_hash) +{ + mMasterHash = master_hash; +} + +size_t nx::HierarchicalSha256Header::getHashBlockSize() const +{ + return mHashBlockSize; +} + +void nx::HierarchicalSha256Header::setHashBlockSize(size_t hash_block_size) +{ + mHashBlockSize = hash_block_size; +} + +const fnd::List& nx::HierarchicalSha256Header::getLayerInfo() const +{ + return mLayerInfo; +} + +void nx::HierarchicalSha256Header::setLayerInfo(const fnd::List& layer_info) +{ + mLayerInfo = layer_info; +} + +bool nx::HierarchicalSha256Header::isEqual(const HierarchicalSha256Header & other) const +{ + return (mMasterHash == other.mMasterHash) \ + && (mHashBlockSize == other.mHashBlockSize) \ + && (mLayerInfo == other.mLayerInfo); +} + +void nx::HierarchicalSha256Header::copyFrom(const HierarchicalSha256Header & other) +{ + if (other.getSize() != 0) + { + importBinary(other.getBytes(), other.getSize()); + } + else + { + mMasterHash = other.mMasterHash; + mHashBlockSize = other.mHashBlockSize; + mLayerInfo = other.mLayerInfo; + } +}