summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IOS/ES/ES.h10
-rw-r--r--Source/Core/Core/IOS/ES/NandUtils.cpp30
-rw-r--r--Source/Core/Core/IOS/FS/FileSystem.h1
-rw-r--r--Source/Core/Core/WiiUtils.cpp3
4 files changed, 38 insertions, 6 deletions
diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h
index b2a0e0e802..7255c79107 100644
--- a/Source/Core/Core/IOS/ES/ES.h
+++ b/Source/Core/Core/IOS/ES/ES.h
@@ -81,6 +81,12 @@ public:
s32 ipc_fd = -1;
};
+ enum class CheckContentHashes : bool
+ {
+ Yes = true,
+ No = false,
+ };
+
IOS::ES::TMDReader FindImportTMD(u64 title_id) const;
IOS::ES::TMDReader FindInstalledTMD(u64 title_id) const;
IOS::ES::TicketReader FindSignedTicket(u64 title_id) const;
@@ -92,7 +98,9 @@ public:
// Get titles for which there is a ticket (in /ticket).
std::vector<u64> GetTitlesWithTickets() const;
- std::vector<IOS::ES::Content> GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd) const;
+ std::vector<IOS::ES::Content>
+ GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd,
+ CheckContentHashes check_content_hashes = CheckContentHashes::No) const;
u32 GetSharedContentsCount() const;
std::vector<std::array<u8, 20>> GetSharedContents() const;
diff --git a/Source/Core/Core/IOS/ES/NandUtils.cpp b/Source/Core/Core/IOS/ES/NandUtils.cpp
index 6ff03bb89e..af35bc4d9a 100644
--- a/Source/Core/Core/IOS/ES/NandUtils.cpp
+++ b/Source/Core/Core/IOS/ES/NandUtils.cpp
@@ -12,6 +12,7 @@
#include <vector>
#include <fmt/format.h>
+#include <mbedtls/sha1.h>
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
@@ -163,7 +164,9 @@ std::vector<u64> ES::GetTitlesWithTickets() const
return title_ids;
}
-std::vector<IOS::ES::Content> ES::GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd) const
+std::vector<IOS::ES::Content>
+ES::GetStoredContentsFromTMD(const IOS::ES::TMDReader& tmd,
+ CheckContentHashes check_content_hashes) const
{
if (!tmd.IsValid())
return {};
@@ -174,10 +177,29 @@ std::vector<IOS::ES::Content> ES::GetStoredContentsFromTMD(const IOS::ES::TMDRea
std::vector<IOS::ES::Content> stored_contents;
std::copy_if(contents.begin(), contents.end(), std::back_inserter(stored_contents),
- [this, &tmd, &map](const IOS::ES::Content& content) {
+ [this, &tmd, &map, check_content_hashes](const IOS::ES::Content& content) {
+ const auto fs = m_ios.GetFS();
+
const std::string path = GetContentPath(tmd.GetTitleId(), content, map);
- return !path.empty() &&
- m_ios.GetFS()->GetMetadata(PID_KERNEL, PID_KERNEL, path).Succeeded();
+ if (path.empty())
+ return false;
+
+ // Check whether the content file exists.
+ const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::Read);
+ if (!file.Succeeded())
+ return false;
+
+ // If content hash checks are disabled, all we have to do is check for existence.
+ if (check_content_hashes == CheckContentHashes::No)
+ return true;
+
+ // Otherwise, check whether the installed content SHA1 matches the expected hash.
+ std::vector<u8> content_data(file->GetStatus()->size);
+ if (!file->Read(content_data.data(), content_data.size()))
+ return false;
+ std::array<u8, 20> sha1{};
+ mbedtls_sha1_ret(content_data.data(), content_data.size(), sha1.data());
+ return sha1 == content.sha1;
});
return stored_contents;
diff --git a/Source/Core/Core/IOS/FS/FileSystem.h b/Source/Core/Core/IOS/FS/FileSystem.h
index 7d53b6ca0f..24274b7528 100644
--- a/Source/Core/Core/IOS/FS/FileSystem.h
+++ b/Source/Core/Core/IOS/FS/FileSystem.h
@@ -205,6 +205,7 @@ public:
/// Reposition the file offset for a file descriptor.
virtual Result<u32> SeekFile(Fd fd, u32 offset, SeekMode mode) = 0;
/// Get status for a file descriptor.
+ /// Guaranteed to succeed for a valid file descriptor.
virtual Result<FileStatus> GetFileStatus(Fd fd) = 0;
/// Create a file with the specified path and metadata.
diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp
index d0d0395efb..0abc8de162 100644
--- a/Source/Core/Core/WiiUtils.cpp
+++ b/Source/Core/Core/WiiUtils.cpp
@@ -149,7 +149,8 @@ bool InstallWAD(IOS::HLE::Kernel& ios, const DiscIO::VolumeWAD& wad, InstallType
const u64 title_id = wad.GetTMD().GetTitleId();
// Skip the install if the WAD is already installed.
- const auto installed_contents = ios.GetES()->GetStoredContentsFromTMD(wad.GetTMD());
+ const auto installed_contents = ios.GetES()->GetStoredContentsFromTMD(
+ wad.GetTMD(), IOS::HLE::Device::ES::CheckContentHashes::Yes);
if (wad.GetTMD().GetContents() == installed_contents)
{
// Clear the "temporary title ID" flag in case the user tries to permanently install a title