fs: revise NcaFileSystemDriver for latest semantics
This commit is contained in:
@@ -150,7 +150,7 @@ namespace ams::fssystem::save {
|
||||
m_storage = fs::SubStorage();
|
||||
}
|
||||
|
||||
Result HierarchicalIntegrityVerificationStorage::Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, os::SdkRecursiveMutex *mtx, fs::StorageType storage_type) {
|
||||
Result HierarchicalIntegrityVerificationStorage::Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, IHash256GeneratorFactory *hgf, os::SdkRecursiveMutex *mtx, fs::StorageType storage_type) {
|
||||
/* Validate preconditions. */
|
||||
AMS_ASSERT(bufs != nullptr);
|
||||
AMS_ASSERT(IntegrityMinLayerCount <= info.max_layers && info.max_layers <= IntegrityMaxLayerCount);
|
||||
@@ -168,7 +168,7 @@ namespace ams::fssystem::save {
|
||||
{
|
||||
fs::HashSalt mac;
|
||||
crypto::GenerateHmacSha256Mac(mac.value, sizeof(mac), info.seed.value, sizeof(info.seed), KeyArray[0].key, KeyArray[0].size);
|
||||
m_verify_storages[0].Initialize(storage[HierarchicalStorageInformation::MasterStorage], storage[HierarchicalStorageInformation::Layer1Storage], static_cast<s64>(1) << info.info[0].block_order, HashSize, m_buffers->buffers[m_max_layers - 2], mac, false, storage_type);
|
||||
m_verify_storages[0].Initialize(storage[HierarchicalStorageInformation::MasterStorage], storage[HierarchicalStorageInformation::Layer1Storage], static_cast<s64>(1) << info.info[0].block_order, HashSize, m_buffers->buffers[m_max_layers - 2], hgf, mac, false, storage_type);
|
||||
}
|
||||
|
||||
/* Ensure we don't leak state if further initialization goes wrong. */
|
||||
@@ -203,7 +203,7 @@ namespace ams::fssystem::save {
|
||||
fs::SubStorage buffer_storage(std::addressof(m_buffer_storages[level]), 0, info.info[level].size);
|
||||
fs::HashSalt mac;
|
||||
crypto::GenerateHmacSha256Mac(mac.value, sizeof(mac), info.seed.value, sizeof(info.seed), KeyArray[level + 1].key, KeyArray[level + 1].size);
|
||||
m_verify_storages[level + 1].Initialize(buffer_storage, storage[level + 2], static_cast<s64>(1) << info.info[level + 1].block_order, static_cast<s64>(1) << info.info[level].block_order, m_buffers->buffers[m_max_layers - 2], mac, false, storage_type);
|
||||
m_verify_storages[level + 1].Initialize(buffer_storage, storage[level + 2], static_cast<s64>(1) << info.info[level + 1].block_order, static_cast<s64>(1) << info.info[level].block_order, m_buffers->buffers[m_max_layers - 2], hgf, mac, false, storage_type);
|
||||
}
|
||||
|
||||
/* Initialize the buffer storage. */
|
||||
@@ -217,7 +217,7 @@ namespace ams::fssystem::save {
|
||||
fs::SubStorage buffer_storage(std::addressof(m_buffer_storages[level]), 0, info.info[level].size);
|
||||
fs::HashSalt mac;
|
||||
crypto::GenerateHmacSha256Mac(mac.value, sizeof(mac), info.seed.value, sizeof(info.seed), KeyArray[level + 1].key, KeyArray[level + 1].size);
|
||||
m_verify_storages[level + 1].Initialize(buffer_storage, storage[level + 2], static_cast<s64>(1) << info.info[level + 1].block_order, static_cast<s64>(1) << info.info[level].block_order, m_buffers->buffers[m_max_layers - 2], mac, true, storage_type);
|
||||
m_verify_storages[level + 1].Initialize(buffer_storage, storage[level + 2], static_cast<s64>(1) << info.info[level + 1].block_order, static_cast<s64>(1) << info.info[level].block_order, m_buffers->buffers[m_max_layers - 2], hgf, mac, true, storage_type);
|
||||
}
|
||||
|
||||
/* Initialize the buffer storage. */
|
||||
|
||||
@@ -17,15 +17,19 @@
|
||||
|
||||
namespace ams::fssystem::save {
|
||||
|
||||
Result IntegrityVerificationStorage::Initialize(fs::SubStorage hs, fs::SubStorage ds, s64 verif_block_size, s64 upper_layer_verif_block_size, IBufferManager *bm, const fs::HashSalt &salt, bool is_real_data, fs::StorageType storage_type) {
|
||||
Result IntegrityVerificationStorage::Initialize(fs::SubStorage hs, fs::SubStorage ds, s64 verif_block_size, s64 upper_layer_verif_block_size, IBufferManager *bm, fssystem::IHash256GeneratorFactory *hgf, const fs::HashSalt &salt, bool is_real_data, fs::StorageType storage_type) {
|
||||
/* Validate preconditions. */
|
||||
AMS_ASSERT(verif_block_size >= HashSize);
|
||||
AMS_ASSERT(bm != nullptr);
|
||||
AMS_ASSERT(hgf != nullptr);
|
||||
|
||||
/* Set storages. */
|
||||
m_hash_storage = hs;
|
||||
m_data_storage = ds;
|
||||
|
||||
/* Set hash generator factory. */
|
||||
m_hash_generator_factory = hgf;
|
||||
|
||||
/* Set verification block sizes. */
|
||||
m_verification_block_size = verif_block_size;
|
||||
m_verification_block_order = ILog2(static_cast<u32>(verif_block_size));
|
||||
@@ -111,14 +115,17 @@ namespace ams::fssystem::save {
|
||||
clear_guard.Cancel();
|
||||
}
|
||||
|
||||
/* Verify the signatures. */
|
||||
Result verify_hash_result = ResultSuccess();
|
||||
|
||||
/* Create hash generator. */
|
||||
auto generator = m_hash_generator_factory->Create();
|
||||
|
||||
/* Prepare to validate the signatures. */
|
||||
const auto signature_count = size >> m_verification_block_order;
|
||||
PooledBuffer signature_buffer(signature_count * sizeof(BlockHash), sizeof(BlockHash));
|
||||
const auto buffer_count = std::min(signature_count, signature_buffer.GetSize() / sizeof(BlockHash));
|
||||
|
||||
/* Verify the signatures. */
|
||||
Result verify_hash_result = ResultSuccess();
|
||||
|
||||
size_t verified_count = 0;
|
||||
while (verified_count < signature_count) {
|
||||
/* Read the current signatures. */
|
||||
@@ -132,7 +139,7 @@ namespace ams::fssystem::save {
|
||||
for (size_t i = 0; i < cur_count && R_SUCCEEDED(cur_result); ++i) {
|
||||
const auto verified_size = (verified_count + i) << m_verification_block_order;
|
||||
u8 *cur_buf = static_cast<u8 *>(buffer) + verified_size;
|
||||
cur_result = this->VerifyHash(cur_buf, reinterpret_cast<BlockHash *>(signature_buffer.GetBuffer()) + i);
|
||||
cur_result = this->VerifyHash(cur_buf, reinterpret_cast<BlockHash *>(signature_buffer.GetBuffer()) + i, generator);
|
||||
|
||||
/* If the data is corrupted, clear the corrupted parts. */
|
||||
if (fs::ResultIntegrityVerificationStorageCorrupted::Includes(cur_result)) {
|
||||
@@ -211,6 +218,8 @@ namespace ams::fssystem::save {
|
||||
PooledBuffer signature_buffer(signature_count * sizeof(BlockHash), sizeof(BlockHash));
|
||||
const auto buffer_count = std::min(signature_count, signature_buffer.GetSize() / sizeof(BlockHash));
|
||||
|
||||
auto generator = m_hash_generator_factory->Create();
|
||||
|
||||
while (updated_count < signature_count) {
|
||||
const auto cur_count = std::min(buffer_count, signature_count - updated_count);
|
||||
|
||||
@@ -220,7 +229,7 @@ namespace ams::fssystem::save {
|
||||
|
||||
for (size_t i = 0; i < cur_count; ++i) {
|
||||
const auto updated_size = (updated_count + i) << m_verification_block_order;
|
||||
this->CalcBlockHash(reinterpret_cast<BlockHash *>(signature_buffer.GetBuffer()) + i, reinterpret_cast<const u8 *>(buffer) + updated_size);
|
||||
this->CalcBlockHash(reinterpret_cast<BlockHash *>(signature_buffer.GetBuffer()) + i, reinterpret_cast<const u8 *>(buffer) + updated_size, generator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,19 +369,18 @@ namespace ams::fssystem::save {
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrityVerificationStorage::CalcBlockHash(BlockHash *out, const void *buffer, size_t block_size) const {
|
||||
/* Create a sha256 generator. */
|
||||
crypto::Sha256Generator sha;
|
||||
sha.Initialize();
|
||||
void IntegrityVerificationStorage::CalcBlockHash(BlockHash *out, const void *buffer, size_t block_size, std::unique_ptr<fssystem::IHash256Generator> &generator) const {
|
||||
/* Initialize the generator. */
|
||||
generator->Initialize();
|
||||
|
||||
/* If calculating for save data, hash the salt. */
|
||||
if (m_storage_type == fs::StorageType_SaveData) {
|
||||
sha.Update(m_salt.value, sizeof(m_salt));
|
||||
generator->Update(m_salt.value, sizeof(m_salt));
|
||||
}
|
||||
|
||||
/* Update with the buffer and get the hash. */
|
||||
sha.Update(buffer, block_size);
|
||||
sha.GetHash(out, sizeof(*out));
|
||||
generator->Update(buffer, block_size);
|
||||
generator->GetHash(out, sizeof(*out));
|
||||
|
||||
/* Set the validation bit, if the hash is for save data. */
|
||||
if (m_storage_type == fs::StorageType_SaveData) {
|
||||
@@ -428,7 +436,7 @@ namespace ams::fssystem::save {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result IntegrityVerificationStorage::VerifyHash(const void *buf, BlockHash *hash) {
|
||||
Result IntegrityVerificationStorage::VerifyHash(const void *buf, BlockHash *hash, std::unique_ptr<fssystem::IHash256Generator> &generator) {
|
||||
/* Validate preconditions. */
|
||||
AMS_ASSERT(buf != nullptr);
|
||||
AMS_ASSERT(hash != nullptr);
|
||||
@@ -445,7 +453,7 @@ namespace ams::fssystem::save {
|
||||
|
||||
/* Get the calculated hash. */
|
||||
BlockHash calc_hash;
|
||||
this->CalcBlockHash(std::addressof(calc_hash), buf);
|
||||
this->CalcBlockHash(std::addressof(calc_hash), buf, generator);
|
||||
|
||||
/* Check that the signatures are equal. */
|
||||
if (!crypto::IsSameBytes(std::addressof(cmp_hash), std::addressof(calc_hash), sizeof(BlockHash))) {
|
||||
|
||||
Reference in New Issue
Block a user