From db5bbbd6cf340fd8e77244ad452089fae0ff33ae Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 4 Oct 2026 16:04:21 -0500 Subject: [PATCH 1/4] Common: Create MD5Context class and ComputeMD5 function to minimize exposure to mbedtls throughout the project. --- Source/Core/Common/Hash.cpp | 32 ++++++++++++++++++++++++++++++++ Source/Core/Common/Hash.h | 22 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/Source/Core/Common/Hash.cpp b/Source/Core/Common/Hash.cpp index f5b9da1b20..6e2ee8fb2b 100644 --- a/Source/Core/Common/Hash.cpp +++ b/Source/Core/Common/Hash.cpp @@ -9,6 +9,8 @@ #include +#include + #include "Common/CPUDetect.h" #include "Common/Intrinsics.h" @@ -457,4 +459,34 @@ u32 ComputeCRC32(std::string_view data) { return ComputeCRC32(reinterpret_cast(data.data()), data.size()); } + +struct MD5Context::Impl +{ + mbedtls_md5_context context; +}; + +MD5Context::MD5Context() : m_impl{std::make_unique()} +{ + mbedtls_md5_init(&m_impl->context); + mbedtls_md5_starts_ret(&m_impl->context); +} + +// FYI: mbedtls_md5_free is unnecessary. It just zeroes the struct. +MD5Context::~MD5Context() = default; + +void MD5Context::Update(std::span data) +{ + mbedtls_md5_update_ret(&m_impl->context, data.data(), data.size()); +} + +void MD5Context::Finish(u8* output) +{ + mbedtls_md5_finish_ret(&m_impl->context, output); +} + +void ComputeMD5(std::span input, u8* output) +{ + mbedtls_md5_ret(input.data(), input.size(), output); +} + } // namespace Common diff --git a/Source/Core/Common/Hash.h b/Source/Core/Common/Hash.h index 6166b74bd9..531dcd94e1 100644 --- a/Source/Core/Common/Hash.h +++ b/Source/Core/Common/Hash.h @@ -4,6 +4,8 @@ #pragma once #include +#include +#include #include #include "Common/CommonTypes.h" @@ -21,4 +23,24 @@ u32 StartCRC32(); u32 UpdateCRC32(u32 crc, const u8* data, size_t len); u32 ComputeCRC32(const u8* data, size_t len); u32 ComputeCRC32(std::string_view data); + +class MD5Context +{ +public: + MD5Context(); + ~MD5Context(); + + void Update(std::span data); + + // output should point to 16 bytes. + void Finish(u8* output); + +private: + struct Impl; + std::unique_ptr m_impl; +}; + +// output should point to 16 bytes. +void ComputeMD5(std::span input, u8* output); + } // namespace Common From 58a0864d035ccc690698fb76063f2936906bd714 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 4 Oct 2026 16:04:42 -0500 Subject: [PATCH 2/4] WiiSave: Use Common::ComputeMD5 instead of mbedtls. --- Source/Core/Core/HW/WiiSave.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/HW/WiiSave.cpp b/Source/Core/Core/HW/WiiSave.cpp index 58a6cf57c5..c90d49a5b8 100644 --- a/Source/Core/Core/HW/WiiSave.cpp +++ b/Source/Core/Core/HW/WiiSave.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -22,10 +21,12 @@ #include #include "Common/Align.h" +#include "Common/BitUtils.h" #include "Common/CommonTypes.h" #include "Common/Crypto/SHA1.h" #include "Common/Crypto/ec.h" #include "Common/FileUtil.h" +#include "Common/Hash.h" #include "Common/IOFile.h" #include "Common/Lazy.h" #include "Common/Logging/Log.h" @@ -125,7 +126,7 @@ public: header.banner[7] &= ~1; Md5 md5_calc; - mbedtls_md5_ret(reinterpret_cast(&header), sizeof(Header), md5_calc.data()); + Common::ComputeMD5(Common::AsU8Span(header), md5_calc.data()); header.md5 = md5_calc; return header; } @@ -302,7 +303,7 @@ public: Md5 md5_file = header.md5; header.md5 = s_md5_blanker; Md5 md5_calc; - mbedtls_md5_ret(reinterpret_cast(&header), sizeof(Header), md5_calc.data()); + Common::ComputeMD5(Common::AsU8Span(header), md5_calc.data()); if (md5_file != md5_calc) { ERROR_LOG_FMT(CONSOLE, "MD5 mismatch\n {:016x}{:016x} != {:016x}{:016x}", From 304086d3179d5c9f3bc94c4487e943ec449280ab Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 4 Oct 2026 16:05:05 -0500 Subject: [PATCH 3/4] SkylanderFigure: Use Common::ComputeMD5 instead of mbedtls. --- .../Core/IOS/USB/Emulated/Skylanders/SkylanderFigure.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/IOS/USB/Emulated/Skylanders/SkylanderFigure.cpp b/Source/Core/Core/IOS/USB/Emulated/Skylanders/SkylanderFigure.cpp index 60edb515ed..7db61999bd 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Skylanders/SkylanderFigure.cpp +++ b/Source/Core/Core/IOS/USB/Emulated/Skylanders/SkylanderFigure.cpp @@ -9,10 +9,10 @@ #include #include -#include #include "Common/BitUtils.h" #include "Common/CommonTypes.h" +#include "Common/Hash.h" #include "Common/IOFile.h" #include "Common/Logging/Log.h" #include "Common/Random.h" @@ -107,7 +107,7 @@ void SkylanderFigure::Encrypt(std::span input) std::array hash_out = {}; - mbedtls_md5_ret(hash_in.data(), 0x56, hash_out.data()); + Common::ComputeMD5(hash_in, hash_out.data()); mbedtls_aes_context aes_context = {}; @@ -394,7 +394,7 @@ void SkylanderFigure::DecryptFigure(std::array* dest) const std::array hash_out = {}; - mbedtls_md5_ret(hash_in.data(), 0x56, hash_out.data()); + Common::ComputeMD5(hash_in, hash_out.data()); mbedtls_aes_context aes_context = {}; From 7e46e85e8fb3cff68f05bc160c7ac3ed77b1414b Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 4 Oct 2026 16:05:09 -0500 Subject: [PATCH 4/4] DiscIO/VolumeVerifier: Use Common::MD5Context instead of mbedtls. --- Source/Core/DiscIO/VolumeVerifier.cpp | 8 +++----- Source/Core/DiscIO/VolumeVerifier.h | 5 ++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp index 3031f14a0f..a8122f6711 100644 --- a/Source/Core/DiscIO/VolumeVerifier.cpp +++ b/Source/Core/DiscIO/VolumeVerifier.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -1087,8 +1086,7 @@ void VolumeVerifier::SetUpHashing() if (m_hashes_to_calculate.md5) { - mbedtls_md5_init(&m_md5_context); - mbedtls_md5_starts_ret(&m_md5_context); + m_md5_context.emplace(); } if (m_hashes_to_calculate.sha1) @@ -1231,7 +1229,7 @@ void VolumeVerifier::Process() if (m_hashes_to_calculate.md5) { m_md5_future = std::async(std::launch::async, [this, byte_increment] { - mbedtls_md5_update_ret(&m_md5_context, m_data.data(), byte_increment); + m_md5_context->Update(std::span{m_data}.first(byte_increment)); }); } @@ -1324,7 +1322,7 @@ void VolumeVerifier::Finish() if (m_hashes_to_calculate.md5) { m_result.hashes.md5 = std::vector(16); - mbedtls_md5_finish_ret(&m_md5_context, m_result.hashes.md5.data()); + m_md5_context->Finish(m_result.hashes.md5.data()); } if (m_hashes_to_calculate.sha1) diff --git a/Source/Core/DiscIO/VolumeVerifier.h b/Source/Core/DiscIO/VolumeVerifier.h index d057fc83d3..141954741d 100644 --- a/Source/Core/DiscIO/VolumeVerifier.h +++ b/Source/Core/DiscIO/VolumeVerifier.h @@ -10,10 +10,9 @@ #include #include -#include - #include "Common/CommonTypes.h" #include "Common/Crypto/SHA1.h" +#include "Common/Hash.h" #include "Core/IOS/ES/Formats.h" #include "DiscIO/DiscScrubber.h" #include "DiscIO/Volume.h" @@ -175,7 +174,7 @@ private: Hashes m_hashes_to_calculate{}; bool m_calculating_any_hash = false; u32 m_crc32_context = 0; - mbedtls_md5_context m_md5_context{}; + std::optional m_md5_context; std::unique_ptr m_sha1_context; u64 m_excess_bytes = 0;