From 0c8bed734b9317e27b755e4ba2310263d7afea06 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Wed, 19 Apr 2023 19:41:33 +0200 Subject: [PATCH] early-access version 3513 --- README.md | 2 +- src/core/crypto/key_manager.cpp | 111 +++++++++++++----------- src/core/crypto/key_manager.h | 3 +- src/core/hle/service/audio/audout_u.cpp | 1 + 4 files changed, 66 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index c4401788c..70e319a3e 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3512. +This is the source code for early-access 3513. ## Legal Notice diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index eed5cefac..c63dc9d5a 100755 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -156,6 +156,10 @@ u64 GetSignatureTypePaddingSize(SignatureType type) { UNREACHABLE(); } +bool Ticket::IsValid() const { + return !std::holds_alternative(data); +} + SignatureType Ticket::GetSignatureType() const { if (const auto* ticket = std::get_if(&data)) { return ticket->sig_type; @@ -236,6 +240,7 @@ bool Ticket::Read(Ticket& ticket_out, const FileSys::VirtualFile& file) { return true; } default: + ticket_out.data.emplace(); return false; } } @@ -535,67 +540,75 @@ static std::optional FindTicketOffset(const std::array& data) { std::optional> ParseTicket(const Ticket& ticket, const RSAKeyPair<2048>& key) { - const auto issuer = ticket.GetData().issuer; - if (IsAllZeroArray(issuer)) { - return std::nullopt; - } - if (issuer[0] != 'R' || issuer[1] != 'o' || issuer[2] != 'o' || issuer[3] != 't') { - LOG_INFO(Crypto, "Attempting to parse ticket with non-standard certificate authority."); - } - - Key128 rights_id = ticket.GetData().rights_id; - - if (rights_id == Key128{}) { + if (!ticket.IsValid()) { return std::nullopt; } - if (!std::any_of(ticket.GetData().title_key_common_pad.begin(), - ticket.GetData().title_key_common_pad.end(), [](u8 b) { return b != 0; })) { - return std::make_pair(rights_id, ticket.GetData().title_key_common); - } + // Dirty hack, figure out why ticket.data variant is invalid + try { + const auto issuer = ticket.GetData().issuer; + if (IsAllZeroArray(issuer)) { + return std::nullopt; + } + if (issuer[0] != 'R' || issuer[1] != 'o' || issuer[2] != 'o' || issuer[3] != 't') { + LOG_INFO(Crypto, "Attempting to parse ticket with non-standard certificate authority."); + } - mbedtls_mpi D; // RSA Private Exponent - mbedtls_mpi N; // RSA Modulus - mbedtls_mpi S; // Input - mbedtls_mpi M; // Output + Key128 rights_id = ticket.GetData().rights_id; - mbedtls_mpi_init(&D); - mbedtls_mpi_init(&N); - mbedtls_mpi_init(&S); - mbedtls_mpi_init(&M); + if (rights_id == Key128{}) { + return std::nullopt; + } - mbedtls_mpi_read_binary(&D, key.decryption_key.data(), key.decryption_key.size()); - mbedtls_mpi_read_binary(&N, key.modulus.data(), key.modulus.size()); - mbedtls_mpi_read_binary(&S, ticket.GetData().title_key_block.data(), 0x100); + if (ticket.GetData().type == TitleKeyType::Common) { + return std::make_pair(rights_id, ticket.GetData().title_key_common); + } - mbedtls_mpi_exp_mod(&M, &S, &D, &N, nullptr); + mbedtls_mpi D; // RSA Private Exponent + mbedtls_mpi N; // RSA Modulus + mbedtls_mpi S; // Input + mbedtls_mpi M; // Output - std::array rsa_step; - mbedtls_mpi_write_binary(&M, rsa_step.data(), rsa_step.size()); + mbedtls_mpi_init(&D); + mbedtls_mpi_init(&N); + mbedtls_mpi_init(&S); + mbedtls_mpi_init(&M); - u8 m_0 = rsa_step[0]; - std::array m_1; - std::memcpy(m_1.data(), rsa_step.data() + 0x01, m_1.size()); - std::array m_2; - std::memcpy(m_2.data(), rsa_step.data() + 0x21, m_2.size()); + mbedtls_mpi_read_binary(&D, key.decryption_key.data(), key.decryption_key.size()); + mbedtls_mpi_read_binary(&N, key.modulus.data(), key.modulus.size()); + mbedtls_mpi_read_binary(&S, ticket.GetData().title_key_block.data(), 0x100); - if (m_0 != 0) { + mbedtls_mpi_exp_mod(&M, &S, &D, &N, nullptr); + + std::array rsa_step; + mbedtls_mpi_write_binary(&M, rsa_step.data(), rsa_step.size()); + + u8 m_0 = rsa_step[0]; + std::array m_1; + std::memcpy(m_1.data(), rsa_step.data() + 0x01, m_1.size()); + std::array m_2; + std::memcpy(m_2.data(), rsa_step.data() + 0x21, m_2.size()); + + if (m_0 != 0) { + return std::nullopt; + } + + m_1 = m_1 ^ MGF1<0x20>(m_2); + m_2 = m_2 ^ MGF1<0xDF>(m_1); + + const auto offset = FindTicketOffset(m_2); + if (!offset) { + return std::nullopt; + } + ASSERT(*offset > 0); + + Key128 key_temp{}; + std::memcpy(key_temp.data(), m_2.data() + *offset, key_temp.size()); + + return std::make_pair(rights_id, key_temp); + } catch (const std::bad_variant_access&) { return std::nullopt; } - - m_1 = m_1 ^ MGF1<0x20>(m_2); - m_2 = m_2 ^ MGF1<0xDF>(m_1); - - const auto offset = FindTicketOffset(m_2); - if (!offset) { - return std::nullopt; - } - ASSERT(*offset > 0); - - Key128 key_temp{}; - std::memcpy(key_temp.data(), m_2.data() + *offset, key_temp.size()); - - return std::make_pair(rights_id, key_temp); } KeyManager::KeyManager() { diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index e0d68fe9e..eb9aab86c 100755 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -96,8 +96,9 @@ struct ECDSATicket { }; struct Ticket { - std::variant data; + std::variant data; + bool IsValid() const; SignatureType GetSignatureType() const; TicketData& GetData(); const TicketData& GetData() const; diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index dd143d345..5d1b11171 100755 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -284,6 +284,7 @@ void AudOutU::OpenAudioOut(HLERequestContext& ctx) { result = audio_out->GetImpl()->GetSystem().Initialize(device_name, in_params, handle, applet_resource_user_id); if (result.IsError()) { + LOG_ERROR(Service_Audio, "Failed to initialize the AudioOut System!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return;