diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h new file mode 100644 index 000000000..5cf697efe --- /dev/null +++ b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h @@ -0,0 +1,164 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/alignment.h" +#include "core/file_sys/fssystem/fs_i_storage.h" +#include "core/file_sys/fssystem/fs_types.h" +#include "core/file_sys/fssystem/fssystem_alignment_matching_storage.h" +#include "core/file_sys/fssystem/fssystem_integrity_verification_storage.h" +#include "core/file_sys/vfs_offset.h" + +namespace FileSys { + +struct HierarchicalIntegrityVerificationLevelInformation { + Int64 offset; + Int64 size; + s32 block_order; + std::array<u8, 4> reserved; +}; +static_assert(std::is_trivial_v<HierarchicalIntegrityVerificationLevelInformation>); +static_assert(sizeof(HierarchicalIntegrityVerificationLevelInformation) == 0x18); +static_assert(alignof(HierarchicalIntegrityVerificationLevelInformation) == 0x4); + +struct HierarchicalIntegrityVerificationInformation { + u32 max_layers; + std::array<HierarchicalIntegrityVerificationLevelInformation, IntegrityMaxLayerCount - 1> info; + HashSalt seed; + + s64 GetLayeredHashSize() const { + return this->info[this->max_layers - 2].offset; + } + + s64 GetDataOffset() const { + return this->info[this->max_layers - 2].offset; + } + + s64 GetDataSize() const { + return this->info[this->max_layers - 2].size; + } +}; +static_assert(std::is_trivial_v<HierarchicalIntegrityVerificationInformation>); + +struct HierarchicalIntegrityVerificationMetaInformation { + u32 magic; + u32 version; + u32 master_hash_size; + HierarchicalIntegrityVerificationInformation level_hash_info; +}; +static_assert(std::is_trivial_v<HierarchicalIntegrityVerificationMetaInformation>); + +struct HierarchicalIntegrityVerificationSizeSet { + s64 control_size; + s64 master_hash_size; + std::array<s64, IntegrityMaxLayerCount - 2> layered_hash_sizes; +}; +static_assert(std::is_trivial_v<HierarchicalIntegrityVerificationSizeSet>); + +class HierarchicalIntegrityVerificationStorage : public IReadOnlyStorage { + YUZU_NON_COPYABLE(HierarchicalIntegrityVerificationStorage); + YUZU_NON_MOVEABLE(HierarchicalIntegrityVerificationStorage); + +public: + using GenerateRandomFunction = void (*)(void* dst, size_t size); + + class HierarchicalStorageInformation { + public: + enum { + MasterStorage = 0, + Layer1Storage = 1, + Layer2Storage = 2, + Layer3Storage = 3, + Layer4Storage = 4, + Layer5Storage = 5, + DataStorage = 6, + }; + + private: + std::array<VirtualFile, DataStorage + 1> m_storages; + + public: + void SetMasterHashStorage(VirtualFile s) { + m_storages[MasterStorage] = s; + } + void SetLayer1HashStorage(VirtualFile s) { + m_storages[Layer1Storage] = s; + } + void SetLayer2HashStorage(VirtualFile s) { + m_storages[Layer2Storage] = s; + } + void SetLayer3HashStorage(VirtualFile s) { + m_storages[Layer3Storage] = s; + } + void SetLayer4HashStorage(VirtualFile s) { + m_storages[Layer4Storage] = s; + } + void SetLayer5HashStorage(VirtualFile s) { + m_storages[Layer5Storage] = s; + } + void SetDataStorage(VirtualFile s) { + m_storages[DataStorage] = s; + } + + VirtualFile& operator[](s32 index) { + ASSERT(MasterStorage <= index && index <= DataStorage); + return m_storages[index]; + } + }; + +public: + HierarchicalIntegrityVerificationStorage(); + virtual ~HierarchicalIntegrityVerificationStorage() override { + this->Finalize(); + } + + Result Initialize(const HierarchicalIntegrityVerificationInformation& info, + HierarchicalStorageInformation storage, int max_data_cache_entries, + int max_hash_cache_entries, s8 buffer_level); + void Finalize(); + + virtual size_t Read(u8* buffer, size_t size, size_t offset) const override; + virtual size_t GetSize() const override; + + bool IsInitialized() const { + return m_data_size >= 0; + } + + s64 GetL1HashVerificationBlockSize() const { + return m_verify_storages[m_max_layers - 2]->GetBlockSize(); + } + + VirtualFile GetL1HashStorage() { + return std::make_shared<OffsetVfsFile>( + m_buffer_storages[m_max_layers - 3], + Common::DivideUp(m_data_size, this->GetL1HashVerificationBlockSize()), 0); + } + +public: + static constexpr s8 GetDefaultDataCacheBufferLevel(u32 max_layers) { + return static_cast<s8>(16 + max_layers - 2); + } + +protected: + static constexpr s64 HashSize = 256 / 8; + static constexpr size_t MaxLayers = IntegrityMaxLayerCount; + +private: + static GenerateRandomFunction s_generate_random; + + static void SetGenerateRandomFunction(GenerateRandomFunction func) { + s_generate_random = func; + } + +private: + friend struct HierarchicalIntegrityVerificationMetaInformation; + +private: + std::array<std::shared_ptr<IntegrityVerificationStorage>, MaxLayers - 1> m_verify_storages; + std::array<VirtualFile, MaxLayers - 1> m_buffer_storages; + s64 m_data_size; + s32 m_max_layers; +}; + +} // namespace FileSys |