From daa5ff9a81447e2fad1746a17d69c1f07b362de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Wed, 8 Mar 2017 16:10:27 +0100 Subject: [PATCH] IOS/ES: Check the content hash during imports This adds a hash check for imported contents. IOS does it for security; we do it for a somewhat different reason, to catch content decryption bugs before incorrectly decrypted contents get written to the NAND, which can cause titles to be corrupted. Either way, we should have been doing this check in all cases. --- Source/Core/Core/IOS/ES/ES.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index de5580a440..aad3e26434 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -14,6 +14,7 @@ #include #include +#include #include "Common/Align.h" #include "Common/Assert.h" @@ -583,6 +584,13 @@ IPCCommandResult ES::AddContentData(const IOCtlVRequest& request) return GetDefaultReply(IPC_SUCCESS); } +static bool CheckIfContentHashMatches(const std::vector& content, const IOS::ES::Content& info) +{ + std::array sha1; + mbedtls_sha1(content.data(), info.size, sha1.data()); + return sha1 == info.sha1; +} + IPCCommandResult ES::AddContentFinish(const IOCtlVRequest& request) { if (!request.HasNumberOfValidVectors(1, 0)) @@ -617,6 +625,11 @@ IPCCommandResult ES::AddContentFinish(const IOCtlVRequest& request) std::vector decrypted_data(m_addtitle_content_buffer.size()); mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, m_addtitle_content_buffer.size(), iv, m_addtitle_content_buffer.data(), decrypted_data.data()); + if (!CheckIfContentHashMatches(decrypted_data, content_info)) + { + ERROR_LOG(IOS_ES, "AddContentFinish: Hash for content %08x doesn't match", content_info.id); + return GetDefaultReply(ES_HASH_DOESNT_MATCH); + } std::string content_path; if (content_info.IsShared())