libs: add ongoing work to facilitate hactool rewrite
This commit is contained in:
@@ -32,7 +32,7 @@ namespace ams::fssystem {
|
||||
|
||||
template<typename BasePointer>
|
||||
AesCtrStorage<BasePointer>::AesCtrStorage(BasePointer base, const void *key, size_t key_size, const void *iv, size_t iv_size) : m_base_storage(std::move(base)) {
|
||||
AMS_ASSERT(base != nullptr);
|
||||
AMS_ASSERT(m_base_storage != nullptr);
|
||||
AMS_ASSERT(key != nullptr);
|
||||
AMS_ASSERT(iv != nullptr);
|
||||
AMS_ASSERT(key_size == KeySize);
|
||||
|
||||
@@ -777,7 +777,7 @@ namespace ams::fssystem {
|
||||
|
||||
/* Get and validate the meta extents. */
|
||||
const s64 meta_offset = patch_info.aes_ctr_ex_offset;
|
||||
const s64 meta_size = util::AlignUp(patch_info.aes_ctr_ex_size, NcaHeader::XtsBlockSize);
|
||||
const s64 meta_size = util::AlignUp(static_cast<s64>(patch_info.aes_ctr_ex_size), NcaHeader::XtsBlockSize);
|
||||
R_UNLESS(meta_offset + meta_size <= base_size, fs::ResultNcaBaseStorageOutOfRangeB());
|
||||
|
||||
/* Create the encrypted storage. */
|
||||
|
||||
@@ -45,6 +45,14 @@ namespace ams::fssystem {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
void Dump(const void *s, size_t size) {
|
||||
const u8 *s8 = static_cast<const u8 *>(s);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
printf("%02X", s8[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
Result NcaReader::Initialize(std::shared_ptr<fs::IStorage> base_storage, const NcaCryptoConfiguration &crypto_cfg, const NcaCompressionConfiguration &compression_cfg, IHash256GeneratorFactorySelector *hgf_selector) {
|
||||
/* Validate preconditions. */
|
||||
AMS_ASSERT(base_storage != nullptr);
|
||||
@@ -60,6 +68,7 @@ namespace ams::fssystem {
|
||||
u8 header_decryption_keys[NcaCryptoConfiguration::HeaderEncryptionKeyCount][NcaCryptoConfiguration::Aes128KeySize];
|
||||
for (size_t i = 0; i < NcaCryptoConfiguration::HeaderEncryptionKeyCount; i++) {
|
||||
crypto_cfg.generate_key(header_decryption_keys[i], AesXtsStorageForNcaHeader::KeySize, crypto_cfg.header_encrypted_encryption_keys[i], AesXtsStorageForNcaHeader::KeySize, static_cast<s32>(KeyType::NcaHeaderKey), crypto_cfg);
|
||||
Dump(header_decryption_keys[i], sizeof(header_decryption_keys[i]));
|
||||
}
|
||||
|
||||
/* Create the header storage. */
|
||||
@@ -119,6 +128,13 @@ namespace ams::fssystem {
|
||||
/* If we do, then we don't have an external key, so we need to generate decryption keys. */
|
||||
crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesCtr], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesCtr * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg);
|
||||
|
||||
/* If we're building for non-nx board (i.e., a host tool), generate all keys for debug. */
|
||||
#if !defined(ATMOSPHERE_BOARD_NINTENDO_NX)
|
||||
crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesXts1], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesXts1 * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg);
|
||||
crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesXts2], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesXts2 * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg);
|
||||
crypto_cfg.generate_key(m_decryption_keys[NcaHeader::DecryptionKey_AesCtrEx], crypto::AesDecryptor128::KeySize, m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesCtrEx * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize, GetKeyTypeValue(m_header.key_index, m_header.GetProperKeyGeneration()), crypto_cfg);
|
||||
#endif
|
||||
|
||||
/* Copy the hardware speed emulation key. */
|
||||
std::memcpy(m_decryption_keys[NcaHeader::DecryptionKey_AesCtrHw], m_header.encrypted_key_area + NcaHeader::DecryptionKey_AesCtrHw * crypto::AesDecryptor128::KeySize, crypto::AesDecryptor128::KeySize);
|
||||
}
|
||||
@@ -164,6 +180,11 @@ namespace ams::fssystem {
|
||||
return m_header.content_type;
|
||||
}
|
||||
|
||||
u8 NcaReader::GetHeaderSign1KeyGeneration() const {
|
||||
AMS_ASSERT(m_body_storage != nullptr);
|
||||
return m_header.header1_signature_key_generation;
|
||||
}
|
||||
|
||||
u8 NcaReader::GetKeyGeneration() const {
|
||||
AMS_ASSERT(m_body_storage != nullptr);
|
||||
return m_header.GetProperKeyGeneration();
|
||||
|
||||
@@ -359,7 +359,7 @@ namespace ams::fssystem {
|
||||
R_UNLESS(p[0] == RootPath[0], fs::ResultInvalidPathFormat());
|
||||
|
||||
/* Check if the path is for a directory. */
|
||||
if (util::Strncmp(p, RootPath, sizeof(RootPath))) {
|
||||
if (util::Strncmp(p, RootPath, sizeof(RootPath)) == 0) {
|
||||
*out = fs::DirectoryEntryType_Directory;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace ams::fssystem::save {
|
||||
|
||||
/* Calculate block shift. */
|
||||
m_verification_block_shift = ILog2(static_cast<u32>(verif_block_size));
|
||||
AMS_ASSERT(static_cast<size_t>(1ull << m_verification_block_size) == m_verification_block_size);
|
||||
AMS_ASSERT(static_cast<size_t>(1ull << m_verification_block_shift) == m_verification_block_size);
|
||||
|
||||
/* Clear the entry. */
|
||||
std::memset(m_entries.get(), 0, sizeof(CacheEntry) * m_max_cache_entry_count);
|
||||
@@ -341,10 +341,14 @@ namespace ams::fssystem::save {
|
||||
CacheIndex index;
|
||||
R_TRY(this->UpdateLastResult(this->StoreAssociateBuffer(std::addressof(index), range, entry)));
|
||||
|
||||
/* Set the after aligned offset. */
|
||||
aligned_offset = entry.offset + entry.size;
|
||||
|
||||
/* If we need to, flush the cache entry. */
|
||||
if (index >= 0 && IsEnabledKeepBurstMode() && offset == aligned_offset && (block_alignment * 2 <= size)) {
|
||||
R_TRY(this->UpdateLastResult(this->FlushCacheEntry(index, false)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace ams::fssystem::save {
|
||||
m_buffer_manager = bm;
|
||||
|
||||
/* Set upper layer block sizes. */
|
||||
upper_layer_verif_block_size = std::max(upper_layer_verif_block_size, HashSize);
|
||||
upper_layer_verif_block_size = std::max(upper_layer_verif_block_size, HashSize);
|
||||
m_upper_layer_verification_block_size = upper_layer_verif_block_size;
|
||||
m_upper_layer_verification_block_order = ILog2(static_cast<u32>(upper_layer_verif_block_size));
|
||||
AMS_ASSERT(m_upper_layer_verification_block_size == (1l << m_upper_layer_verification_block_order));
|
||||
@@ -334,18 +334,10 @@ namespace ams::fssystem::save {
|
||||
/* Only allow cache invalidation for RomFs. */
|
||||
R_UNLESS(m_storage_type != fs::StorageType_SaveData, fs::ResultUnsupportedOperationInIntegrityVerificationStorageB());
|
||||
|
||||
/* Validate the range. */
|
||||
s64 data_size = 0;
|
||||
R_TRY(m_data_storage.GetSize(std::addressof(data_size)));
|
||||
R_UNLESS(0 <= offset && offset <= data_size, fs::ResultInvalidOffset());
|
||||
|
||||
/* Determine the extents to invalidate. */
|
||||
const auto sign_offset = (offset >> m_verification_block_order) * HashSize;
|
||||
const auto sign_size = (std::min(size, data_size - offset) >> m_verification_block_order) * HashSize;
|
||||
|
||||
/* Operate on our storages. */
|
||||
R_TRY(m_hash_storage.OperateRange(dst, dst_size, op_id, sign_offset, sign_size, src, src_size));
|
||||
R_TRY(m_data_storage.OperateRange(dst, dst_size, op_id, sign_offset, sign_size, src, src_size));
|
||||
R_TRY(m_hash_storage.OperateRange(dst, dst_size, op_id, 0, std::numeric_limits<s64>::max(), src, src_size));
|
||||
R_TRY(m_data_storage.OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user