Skip to content

Commit

Permalink
fs: update nca drivers (and dependents/callees) for 14.0.0 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
SciresM committed Mar 25, 2022
1 parent 20e53fc commit ec44eaa
Show file tree
Hide file tree
Showing 24 changed files with 1,495 additions and 461 deletions.
3 changes: 3 additions & 0 deletions libraries/libstratosphere/include/stratosphere/fssystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
#include <stratosphere/fssystem/fssystem_crypto_configuration.hpp>
#include <stratosphere/fssystem/fssystem_compression_configuration.hpp>
#include <stratosphere/fssystem/fssystem_aes_ctr_counter_extended_storage.hpp>
#include <stratosphere/fssystem/fssystem_aes_ctr_storage_external.hpp>
#include <stratosphere/fssystem/fssystem_aes_xts_storage_external.hpp>
#include <stratosphere/fssystem/fssystem_switch_storage.hpp>
#include <stratosphere/fssystem/buffers/fssystem_buffer_manager_utils.hpp>
#include <stratosphere/fssystem/buffers/fssystem_file_system_buffer_manager.hpp>
#include <stratosphere/fssystem/fssystem_pooled_buffer.hpp>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace ams::fssystem {

using IAllocator = BucketTree::IAllocator;

using DecryptFunction = void(*)(void *dst, size_t dst_size, s32 index, const void *enc_key, size_t enc_key_size, const void *iv, size_t iv_size, const void *src, size_t src_size);
using DecryptFunction = void(*)(void *dst, size_t dst_size, u8 index, u8 gen, const void *enc_key, size_t enc_key_size, const void *iv, size_t iv_size, const void *src, size_t src_size);

class IDecryptor {
public:
Expand Down Expand Up @@ -72,7 +72,7 @@ namespace ams::fssystem {
return BucketTree::QueryEntryStorageSize(NodeSize, sizeof(Entry), entry_count);
}

static Result CreateExternalDecryptor(std::unique_ptr<IDecryptor> *out, DecryptFunction func, s32 key_index);
static Result CreateExternalDecryptor(std::unique_ptr<IDecryptor> *out, DecryptFunction func, s32 key_index, s32 key_generation);
static Result CreateSoftwareDecryptor(std::unique_ptr<IDecryptor> *out);
private:
BucketTree m_table;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/fs/fs_istorage.hpp>
#include <stratosphere/fs/impl/fs_newable.hpp>
#include <stratosphere/fssystem/fssystem_nca_file_system_driver.hpp>

namespace ams::fssystem {

/* ACCURATE_TO_VERSION: 14.3.0.0 */
class AesCtrStorageExternal : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
NON_COPYABLE(AesCtrStorageExternal);
NON_MOVEABLE(AesCtrStorageExternal);
public:
static constexpr size_t BlockSize = crypto::Aes128CtrEncryptor::BlockSize;
static constexpr size_t KeySize = crypto::Aes128CtrEncryptor::KeySize;
static constexpr size_t IvSize = crypto::Aes128CtrEncryptor::IvSize;
private:
std::shared_ptr<fs::IStorage> m_base_storage;
u8 m_iv[IvSize];
DecryptAesCtrFunction m_decrypt_function;
s32 m_key_index;
s32 m_key_generation;
u8 m_encrypted_key[KeySize];
public:
AesCtrStorageExternal(std::shared_ptr<fs::IStorage> bs, const void *enc_key, size_t enc_key_size, const void *iv, size_t iv_size, DecryptAesCtrFunction df, s32 kidx, s32 kgen);

virtual Result Read(s64 offset, void *buffer, size_t size) override;
virtual Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
virtual Result GetSize(s64 *out) override;
virtual Result Flush() override;
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
virtual Result SetSize(s64 size) override;
};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/fs/fs_istorage.hpp>
#include <stratosphere/fs/impl/fs_newable.hpp>
#include <stratosphere/fssystem/fssystem_nca_file_system_driver.hpp>

namespace ams::fssystem {

/* ACCURATE_TO_VERSION: 14.3.0.0 */
template<fs::PointerToStorage BasePointer>
class AesXtsStorageExternal : public ::ams::fs::IStorage, public ::ams::fs::impl::Newable {
NON_COPYABLE(AesXtsStorageExternal);
NON_MOVEABLE(AesXtsStorageExternal);
public:
static constexpr size_t AesBlockSize = crypto::Aes128XtsEncryptor::BlockSize;
static constexpr size_t KeySize = crypto::Aes128XtsEncryptor::KeySize;
static constexpr size_t IvSize = crypto::Aes128XtsEncryptor::IvSize;
private:
BasePointer m_base_storage;
char m_key[2][KeySize];
char m_iv[IvSize];
const size_t m_block_size;
CryptAesXtsFunction m_encrypt_function;
CryptAesXtsFunction m_decrypt_function;
public:
AesXtsStorageExternal(BasePointer bs, const void *key1, const void *key2, size_t key_size, const void *iv, size_t iv_size, size_t block_size, CryptAesXtsFunction ef, CryptAesXtsFunction df);

virtual Result Read(s64 offset, void *buffer, size_t size) override;
virtual Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override;
virtual Result GetSize(s64 *out) override;
virtual Result Flush() override;
virtual Result Write(s64 offset, const void *buffer, size_t size) override;
virtual Result SetSize(s64 size) override;
};

using AesXtsStorageExternalByPointer = AesXtsStorageExternal<fs::IStorage *>;
using AesXtsStorageExternalBySharedPointer = AesXtsStorageExternal<std::shared_ptr<fs::IStorage>>;

}
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ namespace ams::fssystem {
size_t m_verification_block_shift;
s32 m_flags;
s32 m_buffer_level;
fs::StorageType m_storage_type;
BlockCacheManager m_block_cache_manager;
bool m_is_writable;
public:
BlockCacheBufferedStorage();
virtual ~BlockCacheBufferedStorage() override;

Result Initialize(fs::IBufferManager *bm, os::SdkRecursiveMutex *mtx, IStorage *data, s64 data_size, size_t verif_block_size, s32 max_cache_entries, bool is_real_data, s8 buffer_level, bool is_keep_burst_mode, fs::StorageType storage_type);
Result Initialize(fs::IBufferManager *bm, os::SdkRecursiveMutex *mtx, IStorage *data, s64 data_size, size_t verif_block_size, s32 max_cache_entries, bool is_real_data, s8 buffer_level, bool is_keep_burst_mode, bool is_writable);
void Finalize();

virtual Result Read(s64 offset, void *buffer, size_t size) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

namespace ams::fssystem {

/* ACCURATE_TO_VERSION: Unknown */
/* ACCURATE_TO_VERSION: 14.3.0.0 */

struct HierarchicalIntegrityVerificationLevelInformation {
fs::Int64 offset;
Expand Down Expand Up @@ -151,20 +151,25 @@ namespace ams::fssystem {
os::SdkRecursiveMutex *m_mutex;
IntegrityVerificationStorage m_verify_storages[MaxLayers - 1];
BlockCacheBufferedStorage m_buffer_storages[MaxLayers - 1];
os::Semaphore *m_read_semaphore;
os::Semaphore *m_write_semaphore;
s64 m_data_size;
s32 m_max_layers;
bool m_is_written_for_rollback;
public:
HierarchicalIntegrityVerificationStorage() : m_buffers(nullptr), m_mutex(nullptr), m_data_size(-1), m_is_written_for_rollback(false) { /* ... */ }
HierarchicalIntegrityVerificationStorage() : m_buffers(nullptr), m_mutex(nullptr), m_data_size(-1) { /* ... */ }
virtual ~HierarchicalIntegrityVerificationStorage() override { this->Finalize(); }

Result Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, IHash256GeneratorFactory *hgf, os::SdkRecursiveMutex *mtx, fs::StorageType storage_type);
Result Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, IHash256GeneratorFactory *hgf, bool hash_salt_enabled, os::SdkRecursiveMutex *mtx, os::Semaphore *read_sema, os::Semaphore *write_sema, int max_data_cache_entries, int max_hash_cache_entries, s8 buffer_level, bool is_writable, bool allow_cleared_blocks);
Result Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, IHash256GeneratorFactory *hgf, bool hash_salt_enabled, os::SdkRecursiveMutex *mtx, int max_data_cache_entries, int max_hash_cache_entries, s8 buffer_level, bool is_writable, bool allow_cleared_blocks) {
R_RETURN(this->Initialize(info, storage, bufs, hgf, hash_salt_enabled, mtx, nullptr, nullptr, max_data_cache_entries, max_hash_cache_entries, buffer_level, is_writable, allow_cleared_blocks));
}

void Finalize();

virtual Result Read(s64 offset, void *buffer, size_t size) override;
virtual Result Write(s64 offset, const void *buffer, size_t size) override;

virtual Result SetSize(s64 size) override { AMS_UNUSED(size); return fs::ResultUnsupportedSetSizeForHierarchicalIntegrityVerificationStorage(); }
virtual Result SetSize(s64 size) override { AMS_UNUSED(size); R_THROW(fs::ResultUnsupportedSetSizeForHierarchicalIntegrityVerificationStorage()); }
virtual Result GetSize(s64 *out) override;

virtual Result Flush() override;
Expand All @@ -179,10 +184,6 @@ namespace ams::fssystem {
return m_data_size >= 0;
}

bool IsWrittenForRollback() const {
return m_is_written_for_rollback;
}

FileSystemBufferManagerSet *GetBuffers() {
return m_buffers;
}
Expand All @@ -201,6 +202,10 @@ namespace ams::fssystem {
fs::SubStorage GetL1HashStorage() {
return fs::SubStorage(std::addressof(m_buffer_storages[m_max_layers - 3]), 0, util::DivideUp(m_data_size, this->GetL1HashVerificationBlockSize()));
}
public:
static constexpr s8 GetDefaultDataCacheBufferLevel(u32 max_layers) {
return 16 + max_layers - 2;
}
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,33 +39,33 @@ namespace ams::fssystem {
IntegrityRomFsStorage() : m_mutex() { /* ... */ }
virtual ~IntegrityRomFsStorage() override { this->Finalize(); }

Result Initialize(HierarchicalIntegrityVerificationInformation level_hash_info, Hash master_hash, HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation storage_info, fs::IBufferManager *bm, IHash256GeneratorFactory *hgf);
Result Initialize(HierarchicalIntegrityVerificationInformation level_hash_info, Hash master_hash, HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation storage_info, fs::IBufferManager *bm, int max_data_cache_entries, int max_hash_cache_entries, s8 buffer_level, IHash256GeneratorFactory *hgf);
void Finalize();

virtual Result Read(s64 offset, void *buffer, size_t size) override {
return m_integrity_storage.Read(offset, buffer, size);
R_RETURN(m_integrity_storage.Read(offset, buffer, size));
}

virtual Result Write(s64 offset, const void *buffer, size_t size) override {
return m_integrity_storage.Write(offset, buffer, size);
R_RETURN(m_integrity_storage.Write(offset, buffer, size));
}

virtual Result SetSize(s64 size) override { AMS_UNUSED(size); return fs::ResultUnsupportedSetSizeForIntegrityRomFsStorage(); }
virtual Result SetSize(s64 size) override { AMS_UNUSED(size); R_THROW(fs::ResultUnsupportedSetSizeForIntegrityRomFsStorage()); }

virtual Result GetSize(s64 *out) override {
return m_integrity_storage.GetSize(out);
R_RETURN(m_integrity_storage.GetSize(out));
}

virtual Result Flush() override {
return m_integrity_storage.Flush();
R_RETURN(m_integrity_storage.Flush());
}

virtual Result OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
return m_integrity_storage.OperateRange(dst, dst_size, op_id, offset, size, src, src_size);
R_RETURN(m_integrity_storage.OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
}

Result Commit() {
return m_integrity_storage.Commit();
R_RETURN(m_integrity_storage.Commit());
}

FileSystemBufferManagerSet *GetBuffers() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

namespace ams::fssystem {

/* ACCURATE_TO_VERSION: Unknown */
/* ACCURATE_TO_VERSION: 14.3.0.0 */

class IntegrityVerificationStorage : public ::ams::fs::IStorage {
NON_COPYABLE(IntegrityVerificationStorage);
Expand All @@ -43,15 +43,16 @@ namespace ams::fssystem {
s64 m_upper_layer_verification_block_size;
s64 m_upper_layer_verification_block_order;
fs::IBufferManager *m_buffer_manager;
fs::HashSalt m_salt;
util::optional<fs::HashSalt> m_salt;
bool m_is_real_data;
fs::StorageType m_storage_type;
fssystem::IHash256GeneratorFactory *m_hash_generator_factory;
bool m_is_writable;
bool m_allow_cleared_blocks;
public:
IntegrityVerificationStorage() : m_verification_block_size(0), m_verification_block_order(0), m_upper_layer_verification_block_size(0), m_upper_layer_verification_block_order(0), m_buffer_manager(nullptr) { /* ... */ }
IntegrityVerificationStorage() : m_verification_block_size(0), m_verification_block_order(0), m_upper_layer_verification_block_size(0), m_upper_layer_verification_block_order(0), m_buffer_manager(nullptr), m_salt(util::nullopt) { /* ... */ }
virtual ~IntegrityVerificationStorage() override { this->Finalize(); }

Result Initialize(fs::SubStorage hs, fs::SubStorage ds, s64 verif_block_size, s64 upper_layer_verif_block_size, fs::IBufferManager *bm, fssystem::IHash256GeneratorFactory *hgf, const fs::HashSalt &salt, bool is_real_data, fs::StorageType storage_type);
Result Initialize(fs::SubStorage hs, fs::SubStorage ds, s64 verif_block_size, s64 upper_layer_verif_block_size, fs::IBufferManager *bm, fssystem::IHash256GeneratorFactory *hgf, const util::optional<fs::HashSalt> &salt, bool is_real_data, bool is_writable, bool allow_cleared_blocks);
void Finalize();

virtual Result Read(s64 offset, void *buffer, size_t size) override;
Expand Down
Loading

0 comments on commit ec44eaa

Please sign in to comment.