summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorshuffle2 <godisgovernment@gmail.com>2017-06-27 01:02:42 -0700
committerGitHub <noreply@github.com>2017-06-27 01:02:42 -0700
commit0f3ee2f209be901a0b3de2d01d6eb3a47f4af888 (patch)
treed623955f89db5fe078fdf9c5acd21e85347118cc /Source/Core
parent3094b1bd4fa2a9827d8f51884be1415c048974fd (diff)
parent9f08534a47b7da028ff3c027b935b073a94fcbbd (diff)
Merge pull request #5700 from leoetlino/title-key
ESFormats: Minor changes
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IOS/ES/ES.h2
-rw-r--r--Source/Core/Core/IOS/ES/Formats.cpp23
-rw-r--r--Source/Core/Core/IOS/ES/Formats.h8
-rw-r--r--Source/Core/Core/IOS/ES/TitleManagement.cpp10
-rw-r--r--Source/Core/Core/IOS/WFS/WFSI.cpp2
-rw-r--r--Source/Core/DiscIO/NANDContentLoader.cpp2
-rw-r--r--Source/Core/DiscIO/VolumeWii.cpp5
7 files changed, 29 insertions, 23 deletions
diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h
index b53a8780f5..747fa0a942 100644
--- a/Source/Core/Core/IOS/ES/ES.h
+++ b/Source/Core/Core/IOS/ES/ES.h
@@ -80,7 +80,7 @@ public:
bool valid = false;
IOS::ES::TMDReader tmd;
- std::vector<u8> title_key;
+ std::array<u8, 16> title_key;
std::map<u32, ExportContent> contents;
};
diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp
index 2a303b5d7f..b7e1e9c106 100644
--- a/Source/Core/Core/IOS/ES/Formats.cpp
+++ b/Source/Core/Core/IOS/ES/Formats.cpp
@@ -380,7 +380,7 @@ u64 TicketReader::GetTitleId() const
return Common::swap64(m_bytes.data() + offsetof(Ticket, title_id));
}
-std::vector<u8> TicketReader::GetTitleKey() const
+std::array<u8, 16> TicketReader::GetTitleKey(const HLE::IOSC& iosc) const
{
u8 iv[16] = {};
std::copy_n(&m_bytes[offsetof(Ticket, title_id)], sizeof(Ticket::title_id), iv);
@@ -394,17 +394,20 @@ std::vector<u8> TicketReader::GetTitleKey() const
GetTitleId(), index);
}
- const bool is_rvt = (GetIssuer() == "Root-CA00000002-XS00000006");
- const HLE::IOSC::ConsoleType console_type =
- is_rvt ? HLE::IOSC::ConsoleType::RVT : HLE::IOSC::ConsoleType::Retail;
-
- std::vector<u8> key(16);
- HLE::IOSC iosc(console_type);
+ std::array<u8, 16> key;
iosc.Decrypt(common_key_handle, iv, &m_bytes[offsetof(Ticket, title_key)], 16, key.data(),
HLE::PID_ES);
return key;
}
+std::array<u8, 16> TicketReader::GetTitleKey() const
+{
+ const bool is_rvt = (GetIssuer() == "Root-CA00000002-XS00000006");
+ const HLE::IOSC::ConsoleType console_type =
+ is_rvt ? HLE::IOSC::ConsoleType::RVT : HLE::IOSC::ConsoleType::Retail;
+ return GetTitleKey(HLE::IOSC{console_type});
+}
+
void TicketReader::DeleteTicket(u64 ticket_id_to_delete)
{
std::vector<u8> new_ticket;
@@ -420,16 +423,16 @@ void TicketReader::DeleteTicket(u64 ticket_id_to_delete)
m_bytes = std::move(new_ticket);
}
-s32 TicketReader::Unpersonalise()
+HLE::ReturnCode TicketReader::Unpersonalise(HLE::IOSC& iosc)
{
const auto ticket_begin = m_bytes.begin();
// IOS uses IOSC to compute an AES key from the peer public key and the device's private ECC key,
// which is used the decrypt the title key. The IV is the ticket ID (8 bytes), zero extended.
using namespace HLE;
- IOSC iosc;
IOSC::Handle public_handle;
- s32 ret = iosc.CreateObject(&public_handle, IOSC::TYPE_PUBLIC_KEY, IOSC::SUBTYPE_ECC233, PID_ES);
+ ReturnCode ret =
+ iosc.CreateObject(&public_handle, IOSC::TYPE_PUBLIC_KEY, IOSC::SUBTYPE_ECC233, PID_ES);
if (ret != IPC_SUCCESS)
return ret;
diff --git a/Source/Core/Core/IOS/ES/Formats.h b/Source/Core/Core/IOS/ES/Formats.h
index dd1352b367..3998076cbe 100644
--- a/Source/Core/Core/IOS/ES/Formats.h
+++ b/Source/Core/Core/IOS/ES/Formats.h
@@ -222,14 +222,18 @@ public:
u32 GetDeviceId() const;
u64 GetTitleId() const;
- std::vector<u8> GetTitleKey() const;
+ // Get the decrypted title key.
+ std::array<u8, 16> GetTitleKey(const HLE::IOSC& iosc) const;
+ // Same as the above version, but guesses the console type depending on the issuer
+ // and constructs a temporary IOSC instance.
+ std::array<u8, 16> GetTitleKey() const;
// Deletes a ticket with the given ticket ID from the internal buffer.
void DeleteTicket(u64 ticket_id);
// Decrypts the title key field for a "personalised" ticket -- one that is device-specific
// and has a title key that must be decrypted first.
- s32 Unpersonalise();
+ HLE::ReturnCode Unpersonalise(HLE::IOSC& iosc);
};
class SharedContentMap final
diff --git a/Source/Core/Core/IOS/ES/TitleManagement.cpp b/Source/Core/Core/IOS/ES/TitleManagement.cpp
index 58f55b84e5..3654f90d85 100644
--- a/Source/Core/Core/IOS/ES/TitleManagement.cpp
+++ b/Source/Core/Core/IOS/ES/TitleManagement.cpp
@@ -60,7 +60,7 @@ ReturnCode ES::ImportTicket(const std::vector<u8>& ticket_bytes, const std::vect
WARN_LOG(IOS_ES, "Device ID mismatch: ticket %08x, device %08x", ticket_device_id, device_id);
return ES_DEVICE_ID_MISMATCH;
}
- const ReturnCode ret = static_cast<ReturnCode>(ticket.Unpersonalise());
+ const ReturnCode ret = ticket.Unpersonalise(m_ios.GetIOSC());
if (ret < 0)
{
ERROR_LOG(IOS_ES, "ImportTicket: Failed to unpersonalise ticket for %016" PRIx64 " (%d)",
@@ -294,9 +294,9 @@ ReturnCode ES::ImportContentEnd(Context& context, u32 content_fd)
u8 iv[16] = {0};
iv[0] = (content_info.index >> 8) & 0xFF;
iv[1] = content_info.index & 0xFF;
- std::vector<u8> decrypted_data = Common::AES::Decrypt(ticket.GetTitleKey().data(), iv,
- context.title_import.content_buffer.data(),
- context.title_import.content_buffer.size());
+ std::vector<u8> decrypted_data = Common::AES::Decrypt(
+ ticket.GetTitleKey(m_ios.GetIOSC()).data(), iv, context.title_import.content_buffer.data(),
+ context.title_import.content_buffer.size());
if (!CheckIfContentHashMatches(decrypted_data, content_info))
{
ERROR_LOG(IOS_ES, "ImportContentEnd: Hash for content %08x doesn't match", content_info.id);
@@ -570,7 +570,7 @@ ReturnCode ES::ExportTitleInit(Context& context, u64 title_id, u8* tmd_bytes, u3
if (ticket.GetTitleId() != context.title_export.tmd.GetTitleId())
return ES_EINVAL;
- context.title_export.title_key = ticket.GetTitleKey();
+ context.title_export.title_key = ticket.GetTitleKey(m_ios.GetIOSC());
const std::vector<u8>& raw_tmd = context.title_export.tmd.GetBytes();
if (tmd_size != raw_tmd.size())
diff --git a/Source/Core/Core/IOS/WFS/WFSI.cpp b/Source/Core/Core/IOS/WFS/WFSI.cpp
index 905e7629e8..c35eeec0e9 100644
--- a/Source/Core/Core/IOS/WFS/WFSI.cpp
+++ b/Source/Core/Core/IOS/WFS/WFSI.cpp
@@ -117,7 +117,7 @@ IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
break;
}
- memcpy(m_aes_key, ticket.GetTitleKey().data(), sizeof(m_aes_key));
+ memcpy(m_aes_key, ticket.GetTitleKey(m_ios.GetIOSC()).data(), sizeof(m_aes_key));
mbedtls_aes_setkey_dec(&m_aes_ctx, m_aes_key, 128);
break;
diff --git a/Source/Core/DiscIO/NANDContentLoader.cpp b/Source/Core/DiscIO/NANDContentLoader.cpp
index fe5d77d15e..0178c3c14e 100644
--- a/Source/Core/DiscIO/NANDContentLoader.cpp
+++ b/Source/Core/DiscIO/NANDContentLoader.cpp
@@ -186,7 +186,7 @@ void NANDContentLoader::InitializeContentEntries(const std::vector<u8>& data_app
m_Content.resize(contents.size());
u32 data_app_offset = 0;
- const std::vector<u8> title_key = m_ticket.GetTitleKey();
+ const std::array<u8, 16> title_key = m_ticket.GetTitleKey();
IOS::ES::SharedContentMap shared_content{m_root};
for (size_t i = 0; i < contents.size(); ++i)
diff --git a/Source/Core/DiscIO/VolumeWii.cpp b/Source/Core/DiscIO/VolumeWii.cpp
index b8215527a6..8ccca04409 100644
--- a/Source/Core/DiscIO/VolumeWii.cpp
+++ b/Source/Core/DiscIO/VolumeWii.cpp
@@ -5,6 +5,7 @@
#include "DiscIO/VolumeWii.h"
#include <algorithm>
+#include <array>
#include <cstddef>
#include <cstring>
#include <map>
@@ -97,9 +98,7 @@ VolumeWii::VolumeWii(std::unique_ptr<BlobReader> reader)
IOS::ES::TMDReader tmd{std::move(tmd_buffer)};
// Get the decryption key
- const std::vector<u8> key = ticket.GetTitleKey();
- if (key.size() != 16)
- continue;
+ const std::array<u8, 16> key = ticket.GetTitleKey();
std::unique_ptr<mbedtls_aes_context> aes_context = std::make_unique<mbedtls_aes_context>();
mbedtls_aes_setkey_dec(aes_context.get(), key.data(), 128);