[nstool] Rename HashTreeMeta to LayeredIntegrityMetadata and associated WrappedIFile. Improved low couling in LayeredIntegrityMetadata.

This commit is contained in:
jakcron 2018-10-06 13:31:24 +08:00
parent 9e86d96b84
commit 0c4103a620
9 changed files with 180 additions and 197 deletions

View file

@ -184,9 +184,9 @@
<ClInclude Include="source\common.h" />
<ClInclude Include="source\ElfSymbolParser.h" />
<ClInclude Include="source\EsTikProcess.h" />
<ClInclude Include="source\HashTreeMeta.h" />
<ClInclude Include="source\HashTreeWrappedIFile.h" />
<ClInclude Include="source\KeyConfiguration.h" />
<ClInclude Include="source\LayeredIntegrityMetadata.h" />
<ClInclude Include="source\LayeredIntegrityWrappedIFile.h" />
<ClInclude Include="source\NacpProcess.h" />
<ClInclude Include="source\NcaProcess.h" />
<ClInclude Include="source\NpdmProcess.h" />
@ -209,9 +209,9 @@
<ClCompile Include="source\CnmtProcess.cpp" />
<ClCompile Include="source\ElfSymbolParser.cpp" />
<ClCompile Include="source\EsTikProcess.cpp" />
<ClCompile Include="source\HashTreeMeta.cpp" />
<ClCompile Include="source\HashTreeWrappedIFile.cpp" />
<ClCompile Include="source\KeyConfiguration.cpp" />
<ClCompile Include="source\LayeredIntegrityMetadata.cpp" />
<ClCompile Include="source\LayeredIntegrityWrappedIFile.cpp" />
<ClCompile Include="source\main.cpp" />
<ClCompile Include="source\NacpProcess.cpp" />
<ClCompile Include="source\NcaProcess.cpp" />

View file

@ -28,21 +28,24 @@
<ClInclude Include="source\CnmtProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\ElfSymbolParser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\EsTikProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\HashTreeMeta.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\HashTreeWrappedIFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\KeyConfiguration.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\LayeredIntegrityMetadata.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\LayeredIntegrityWrappedIFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\NacpProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -88,9 +91,6 @@
<ClInclude Include="source\XciProcess.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="source\common.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\AesCtrWrappedIFile.cpp">
@ -108,15 +108,15 @@
<ClCompile Include="source\EsTikProcess.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\HashTreeMeta.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\HashTreeWrappedIFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\KeyConfiguration.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\LayeredIntegrityMetadata.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\LayeredIntegrityWrappedIFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>

View file

@ -1,135 +0,0 @@
#include "HashTreeMeta.h"
HashTreeMeta::HashTreeMeta() :
mLayerInfo(),
mDataLayer(),
mMasterHashList(),
mDoAlignHashToBlock(false)
{
}
HashTreeMeta::HashTreeMeta(const byte_t* data, size_t len, HashTreeType type) :
HashTreeMeta()
{
importData(data, len, type);
}
void HashTreeMeta::operator=(const HashTreeMeta& other)
{
mLayerInfo = other.mLayerInfo;
mDataLayer = other.mDataLayer;
mMasterHashList = other.mMasterHashList;
mDoAlignHashToBlock = other.mDoAlignHashToBlock;
}
bool HashTreeMeta::operator==(const HashTreeMeta& other) const
{
return (mLayerInfo == other.mLayerInfo) \
&& (mDataLayer == other.mDataLayer) \
&& (mMasterHashList == other.mMasterHashList) \
&& (mDoAlignHashToBlock == other.mDoAlignHashToBlock);
}
bool HashTreeMeta::operator!=(const HashTreeMeta& other) const
{
return !(*this == other);
}
void HashTreeMeta::importData(const byte_t* data, size_t len, HashTreeType type)
{
if (type == HASH_TYPE_INTEGRITY)
{
nn::hac::HierarchicalIntegrityHeader hdr;
hdr.fromBytes(data, len);
importHierarchicalIntergityHeader(hdr);
}
else if (type == HASH_TYPE_SHA256)
{
nn::hac::HierarchicalSha256Header hdr;
hdr.fromBytes(data, len);
importHierarchicalSha256Header(hdr);
}
}
const fnd::List<HashTreeMeta::sLayer>& HashTreeMeta::getHashLayerInfo() const
{
return mLayerInfo;
}
void HashTreeMeta::setHashLayerInfo(const fnd::List<sLayer>& layer_info)
{
mLayerInfo = layer_info;
}
const HashTreeMeta::sLayer& HashTreeMeta::getDataLayer() const
{
return mDataLayer;
}
void HashTreeMeta::setDataLayer(const sLayer& data_info)
{
mDataLayer = data_info;
}
const fnd::List<fnd::sha::sSha256Hash>& HashTreeMeta::getMasterHashList() const
{
return mMasterHashList;
}
void HashTreeMeta::setMasterHashList(const fnd::List<fnd::sha::sSha256Hash>& master_hash_list)
{
mMasterHashList = master_hash_list;
}
bool HashTreeMeta::getAlignHashToBlock() const
{
return mDoAlignHashToBlock;
}
void HashTreeMeta::setAlignHashToBlock(bool doAlign)
{
mDoAlignHashToBlock = doAlign;
}
void HashTreeMeta::importHierarchicalIntergityHeader(const nn::hac::HierarchicalIntegrityHeader& hdr)
{
mDoAlignHashToBlock = true;
for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
{
sLayer layer;
layer.offset = hdr.getLayerInfo()[i].offset;
layer.size = hdr.getLayerInfo()[i].size;
layer.block_size = _BIT(hdr.getLayerInfo()[i].block_size);
if (i+1 == hdr.getLayerInfo().size())
{
mDataLayer = layer;
}
else
{
mLayerInfo.addElement(layer);
}
}
mMasterHashList = hdr.getMasterHashList();
}
void HashTreeMeta::importHierarchicalSha256Header(const nn::hac::HierarchicalSha256Header& hdr)
{
mDoAlignHashToBlock = false;
for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
{
sLayer layer;
layer.offset = hdr.getLayerInfo()[i].offset;
layer.size = hdr.getLayerInfo()[i].size;
layer.block_size = hdr.getHashBlockSize();
if (i+1 == hdr.getLayerInfo().size())
{
mDataLayer = layer;
}
else
{
mLayerInfo.addElement(layer);
}
}
mMasterHashList.addElement(hdr.getMasterHash());
}

View file

@ -0,0 +1,71 @@
#include "LayeredIntegrityMetadata.h"
LayeredIntegrityMetadata::LayeredIntegrityMetadata() :
mLayerInfo(),
mDataLayer(),
mMasterHashList(),
mDoAlignHashToBlock(false)
{
}
void LayeredIntegrityMetadata::operator=(const LayeredIntegrityMetadata& other)
{
mLayerInfo = other.mLayerInfo;
mDataLayer = other.mDataLayer;
mMasterHashList = other.mMasterHashList;
mDoAlignHashToBlock = other.mDoAlignHashToBlock;
}
bool LayeredIntegrityMetadata::operator==(const LayeredIntegrityMetadata& other) const
{
return (mLayerInfo == other.mLayerInfo) \
&& (mDataLayer == other.mDataLayer) \
&& (mMasterHashList == other.mMasterHashList) \
&& (mDoAlignHashToBlock == other.mDoAlignHashToBlock);
}
bool LayeredIntegrityMetadata::operator!=(const LayeredIntegrityMetadata& other) const
{
return !(*this == other);
}
const fnd::List<LayeredIntegrityMetadata::sLayer>& LayeredIntegrityMetadata::getHashLayerInfo() const
{
return mLayerInfo;
}
void LayeredIntegrityMetadata::setHashLayerInfo(const fnd::List<sLayer>& layer_info)
{
mLayerInfo = layer_info;
}
const LayeredIntegrityMetadata::sLayer& LayeredIntegrityMetadata::getDataLayer() const
{
return mDataLayer;
}
void LayeredIntegrityMetadata::setDataLayerInfo(const sLayer& data_info)
{
mDataLayer = data_info;
}
const fnd::List<fnd::sha::sSha256Hash>& LayeredIntegrityMetadata::getMasterHashList() const
{
return mMasterHashList;
}
void LayeredIntegrityMetadata::setMasterHashList(const fnd::List<fnd::sha::sSha256Hash>& master_hash_list)
{
mMasterHashList = master_hash_list;
}
bool LayeredIntegrityMetadata::getAlignHashToBlock() const
{
return mDoAlignHashToBlock;
}
void LayeredIntegrityMetadata::setAlignHashToBlock(bool doAlign)
{
mDoAlignHashToBlock = doAlign;
}

View file

@ -2,15 +2,9 @@
#include <nn/hac/HierarchicalIntegrityHeader.h>
#include <nn/hac/HierarchicalSha256Header.h>
class HashTreeMeta
class LayeredIntegrityMetadata
{
public:
enum HashTreeType
{
HASH_TYPE_INTEGRITY,
HASH_TYPE_SHA256
};
struct sLayer
{
size_t offset;
@ -35,20 +29,17 @@ public:
}
};
HashTreeMeta();
HashTreeMeta(const byte_t* data, size_t len, HashTreeType type);
LayeredIntegrityMetadata();
void operator=(const HashTreeMeta& other);
bool operator==(const HashTreeMeta& other) const;
bool operator!=(const HashTreeMeta& other) const;
void importData(const byte_t* data, size_t len, HashTreeType type);
void operator=(const LayeredIntegrityMetadata& other);
bool operator==(const LayeredIntegrityMetadata& other) const;
bool operator!=(const LayeredIntegrityMetadata& other) const;
const fnd::List<sLayer>& getHashLayerInfo() const;
void setHashLayerInfo(const fnd::List<sLayer>& layer_info);
const sLayer& getDataLayer() const;
void setDataLayer(const sLayer& data_info);
void setDataLayerInfo(const sLayer& data_info);
const fnd::List<fnd::sha::sSha256Hash>& getMasterHashList() const;
void setMasterHashList(const fnd::List<fnd::sha::sSha256Hash>& master_hash_list);
@ -56,13 +47,9 @@ public:
bool getAlignHashToBlock() const;
void setAlignHashToBlock(bool doAlign);
private:
// data
fnd::List<sLayer> mLayerInfo;
sLayer mDataLayer;
fnd::List<fnd::sha::sSha256Hash> mMasterHashList;
bool mDoAlignHashToBlock;
void importHierarchicalIntergityHeader(const nn::hac::HierarchicalIntegrityHeader& hdr);
void importHierarchicalSha256Header(const nn::hac::HierarchicalSha256Header& hdr);
};

View file

@ -1,8 +1,8 @@
#include "common.h"
#include "HashTreeWrappedIFile.h"
#include "LayeredIntegrityWrappedIFile.h"
#include "OffsetAdjustedIFile.h"
HashTreeWrappedIFile::HashTreeWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const HashTreeMeta& hdr) :
LayeredIntegrityWrappedIFile::LayeredIntegrityWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const LayeredIntegrityMetadata& hdr) :
mFile(file),
mData(nullptr),
mDataHashLayer(),
@ -11,17 +11,17 @@ HashTreeWrappedIFile::HashTreeWrappedIFile(const fnd::SharedPtr<fnd::IFile>& fil
initialiseDataLayer(hdr);
}
size_t HashTreeWrappedIFile::size()
size_t LayeredIntegrityWrappedIFile::size()
{
return (*mData)->size();
}
void HashTreeWrappedIFile::seek(size_t offset)
void LayeredIntegrityWrappedIFile::seek(size_t offset)
{
mDataOffset = offset;
}
void HashTreeWrappedIFile::read(byte_t* out, size_t len)
void LayeredIntegrityWrappedIFile::read(byte_t* out, size_t len)
{
struct sBlockPosition
{
@ -72,23 +72,23 @@ void HashTreeWrappedIFile::read(byte_t* out, size_t len)
seek(mDataOffset + len);
}
void HashTreeWrappedIFile::read(byte_t* out, size_t offset, size_t len)
void LayeredIntegrityWrappedIFile::read(byte_t* out, size_t offset, size_t len)
{
seek(offset);
read(out, len);
}
void HashTreeWrappedIFile::write(const byte_t* out, size_t len)
void LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t len)
{
throw fnd::Exception(kModuleName, "write() not supported");
}
void HashTreeWrappedIFile::write(const byte_t* out, size_t offset, size_t len)
void LayeredIntegrityWrappedIFile::write(const byte_t* out, size_t offset, size_t len)
{
throw fnd::Exception(kModuleName, "write() not supported");
}
void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
void LayeredIntegrityWrappedIFile::initialiseDataLayer(const LayeredIntegrityMetadata& hdr)
{
fnd::sha::sSha256Hash hash;
fnd::Vec<byte_t> cur, prev;
@ -106,7 +106,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
for (size_t i = 0; i < hdr.getHashLayerInfo().size(); i++)
{
// get block size
const HashTreeMeta::sLayer& layer = hdr.getHashLayerInfo()[i];
const LayeredIntegrityMetadata::sLayer& layer = hdr.getHashLayerInfo()[i];
// allocate layer
cur.alloc(align(layer.size, layer.block_size));
@ -152,7 +152,7 @@ void HashTreeWrappedIFile::initialiseDataLayer(const HashTreeMeta& hdr)
mCache.alloc(cache_size);
}
void HashTreeWrappedIFile::readData(size_t block_offset, size_t block_num)
void LayeredIntegrityWrappedIFile::readData(size_t block_offset, size_t block_num)
{
fnd::sha::sSha256Hash hash;

View file

@ -4,13 +4,13 @@
#include <fnd/SharedPtr.h>
#include <fnd/Vec.h>
#include <fnd/sha.h>
#include "HashTreeMeta.h"
#include "LayeredIntegrityMetadata.h"
class HashTreeWrappedIFile : public fnd::IFile
class LayeredIntegrityWrappedIFile : public fnd::IFile
{
public:
HashTreeWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const HashTreeMeta& hdr);
LayeredIntegrityWrappedIFile(const fnd::SharedPtr<fnd::IFile>& file, const LayeredIntegrityMetadata& hdr);
size_t size();
void seek(size_t offset);
@ -19,7 +19,7 @@ public:
void write(const byte_t* out, size_t len);
void write(const byte_t* out, size_t offset, size_t len);
private:
const std::string kModuleName = "HashTreeWrappedIFile";
const std::string kModuleName = "LayeredIntegrityWrappedIFile";
static const size_t kDefaultCacheSize = 0x10000;
std::stringstream mErrorSs;
@ -40,6 +40,6 @@ private:
inline size_t getRemanderBlockReadSize(size_t total_size) const { return total_size % mDataBlockSize; }
inline size_t getBlockNum(size_t total_size) const { return (total_size / mDataBlockSize) + (getRemanderBlockReadSize(total_size) > 0); }
void initialiseDataLayer(const HashTreeMeta& hdr);
void initialiseDataLayer(const LayeredIntegrityMetadata& hdr);
void readData(size_t block_offset, size_t block_num);
};

View file

@ -10,7 +10,7 @@
#include "NpdmProcess.h"
#include "OffsetAdjustedIFile.h"
#include "AesCtrWrappedIFile.h"
#include "HashTreeWrappedIFile.h"
#include "LayeredIntegrityWrappedIFile.h"
NcaProcess::NcaProcess() :
mFile(),
@ -258,9 +258,69 @@ void NcaProcess::generatePartitionConfiguration()
info.hash_type = (nn::hac::nca::HashType)fs_header.hash_type;
info.enc_type = (nn::hac::nca::EncryptionType)fs_header.encryption_type;
if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256)
info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, HashTreeMeta::HASH_TYPE_SHA256);
{
// info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, LayeredIntegrityMetadata::HASH_TYPE_SHA256);
nn::hac::HierarchicalSha256Header hdr;
fnd::List<LayeredIntegrityMetadata::sLayer> hash_layers;
LayeredIntegrityMetadata::sLayer data_layer;
fnd::List<fnd::sha::sSha256Hash> master_hash_list;
// import raw data
hdr.fromBytes(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen);
for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
{
LayeredIntegrityMetadata::sLayer layer;
layer.offset = hdr.getLayerInfo()[i].offset;
layer.size = hdr.getLayerInfo()[i].size;
layer.block_size = hdr.getHashBlockSize();
if (i + 1 == hdr.getLayerInfo().size())
{
data_layer = layer;
}
else
{
hash_layers.addElement(layer);
}
}
master_hash_list.addElement(hdr.getMasterHash());
// write data into metadata
info.layered_intergrity_metadata.setAlignHashToBlock(false);
info.layered_intergrity_metadata.setHashLayerInfo(hash_layers);
info.layered_intergrity_metadata.setDataLayerInfo(data_layer);
info.layered_intergrity_metadata.setMasterHashList(master_hash_list);
}
else if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY)
info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, HashTreeMeta::HASH_TYPE_INTEGRITY);
{
// info.hash_tree_meta.importData(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen, LayeredIntegrityMetadata::HASH_TYPE_INTEGRITY);
nn::hac::HierarchicalIntegrityHeader hdr;
fnd::List<LayeredIntegrityMetadata::sLayer> hash_layers;
LayeredIntegrityMetadata::sLayer data_layer;
fnd::List<fnd::sha::sSha256Hash> master_hash_list;
hdr.fromBytes(fs_header.hash_superblock, nn::hac::nca::kFsHeaderHashSuperblockLen);
for (size_t i = 0; i < hdr.getLayerInfo().size(); i++)
{
LayeredIntegrityMetadata::sLayer layer;
layer.offset = hdr.getLayerInfo()[i].offset;
layer.size = hdr.getLayerInfo()[i].size;
layer.block_size = _BIT(hdr.getLayerInfo()[i].block_size);
if (i + 1 == hdr.getLayerInfo().size())
{
data_layer = layer;
}
else
{
hash_layers.addElement(layer);
}
}
// write data into metadata
info.layered_intergrity_metadata.setAlignHashToBlock(true);
info.layered_intergrity_metadata.setHashLayerInfo(hash_layers);
info.layered_intergrity_metadata.setDataLayerInfo(data_layer);
info.layered_intergrity_metadata.setMasterHashList(hdr.getMasterHashList());
}
// create reader
try
@ -304,7 +364,7 @@ void NcaProcess::generatePartitionConfiguration()
// filter out unrecognised hash types, and hash based readers
if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256 || info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY)
{
info.reader = new HashTreeWrappedIFile(info.reader, info.hash_tree_meta);
info.reader = new LayeredIntegrityWrappedIFile(info.reader, info.layered_intergrity_metadata);
}
else if (info.hash_type != nn::hac::nca::HASH_NONE)
{
@ -440,7 +500,7 @@ void NcaProcess::displayHeader()
}
if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_INTERGRITY)
{
HashTreeMeta& hash_hdr = info.hash_tree_meta;
LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata;
std::cout << " HierarchicalIntegrity Header:" << std::endl;
for (size_t j = 0; j < hash_hdr.getHashLayerInfo().size(); j++)
{
@ -463,7 +523,7 @@ void NcaProcess::displayHeader()
}
else if (info.hash_type == nn::hac::nca::HASH_HIERARCHICAL_SHA256)
{
HashTreeMeta& hash_hdr = info.hash_tree_meta;
LayeredIntegrityMetadata& hash_hdr = info.layered_intergrity_metadata;
std::cout << " HierarchicalSha256 Header:" << std::endl;
std::cout << " Master Hash:" << std::endl;
std::cout << " " << fnd::SimpleTextOutput::arrayToString(hash_hdr.getMasterHashList()[0].bytes, 0x10, true, ":") << std::endl;

View file

@ -4,7 +4,7 @@
#include <fnd/IFile.h>
#include <fnd/SharedPtr.h>
#include <nn/hac/NcaHeader.h>
#include "HashTreeMeta.h"
#include "LayeredIntegrityMetadata.h"
#include "KeyConfiguration.h"
@ -100,7 +100,7 @@ private:
nn::hac::nca::FormatType format_type;
nn::hac::nca::HashType hash_type;
nn::hac::nca::EncryptionType enc_type;
HashTreeMeta hash_tree_meta;
LayeredIntegrityMetadata layered_intergrity_metadata;
fnd::aes::sAesIvCtr aes_ctr;
} mPartitions[nn::hac::nca::kPartitionNum];