introduce wrapper for SHA1 functionality

This commit is contained in:
Shawn Hoffman
2022-07-23 22:45:10 -07:00
parent 91169333e9
commit dd29a54cf6
27 changed files with 256 additions and 199 deletions

View File

@ -12,9 +12,8 @@
#include <utility>
#include <vector>
#include <mbedtls/sha1.h>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/StringUtil.h"
#include "Core/IOS/ES/Formats.h"
@ -33,21 +32,21 @@ const IOS::ES::TMDReader Volume::INVALID_TMD{};
const std::vector<u8> Volume::INVALID_CERT_CHAIN{};
template <typename T>
static void AddToSyncHash(mbedtls_sha1_context* context, const T& data)
static void AddToSyncHash(Common::SHA1::Context* context, const T& data)
{
static_assert(std::is_trivially_copyable_v<T>);
mbedtls_sha1_update_ret(context, reinterpret_cast<const u8*>(&data), sizeof(data));
context->Update(reinterpret_cast<const u8*>(&data), sizeof(data));
}
void Volume::ReadAndAddToSyncHash(mbedtls_sha1_context* context, u64 offset, u64 length,
void Volume::ReadAndAddToSyncHash(Common::SHA1::Context* context, u64 offset, u64 length,
const Partition& partition) const
{
std::vector<u8> buffer(length);
if (Read(offset, length, buffer.data(), partition))
mbedtls_sha1_update_ret(context, buffer.data(), buffer.size());
context->Update(buffer);
}
void Volume::AddTMDToSyncHash(mbedtls_sha1_context* context, const Partition& partition) const
void Volume::AddTMDToSyncHash(Common::SHA1::Context* context, const Partition& partition) const
{
// We want to hash some important parts of the TMD, but nothing that changes when fakesigning.
// (Fakesigned WADs are very popular, and we don't want people with properly signed WADs to

View File

@ -11,9 +11,8 @@
#include <string>
#include <vector>
#include <mbedtls/sha1.h>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/StringUtil.h"
#include "Common/Swap.h"
#include "Core/IOS/ES/Formats.h"
@ -164,9 +163,9 @@ protected:
return CP1252ToUTF8(string);
}
void ReadAndAddToSyncHash(mbedtls_sha1_context* context, u64 offset, u64 length,
void ReadAndAddToSyncHash(Common::SHA1::Context* context, u64 offset, u64 length,
const Partition& partition) const;
void AddTMDToSyncHash(mbedtls_sha1_context* context, const Partition& partition) const;
void AddTMDToSyncHash(Common::SHA1::Context* context, const Partition& partition) const;
virtual u32 GetOffsetShift() const { return 0; }
static std::map<Language, std::string> ReadWiiNames(const std::vector<char16_t>& data);

View File

@ -8,9 +8,8 @@
#include <string>
#include <vector>
#include <mbedtls/sha1.h>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "DiscIO/DiscUtils.h"
#include "DiscIO/Enums.h"
#include "DiscIO/Filesystem.h"
@ -95,7 +94,7 @@ bool VolumeDisc::IsNKit() const
return ReadSwapped<u32>(0x200, PARTITION_NONE) == NKIT_MAGIC;
}
void VolumeDisc::AddGamePartitionToSyncHash(mbedtls_sha1_context* context) const
void VolumeDisc::AddGamePartitionToSyncHash(Common::SHA1::Context* context) const
{
const Partition partition = GetGamePartition();

View File

@ -6,9 +6,8 @@
#include <optional>
#include <string>
#include <mbedtls/sha1.h>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "DiscIO/Volume.h"
namespace DiscIO
@ -27,7 +26,7 @@ public:
protected:
Region RegionCodeToRegion(std::optional<u32> region_code) const;
void AddGamePartitionToSyncHash(mbedtls_sha1_context* context) const;
void AddGamePartitionToSyncHash(Common::SHA1::Context* context) const;
};
} // namespace DiscIO

View File

@ -11,11 +11,10 @@
#include <utility>
#include <vector>
#include <mbedtls/sha1.h>
#include "Common/Assert.h"
#include "Common/ColorUtil.h"
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
@ -152,15 +151,11 @@ bool VolumeGC::IsDatelDisc() const
std::array<u8, 20> VolumeGC::GetSyncHash() const
{
mbedtls_sha1_context context;
mbedtls_sha1_init(&context);
mbedtls_sha1_starts_ret(&context);
auto context = Common::SHA1::CreateContext();
AddGamePartitionToSyncHash(&context);
AddGamePartitionToSyncHash(context.get());
std::array<u8, 20> hash;
mbedtls_sha1_finish_ret(&context, hash.data());
return hash;
return context->Finish();
}
VolumeGC::ConvertedGCBanner VolumeGC::LoadBannerFile() const

View File

@ -13,7 +13,6 @@
#include <unordered_set>
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mz_compat.h>
#include <pugixml.hpp>
@ -21,6 +20,7 @@
#include "Common/Assert.h"
#include "Common/CommonPaths.h"
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/FileUtil.h"
#include "Common/Hash.h"
#include "Common/HttpRequest.h"
@ -1053,8 +1053,7 @@ void VolumeVerifier::SetUpHashing()
if (m_hashes_to_calculate.sha1)
{
mbedtls_sha1_init(&m_sha1_context);
mbedtls_sha1_starts_ret(&m_sha1_context);
m_sha1_context = Common::SHA1::CreateContext();
}
}
@ -1191,7 +1190,7 @@ void VolumeVerifier::Process()
if (m_hashes_to_calculate.sha1)
{
m_sha1_future = std::async(std::launch::async, [this, byte_increment] {
mbedtls_sha1_update_ret(&m_sha1_context, m_data.data(), byte_increment);
m_sha1_context->Update(m_data.data(), byte_increment);
});
}
}
@ -1283,8 +1282,8 @@ void VolumeVerifier::Finish()
if (m_hashes_to_calculate.sha1)
{
m_result.hashes.sha1 = std::vector<u8>(20);
mbedtls_sha1_finish_ret(&m_sha1_context, m_result.hashes.sha1.data());
const auto digest = m_sha1_context->Finish();
m_result.hashes.sha1 = std::vector<u8>(digest.begin(), digest.end());
}
}

View File

@ -5,14 +5,15 @@
#include <future>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/DiscScrubber.h"
#include "DiscIO/Volume.h"
@ -174,7 +175,7 @@ private:
bool m_calculating_any_hash = false;
u32 m_crc32_context = 0;
mbedtls_md5_context m_md5_context{};
mbedtls_sha1_context m_sha1_context{};
std::unique_ptr<Common::SHA1::Context> m_sha1_context;
u64 m_excess_bytes = 0;
std::vector<u8> m_data;

View File

@ -14,11 +14,11 @@
#include <vector>
#include <mbedtls/aes.h>
#include <mbedtls/sha1.h>
#include "Common/Align.h"
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
@ -171,9 +171,7 @@ bool VolumeWAD::CheckContentIntegrity(const IOS::ES::Content& content,
mbedtls_aes_crypt_cbc(&context, MBEDTLS_AES_DECRYPT, decrypted_data.size(), iv.data(),
encrypted_data.data(), decrypted_data.data());
std::array<u8, 20> sha1;
mbedtls_sha1_ret(decrypted_data.data(), content.size, sha1.data());
return sha1 == content.sha1;
return Common::SHA1::CalculateDigest(decrypted_data.data(), content.size) == content.sha1;
}
bool VolumeWAD::CheckContentIntegrity(const IOS::ES::Content& content, u64 content_offset,
@ -349,17 +347,13 @@ std::array<u8, 20> VolumeWAD::GetSyncHash() const
// We can skip hashing the contents since the TMD contains hashes of the contents.
// We specifically don't hash the ticket, since its console ID can differ without any problems.
mbedtls_sha1_context context;
mbedtls_sha1_init(&context);
mbedtls_sha1_starts_ret(&context);
auto context = Common::SHA1::CreateContext();
AddTMDToSyncHash(&context, PARTITION_NONE);
AddTMDToSyncHash(context.get(), PARTITION_NONE);
ReadAndAddToSyncHash(&context, m_opening_bnr_offset, m_opening_bnr_size, PARTITION_NONE);
ReadAndAddToSyncHash(context.get(), m_opening_bnr_offset, m_opening_bnr_size, PARTITION_NONE);
std::array<u8, 20> hash;
mbedtls_sha1_finish_ret(&context, hash.data());
return hash;
return context->Finish();
}
} // namespace DiscIO

View File

@ -17,11 +17,11 @@
#include <vector>
#include <mbedtls/aes.h>
#include <mbedtls/sha1.h>
#include "Common/Align.h"
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/Logging/Log.h"
#include "Common/Swap.h"
@ -366,29 +366,25 @@ const BlobReader& VolumeWii::GetBlobReader() const
std::array<u8, 20> VolumeWii::GetSyncHash() const
{
mbedtls_sha1_context context;
mbedtls_sha1_init(&context);
mbedtls_sha1_starts_ret(&context);
auto context = Common::SHA1::CreateContext();
// Disc header
ReadAndAddToSyncHash(&context, 0, 0x80, PARTITION_NONE);
ReadAndAddToSyncHash(context.get(), 0, 0x80, PARTITION_NONE);
// Region code
ReadAndAddToSyncHash(&context, 0x4E000, 4, PARTITION_NONE);
ReadAndAddToSyncHash(context.get(), 0x4E000, 4, PARTITION_NONE);
// The data offset of the game partition - an important factor for disc drive timings
const u64 data_offset = PartitionOffsetToRawOffset(0, GetGamePartition());
mbedtls_sha1_update_ret(&context, reinterpret_cast<const u8*>(&data_offset), sizeof(data_offset));
context->Update(reinterpret_cast<const u8*>(&data_offset), sizeof(data_offset));
// TMD
AddTMDToSyncHash(&context, GetGamePartition());
AddTMDToSyncHash(context.get(), GetGamePartition());
// Game partition contents
AddGamePartitionToSyncHash(&context);
AddGamePartitionToSyncHash(context.get());
std::array<u8, 20> hash;
mbedtls_sha1_finish_ret(&context, hash.data());
return hash;
return context->Finish();
}
bool VolumeWii::CheckH3TableIntegrity(const Partition& partition) const
@ -410,9 +406,7 @@ bool VolumeWii::CheckH3TableIntegrity(const Partition& partition) const
if (contents.size() != 1)
return false;
std::array<u8, 20> h3_table_sha1;
mbedtls_sha1_ret(h3_table.data(), h3_table.size(), h3_table_sha1.data());
return h3_table_sha1 == contents[0].sha1;
return Common::SHA1::CalculateDigest(h3_table) == contents[0].sha1;
}
bool VolumeWii::CheckBlockIntegrity(u64 block_index, const u8* encrypted_data,
@ -423,7 +417,8 @@ bool VolumeWii::CheckBlockIntegrity(u64 block_index, const u8* encrypted_data,
return false;
const PartitionDetails& partition_details = it->second;
if (block_index / BLOCKS_PER_GROUP * SHA1_SIZE >= partition_details.h3_table->size())
if (block_index / BLOCKS_PER_GROUP * Common::SHA1::DIGEST_LEN >=
partition_details.h3_table->size())
return false;
mbedtls_aes_context* aes_context = partition_details.key->get();
@ -438,25 +433,22 @@ bool VolumeWii::CheckBlockIntegrity(u64 block_index, const u8* encrypted_data,
for (u32 hash_index = 0; hash_index < 31; ++hash_index)
{
u8 h0_hash[SHA1_SIZE];
mbedtls_sha1_ret(cluster_data + hash_index * 0x400, 0x400, h0_hash);
if (memcmp(h0_hash, hashes.h0[hash_index], SHA1_SIZE))
if (Common::SHA1::CalculateDigest(cluster_data + hash_index * 0x400, 0x400) !=
hashes.h0[hash_index])
return false;
}
u8 h1_hash[SHA1_SIZE];
mbedtls_sha1_ret(reinterpret_cast<u8*>(hashes.h0), sizeof(hashes.h0), h1_hash);
if (memcmp(h1_hash, hashes.h1[block_index % 8], SHA1_SIZE))
if (Common::SHA1::CalculateDigest(hashes.h0) != hashes.h1[block_index % 8])
return false;
u8 h2_hash[SHA1_SIZE];
mbedtls_sha1_ret(reinterpret_cast<u8*>(hashes.h1), sizeof(hashes.h1), h2_hash);
if (memcmp(h2_hash, hashes.h2[block_index / 8 % 8], SHA1_SIZE))
if (Common::SHA1::CalculateDigest(hashes.h1) != hashes.h2[block_index / 8 % 8])
return false;
u8 h3_hash[SHA1_SIZE];
mbedtls_sha1_ret(reinterpret_cast<u8*>(hashes.h2), sizeof(hashes.h2), h3_hash);
if (memcmp(h3_hash, partition_details.h3_table->data() + block_index / 64 * SHA1_SIZE, SHA1_SIZE))
Common::SHA1::Digest h3_digest;
auto h3_digest_ptr =
partition_details.h3_table->data() + block_index / 64 * Common::SHA1::DIGEST_LEN;
memcpy(h3_digest.data(), h3_digest_ptr, sizeof(h3_digest));
if (Common::SHA1::CalculateDigest(hashes.h2) != h3_digest)
return false;
return true;
@ -496,14 +488,13 @@ bool VolumeWii::HashGroup(const std::array<u8, BLOCK_DATA_SIZE> in[BLOCKS_PER_GR
{
// H0 hashes
for (size_t j = 0; j < 31; ++j)
mbedtls_sha1_ret(in[i].data() + j * 0x400, 0x400, out[i].h0[j]);
out[i].h0[j] = Common::SHA1::CalculateDigest(in[i].data() + j * 0x400, 0x400);
// H0 padding
std::memset(out[i].padding_0, 0, sizeof(HashBlock::padding_0));
out[i].padding_0 = {};
// H1 hash
mbedtls_sha1_ret(reinterpret_cast<u8*>(out[i].h0), sizeof(HashBlock::h0),
out[h1_base].h1[i - h1_base]);
out[h1_base].h1[i - h1_base] = Common::SHA1::CalculateDigest(out[i].h0);
}
if (i % 8 == 7)
@ -514,15 +505,14 @@ bool VolumeWii::HashGroup(const std::array<u8, BLOCK_DATA_SIZE> in[BLOCKS_PER_GR
if (success)
{
// H1 padding
std::memset(out[h1_base].padding_1, 0, sizeof(HashBlock::padding_1));
out[h1_base].padding_1 = {};
// H1 copies
for (size_t j = 1; j < 8; ++j)
std::memcpy(out[h1_base + j].h1, out[h1_base].h1, sizeof(HashBlock::h1));
out[h1_base + j].h1 = out[h1_base].h1;
// H2 hash
mbedtls_sha1_ret(reinterpret_cast<u8*>(out[i].h1), sizeof(HashBlock::h1),
out[0].h2[h1_base / 8]);
out[0].h2[h1_base / 8] = Common::SHA1::CalculateDigest(out[i].h1);
}
if (i == BLOCKS_PER_GROUP - 1)
@ -533,11 +523,11 @@ bool VolumeWii::HashGroup(const std::array<u8, BLOCK_DATA_SIZE> in[BLOCKS_PER_GR
if (success)
{
// H2 padding
std::memset(out[0].padding_2, 0, sizeof(HashBlock::padding_2));
out[0].padding_2 = {};
// H2 copies
for (size_t j = 1; j < BLOCKS_PER_GROUP; ++j)
std::memcpy(out[j].h2, out[0].h2, sizeof(HashBlock::h2));
out[j].h2 = out[0].h2;
}
}
}

View File

@ -14,6 +14,7 @@
#include <mbedtls/aes.h>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/Lazy.h"
#include "Core/IOS/ES/Formats.h"
#include "DiscIO/Filesystem.h"
@ -34,7 +35,6 @@ class VolumeWii : public VolumeDisc
{
public:
static constexpr size_t AES_KEY_SIZE = 16;
static constexpr size_t SHA1_SIZE = 20;
static constexpr u32 BLOCKS_PER_GROUP = 0x40;
@ -48,12 +48,12 @@ public:
struct HashBlock
{
u8 h0[31][SHA1_SIZE];
u8 padding_0[20];
u8 h1[8][SHA1_SIZE];
u8 padding_1[32];
u8 h2[8][SHA1_SIZE];
u8 padding_2[32];
std::array<Common::SHA1::Digest, 31> h0;
std::array<u8, 20> padding_0;
std::array<Common::SHA1::Digest, 8> h1;
std::array<u8, 32> padding_1;
std::array<Common::SHA1::Digest, 8> h2;
std::array<u8, 32> padding_2;
};
static_assert(sizeof(HashBlock) == BLOCK_HEADER_SIZE);

View File

@ -15,12 +15,12 @@
#include <utility>
#include <fmt/format.h>
#include <mbedtls/sha1.h>
#include <zstd.h>
#include "Common/Align.h"
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/FileUtil.h"
#include "Common/IOFile.h"
#include "Common/Logging/Log.h"
@ -109,9 +109,8 @@ bool WIARVZFileReader<RVZ>::Initialize(const std::string& path)
return false;
}
SHA1 header_1_actual_hash;
mbedtls_sha1_ret(reinterpret_cast<const u8*>(&m_header_1), sizeof(m_header_1) - sizeof(SHA1),
header_1_actual_hash.data());
const auto header_1_actual_hash = Common::SHA1::CalculateDigest(
reinterpret_cast<const u8*>(&m_header_1), sizeof(m_header_1) - Common::SHA1::DIGEST_LEN);
if (m_header_1.header_1_hash != header_1_actual_hash)
return false;
@ -130,8 +129,7 @@ bool WIARVZFileReader<RVZ>::Initialize(const std::string& path)
if (!m_file.ReadBytes(header_2.data(), header_2.size()))
return false;
SHA1 header_2_actual_hash;
mbedtls_sha1_ret(header_2.data(), header_2.size(), header_2_actual_hash.data());
const auto header_2_actual_hash = Common::SHA1::CalculateDigest(header_2);
if (m_header_1.header_2_hash != header_2_actual_hash)
return false;
@ -168,9 +166,7 @@ bool WIARVZFileReader<RVZ>::Initialize(const std::string& path)
if (!m_file.ReadBytes(partition_entries.data(), partition_entries.size()))
return false;
SHA1 partition_entries_actual_hash;
mbedtls_sha1_ret(reinterpret_cast<const u8*>(partition_entries.data()), partition_entries.size(),
partition_entries_actual_hash.data());
const auto partition_entries_actual_hash = Common::SHA1::CalculateDigest(partition_entries);
if (m_header_2.partition_entries_hash != partition_entries_actual_hash)
return false;
@ -635,8 +631,8 @@ WIARVZFileReader<RVZ>::Chunk::Chunk(File::IOFile* file, u64 offset_in_file, u64
m_rvz_packed_size(rvz_packed_size), m_data_offset(data_offset)
{
constexpr size_t MAX_SIZE_PER_EXCEPTION_LIST =
Common::AlignUp(VolumeWii::BLOCK_HEADER_SIZE, sizeof(SHA1)) / sizeof(SHA1) *
VolumeWii::BLOCKS_PER_GROUP * sizeof(HashExceptionEntry) +
Common::AlignUp(VolumeWii::BLOCK_HEADER_SIZE, Common::SHA1::DIGEST_LEN) /
Common::SHA1::DIGEST_LEN * VolumeWii::BLOCKS_PER_GROUP * sizeof(HashExceptionEntry) +
sizeof(u16);
m_out_bytes_allocated_for_exceptions =
@ -861,11 +857,11 @@ bool WIARVZFileReader<RVZ>::ApplyHashExceptions(
return false;
const size_t offset_in_block = offset % VolumeWii::BLOCK_HEADER_SIZE;
if (offset_in_block + sizeof(SHA1) > VolumeWii::BLOCK_HEADER_SIZE)
if (offset_in_block + Common::SHA1::DIGEST_LEN > VolumeWii::BLOCK_HEADER_SIZE)
return false;
std::memcpy(reinterpret_cast<u8*>(&hash_blocks[block_index]) + offset_in_block, &exception.hash,
sizeof(SHA1));
Common::SHA1::DIGEST_LEN);
}
return true;
@ -1420,7 +1416,7 @@ WIARVZFileReader<RVZ>::ProcessAndCompress(CompressThreadState* state, CompressPa
&aes_context);
const auto compare_hash = [&](size_t offset_in_block) {
ASSERT(offset_in_block + sizeof(SHA1) <= VolumeWii::BLOCK_HEADER_SIZE);
ASSERT(offset_in_block + Common::SHA1::DIGEST_LEN <= VolumeWii::BLOCK_HEADER_SIZE);
const u8* desired_hash = reinterpret_cast<u8*>(&hashes) + offset_in_block;
const u8* computed_hash =
@ -1432,22 +1428,22 @@ WIARVZFileReader<RVZ>::ProcessAndCompress(CompressThreadState* state, CompressPa
// that affects the recalculated hashes. Chunks which have been marked as reusable at
// this point normally have zero matching hashes anyway, so this shouldn't waste space.
if ((chunks_per_wii_group != 1 && output_entries[chunk_index].reuse_id) ||
!std::equal(desired_hash, desired_hash + sizeof(SHA1), computed_hash))
!std::equal(desired_hash, desired_hash + Common::SHA1::DIGEST_LEN, computed_hash))
{
const u64 hash_offset = hash_offset_of_block + offset_in_block;
ASSERT(hash_offset <= std::numeric_limits<u16>::max());
HashExceptionEntry& exception = exception_lists[exception_list_index].emplace_back();
exception.offset = static_cast<u16>(Common::swap16(hash_offset));
std::memcpy(exception.hash.data(), desired_hash, sizeof(SHA1));
std::memcpy(exception.hash.data(), desired_hash, Common::SHA1::DIGEST_LEN);
}
};
const auto compare_hashes = [&compare_hash](size_t offset, size_t size) {
for (size_t l = 0; l < size; l += sizeof(SHA1))
for (size_t l = 0; l < size; l += Common::SHA1::DIGEST_LEN)
// The std::min is to ensure that we don't go beyond the end of HashBlock with
// padding_2, which is 32 bytes long (not divisible by sizeof(SHA1), which is 20).
compare_hash(offset + std::min(l, size - sizeof(SHA1)));
// padding_2, which is 32 bytes long (not divisible by SHA1::DIGEST_LEN, which is 20).
compare_hash(offset + std::min(l, size - Common::SHA1::DIGEST_LEN));
};
using HashBlock = VolumeWii::HashBlock;
@ -1996,9 +1992,8 @@ WIARVZFileReader<RVZ>::Convert(BlobReader* infile, const VolumeDisc* infile_volu
header_2.partition_entries_offset = Common::swap64(partition_entries_offset);
if (partition_entries.data() == nullptr)
partition_entries.reserve(1); // Avoid a crash in mbedtls_sha1_ret
mbedtls_sha1_ret(reinterpret_cast<const u8*>(partition_entries.data()), partition_entries_size,
header_2.partition_entries_hash.data());
partition_entries.reserve(1); // Avoid a crash in mbedtls_sha1_ret TODO examine this
header_2.partition_entries_hash = Common::SHA1::CalculateDigest(partition_entries);
header_2.number_of_raw_data_entries = Common::swap32(static_cast<u32>(raw_data_entries.size()));
header_2.raw_data_entries_offset = Common::swap64(raw_data_entries_offset);
@ -2014,12 +2009,12 @@ WIARVZFileReader<RVZ>::Convert(BlobReader* infile, const VolumeDisc* infile_volu
header_1.version_compatible =
Common::swap32(RVZ ? RVZ_VERSION_WRITE_COMPATIBLE : WIA_VERSION_WRITE_COMPATIBLE);
header_1.header_2_size = Common::swap32(sizeof(WIAHeader2));
mbedtls_sha1_ret(reinterpret_cast<const u8*>(&header_2), sizeof(header_2),
header_1.header_2_hash.data());
header_1.header_2_hash =
Common::SHA1::CalculateDigest(reinterpret_cast<const u8*>(&header_2), sizeof(header_2));
header_1.iso_file_size = Common::swap64(infile->GetDataSize());
header_1.wia_file_size = Common::swap64(outfile->GetSize());
mbedtls_sha1_ret(reinterpret_cast<const u8*>(&header_1), offsetof(WIAHeader1, header_1_hash),
header_1.header_1_hash.data());
header_1.header_1_hash = Common::SHA1::CalculateDigest(reinterpret_cast<const u8*>(&header_1),
offsetof(WIAHeader1, header_1_hash));
if (!outfile->Seek(0, File::SeekOrigin::Begin))
return ConversionResultCode::WriteFailed;

View File

@ -12,6 +12,7 @@
#include <utility>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "Common/IOFile.h"
#include "Common/Swap.h"
#include "DiscIO/Blob.h"
@ -70,7 +71,6 @@ public:
int compression_level, int chunk_size, CompressCB callback);
private:
using SHA1 = std::array<u8, 20>;
using WiiKey = std::array<u8, 16>;
// See docs/WiaAndRvz.md for details about the format
@ -82,10 +82,10 @@ private:
u32 version;
u32 version_compatible;
u32 header_2_size;
SHA1 header_2_hash;
Common::SHA1::Digest header_2_hash;
u64 iso_file_size;
u64 wia_file_size;
SHA1 header_1_hash;
Common::SHA1::Digest header_1_hash;
};
static_assert(sizeof(WIAHeader1) == 0x48, "Wrong size for WIA header 1");
@ -101,7 +101,7 @@ private:
u32 number_of_partition_entries;
u32 partition_entry_size;
u64 partition_entries_offset;
SHA1 partition_entries_hash;
Common::SHA1::Digest partition_entries_hash;
u32 number_of_raw_data_entries;
u64 raw_data_entries_offset;
@ -161,7 +161,7 @@ private:
struct HashExceptionEntry
{
u16 offset;
SHA1 hash;
Common::SHA1::Digest hash;
};
static_assert(sizeof(HashExceptionEntry) == 0x16, "Wrong size for WIA hash exception entry");
#pragma pack(pop)

View File

@ -13,7 +13,6 @@
#include <bzlib.h>
#include <lzma.h>
#include <mbedtls/sha1.h>
#include <zstd.h>
#include "Common/Assert.h"
@ -48,7 +47,6 @@ bool NoneDecompressor::Decompress(const DecompressionBuffer& in, DecompressionBu
PurgeDecompressor::PurgeDecompressor(u64 decompressed_size) : m_decompressed_size(decompressed_size)
{
mbedtls_sha1_init(&m_sha1_context);
}
bool PurgeDecompressor::Decompress(const DecompressionBuffer& in, DecompressionBuffer* out,
@ -56,10 +54,10 @@ bool PurgeDecompressor::Decompress(const DecompressionBuffer& in, DecompressionB
{
if (!m_started)
{
mbedtls_sha1_starts_ret(&m_sha1_context);
m_sha1_context = Common::SHA1::CreateContext();
// Include the exception lists in the SHA-1 calculation (but not in the compression...)
mbedtls_sha1_update_ret(&m_sha1_context, in.data.data(), *in_bytes_read);
m_sha1_context->Update(in.data.data(), *in_bytes_read);
m_started = true;
}
@ -67,7 +65,7 @@ bool PurgeDecompressor::Decompress(const DecompressionBuffer& in, DecompressionB
while (!m_done && in.bytes_written != *in_bytes_read &&
(m_segment_bytes_written < sizeof(m_segment) || out->data.size() != out->bytes_written))
{
if (m_segment_bytes_written == 0 && *in_bytes_read == in.data.size() - sizeof(SHA1))
if (m_segment_bytes_written == 0 && *in_bytes_read == in.data.size() - Common::SHA1::DIGEST_LEN)
{
const size_t zeroes_to_write = std::min<size_t>(m_decompressed_size - m_out_bytes_written,
out->data.size() - out->bytes_written);
@ -79,10 +77,9 @@ bool PurgeDecompressor::Decompress(const DecompressionBuffer& in, DecompressionB
if (m_out_bytes_written == m_decompressed_size && in.bytes_written == in.data.size())
{
SHA1 actual_hash;
mbedtls_sha1_finish_ret(&m_sha1_context, actual_hash.data());
const auto actual_hash = m_sha1_context->Finish();
SHA1 expected_hash;
Common::SHA1::Digest expected_hash;
std::memcpy(expected_hash.data(), in.data.data() + *in_bytes_read, expected_hash.size());
*in_bytes_read += expected_hash.size();
@ -102,7 +99,7 @@ bool PurgeDecompressor::Decompress(const DecompressionBuffer& in, DecompressionB
std::memcpy(reinterpret_cast<u8*>(&m_segment) + m_segment_bytes_written,
in.data.data() + *in_bytes_read, bytes_to_copy);
mbedtls_sha1_update_ret(&m_sha1_context, in.data.data() + *in_bytes_read, bytes_to_copy);
m_sha1_context->Update(in.data.data() + *in_bytes_read, bytes_to_copy);
*in_bytes_read += bytes_to_copy;
m_bytes_read += bytes_to_copy;
@ -134,7 +131,7 @@ bool PurgeDecompressor::Decompress(const DecompressionBuffer& in, DecompressionB
std::memcpy(out->data.data() + out->bytes_written, in.data.data() + *in_bytes_read,
bytes_to_copy);
mbedtls_sha1_update_ret(&m_sha1_context, in.data.data() + *in_bytes_read, bytes_to_copy);
m_sha1_context->Update(in.data.data() + *in_bytes_read, bytes_to_copy);
*in_bytes_read += bytes_to_copy;
m_bytes_read += bytes_to_copy;
@ -435,10 +432,7 @@ bool RVZPackDecompressor::Done() const
Compressor::~Compressor() = default;
PurgeCompressor::PurgeCompressor()
{
mbedtls_sha1_init(&m_sha1_context);
}
PurgeCompressor::PurgeCompressor() = default;
PurgeCompressor::~PurgeCompressor() = default;
@ -447,14 +441,14 @@ bool PurgeCompressor::Start(std::optional<u64> size)
m_buffer.clear();
m_bytes_written = 0;
mbedtls_sha1_starts_ret(&m_sha1_context);
m_sha1_context = Common::SHA1::CreateContext();
return true;
}
bool PurgeCompressor::AddPrecedingDataOnlyForPurgeHashing(const u8* data, size_t size)
{
mbedtls_sha1_update_ret(&m_sha1_context, data, size);
m_sha1_context->Update(data, size);
return true;
}
@ -465,7 +459,7 @@ bool PurgeCompressor::Compress(const u8* data, size_t size)
ASSERT_MSG(DISCIO, m_bytes_written == 0,
"Calling PurgeCompressor::Compress() twice is not supported");
m_buffer.resize(size + sizeof(PurgeSegment) + sizeof(SHA1));
m_buffer.resize(size + sizeof(PurgeSegment) + Common::SHA1::DIGEST_LEN);
size_t bytes_read = 0;
@ -517,10 +511,12 @@ bool PurgeCompressor::Compress(const u8* data, size_t size)
bool PurgeCompressor::End()
{
mbedtls_sha1_update_ret(&m_sha1_context, m_buffer.data(), m_bytes_written);
m_sha1_context->Update(m_buffer.data(), m_bytes_written);
mbedtls_sha1_finish_ret(&m_sha1_context, m_buffer.data() + m_bytes_written);
m_bytes_written += sizeof(SHA1);
const auto digest = m_sha1_context->Finish();
std::memcpy(m_buffer.data() + m_bytes_written, digest.data(), sizeof(digest));
m_bytes_written += sizeof(digest);
ASSERT(m_bytes_written <= m_buffer.size());

View File

@ -10,10 +10,10 @@
#include <bzlib.h>
#include <lzma.h>
#include <mbedtls/sha1.h>
#include <zstd.h>
#include "Common/CommonTypes.h"
#include "Common/Crypto/SHA1.h"
#include "DiscIO/LaggedFibonacciGenerator.h"
namespace DiscIO
@ -24,8 +24,6 @@ struct DecompressionBuffer
size_t bytes_written = 0;
};
using SHA1 = std::array<u8, 20>;
struct PurgeSegment
{
u32 offset;
@ -71,7 +69,7 @@ private:
size_t m_out_bytes_written = 0;
bool m_started = false;
mbedtls_sha1_context m_sha1_context;
std::unique_ptr<Common::SHA1::Context> m_sha1_context;
};
class Bzip2Decompressor final : public Decompressor
@ -179,7 +177,7 @@ public:
private:
std::vector<u8> m_buffer;
size_t m_bytes_written = 0;
mbedtls_sha1_context m_sha1_context;
std::unique_ptr<Common::SHA1::Context> m_sha1_context;
};
class Bzip2Compressor final : public Compressor