diff options
| -rw-r--r-- | src/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | src/common/atomic_ops.cpp | 37 | ||||
| -rw-r--r-- | src/common/atomic_ops.h | 10 | ||||
| -rw-r--r-- | src/common/logging/backend.cpp | 22 | ||||
| -rw-r--r-- | src/common/logging/backend.h | 14 | ||||
| -rw-r--r-- | src/core/crypto/aes_util.cpp | 21 | ||||
| -rw-r--r-- | src/core/crypto/aes_util.h | 9 | ||||
| -rw-r--r-- | src/core/crypto/ctr_encryption_layer.cpp | 9 | ||||
| -rw-r--r-- | src/core/crypto/ctr_encryption_layer.h | 9 | ||||
| -rw-r--r-- | src/core/crypto/partition_data_manager.cpp | 5 | ||||
| -rw-r--r-- | src/core/file_sys/content_archive.cpp | 7 | ||||
| -rw-r--r-- | src/core/file_sys/nca_patch.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 21 | ||||
| -rw-r--r-- | src/core/memory.cpp | 10 |
14 files changed, 98 insertions, 86 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54dca3302..71efbb40d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -60,9 +60,14 @@ else() | |||
| 60 | -Wmissing-declarations | 60 | -Wmissing-declarations |
| 61 | -Wno-attributes | 61 | -Wno-attributes |
| 62 | -Wno-unused-parameter | 62 | -Wno-unused-parameter |
| 63 | -fconcepts | ||
| 64 | ) | 63 | ) |
| 65 | 64 | ||
| 65 | # TODO: Remove when we update to a GCC compiler that enables this | ||
| 66 | # by default (i.e. GCC 10 or newer). | ||
| 67 | if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) | ||
| 68 | add_compile_options(-fconcepts) | ||
| 69 | endif() | ||
| 70 | |||
| 66 | if (ARCHITECTURE_x86_64) | 71 | if (ARCHITECTURE_x86_64) |
| 67 | add_compile_options("-mcx16") | 72 | add_compile_options("-mcx16") |
| 68 | endif() | 73 | endif() |
diff --git a/src/common/atomic_ops.cpp b/src/common/atomic_ops.cpp index 1098e21ff..1612d0e67 100644 --- a/src/common/atomic_ops.cpp +++ b/src/common/atomic_ops.cpp | |||
| @@ -14,50 +14,55 @@ namespace Common { | |||
| 14 | 14 | ||
| 15 | #if _MSC_VER | 15 | #if _MSC_VER |
| 16 | 16 | ||
| 17 | bool AtomicCompareAndSwap(u8 volatile* pointer, u8 value, u8 expected) { | 17 | bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) { |
| 18 | u8 result = _InterlockedCompareExchange8((char*)pointer, value, expected); | 18 | const u8 result = |
| 19 | _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); | ||
| 19 | return result == expected; | 20 | return result == expected; |
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | bool AtomicCompareAndSwap(u16 volatile* pointer, u16 value, u16 expected) { | 23 | bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) { |
| 23 | u16 result = _InterlockedCompareExchange16((short*)pointer, value, expected); | 24 | const u16 result = |
| 25 | _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); | ||
| 24 | return result == expected; | 26 | return result == expected; |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | bool AtomicCompareAndSwap(u32 volatile* pointer, u32 value, u32 expected) { | 29 | bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) { |
| 28 | u32 result = _InterlockedCompareExchange((long*)pointer, value, expected); | 30 | const u32 result = |
| 31 | _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); | ||
| 29 | return result == expected; | 32 | return result == expected; |
| 30 | } | 33 | } |
| 31 | 34 | ||
| 32 | bool AtomicCompareAndSwap(u64 volatile* pointer, u64 value, u64 expected) { | 35 | bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) { |
| 33 | u64 result = _InterlockedCompareExchange64((__int64*)pointer, value, expected); | 36 | const u64 result = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), |
| 37 | value, expected); | ||
| 34 | return result == expected; | 38 | return result == expected; |
| 35 | } | 39 | } |
| 36 | 40 | ||
| 37 | bool AtomicCompareAndSwap(u64 volatile* pointer, u128 value, u128 expected) { | 41 | bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) { |
| 38 | return _InterlockedCompareExchange128((__int64*)pointer, value[1], value[0], | 42 | return _InterlockedCompareExchange128(reinterpret_cast<volatile __int64*>(pointer), value[1], |
| 39 | (__int64*)expected.data()) != 0; | 43 | value[0], |
| 44 | reinterpret_cast<__int64*>(expected.data())) != 0; | ||
| 40 | } | 45 | } |
| 41 | 46 | ||
| 42 | #else | 47 | #else |
| 43 | 48 | ||
| 44 | bool AtomicCompareAndSwap(u8 volatile* pointer, u8 value, u8 expected) { | 49 | bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) { |
| 45 | return __sync_bool_compare_and_swap(pointer, expected, value); | 50 | return __sync_bool_compare_and_swap(pointer, expected, value); |
| 46 | } | 51 | } |
| 47 | 52 | ||
| 48 | bool AtomicCompareAndSwap(u16 volatile* pointer, u16 value, u16 expected) { | 53 | bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) { |
| 49 | return __sync_bool_compare_and_swap(pointer, expected, value); | 54 | return __sync_bool_compare_and_swap(pointer, expected, value); |
| 50 | } | 55 | } |
| 51 | 56 | ||
| 52 | bool AtomicCompareAndSwap(u32 volatile* pointer, u32 value, u32 expected) { | 57 | bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) { |
| 53 | return __sync_bool_compare_and_swap(pointer, expected, value); | 58 | return __sync_bool_compare_and_swap(pointer, expected, value); |
| 54 | } | 59 | } |
| 55 | 60 | ||
| 56 | bool AtomicCompareAndSwap(u64 volatile* pointer, u64 value, u64 expected) { | 61 | bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) { |
| 57 | return __sync_bool_compare_and_swap(pointer, expected, value); | 62 | return __sync_bool_compare_and_swap(pointer, expected, value); |
| 58 | } | 63 | } |
| 59 | 64 | ||
| 60 | bool AtomicCompareAndSwap(u64 volatile* pointer, u128 value, u128 expected) { | 65 | bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) { |
| 61 | unsigned __int128 value_a; | 66 | unsigned __int128 value_a; |
| 62 | unsigned __int128 expected_a; | 67 | unsigned __int128 expected_a; |
| 63 | std::memcpy(&value_a, value.data(), sizeof(u128)); | 68 | std::memcpy(&value_a, value.data(), sizeof(u128)); |
diff --git a/src/common/atomic_ops.h b/src/common/atomic_ops.h index e6181d521..8d6b73c00 100644 --- a/src/common/atomic_ops.h +++ b/src/common/atomic_ops.h | |||
| @@ -8,10 +8,10 @@ | |||
| 8 | 8 | ||
| 9 | namespace Common { | 9 | namespace Common { |
| 10 | 10 | ||
| 11 | bool AtomicCompareAndSwap(u8 volatile* pointer, u8 value, u8 expected); | 11 | bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected); |
| 12 | bool AtomicCompareAndSwap(u16 volatile* pointer, u16 value, u16 expected); | 12 | bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected); |
| 13 | bool AtomicCompareAndSwap(u32 volatile* pointer, u32 value, u32 expected); | 13 | bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected); |
| 14 | bool AtomicCompareAndSwap(u64 volatile* pointer, u64 value, u64 expected); | 14 | bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected); |
| 15 | bool AtomicCompareAndSwap(u64 volatile* pointer, u128 value, u128 expected); | 15 | bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected); |
| 16 | 16 | ||
| 17 | } // namespace Common | 17 | } // namespace Common |
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 04bc3128f..62cfde397 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -113,19 +113,19 @@ private: | |||
| 113 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, | 113 | Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, |
| 114 | const char* function, std::string message) const { | 114 | const char* function, std::string message) const { |
| 115 | using std::chrono::duration_cast; | 115 | using std::chrono::duration_cast; |
| 116 | using std::chrono::microseconds; | ||
| 116 | using std::chrono::steady_clock; | 117 | using std::chrono::steady_clock; |
| 117 | 118 | ||
| 118 | Entry entry; | 119 | return { |
| 119 | entry.timestamp = | 120 | .timestamp = duration_cast<microseconds>(steady_clock::now() - time_origin), |
| 120 | duration_cast<std::chrono::microseconds>(steady_clock::now() - time_origin); | 121 | .log_class = log_class, |
| 121 | entry.log_class = log_class; | 122 | .log_level = log_level, |
| 122 | entry.log_level = log_level; | 123 | .filename = filename, |
| 123 | entry.filename = filename; | 124 | .line_num = line_nr, |
| 124 | entry.line_num = line_nr; | 125 | .function = function, |
| 125 | entry.function = function; | 126 | .message = std::move(message), |
| 126 | entry.message = std::move(message); | 127 | .final_entry = false, |
| 127 | 128 | }; | |
| 128 | return entry; | ||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | std::mutex writing_mutex; | 131 | std::mutex writing_mutex; |
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index fc338c70d..e5d702568 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h | |||
| @@ -21,19 +21,13 @@ class Filter; | |||
| 21 | */ | 21 | */ |
| 22 | struct Entry { | 22 | struct Entry { |
| 23 | std::chrono::microseconds timestamp; | 23 | std::chrono::microseconds timestamp; |
| 24 | Class log_class; | 24 | Class log_class{}; |
| 25 | Level log_level; | 25 | Level log_level{}; |
| 26 | const char* filename; | 26 | const char* filename = nullptr; |
| 27 | unsigned int line_num; | 27 | unsigned int line_num = 0; |
| 28 | std::string function; | 28 | std::string function; |
| 29 | std::string message; | 29 | std::string message; |
| 30 | bool final_entry = false; | 30 | bool final_entry = false; |
| 31 | |||
| 32 | Entry() = default; | ||
| 33 | Entry(Entry&& o) = default; | ||
| 34 | |||
| 35 | Entry& operator=(Entry&& o) = default; | ||
| 36 | Entry& operator=(const Entry& o) = default; | ||
| 37 | }; | 31 | }; |
| 38 | 32 | ||
| 39 | /** | 33 | /** |
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp index 4be76bb43..330996b24 100644 --- a/src/core/crypto/aes_util.cpp +++ b/src/core/crypto/aes_util.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | ||
| 5 | #include <mbedtls/cipher.h> | 6 | #include <mbedtls/cipher.h> |
| 6 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| @@ -10,8 +11,10 @@ | |||
| 10 | 11 | ||
| 11 | namespace Core::Crypto { | 12 | namespace Core::Crypto { |
| 12 | namespace { | 13 | namespace { |
| 13 | std::vector<u8> CalculateNintendoTweak(std::size_t sector_id) { | 14 | using NintendoTweak = std::array<u8, 16>; |
| 14 | std::vector<u8> out(0x10); | 15 | |
| 16 | NintendoTweak CalculateNintendoTweak(std::size_t sector_id) { | ||
| 17 | NintendoTweak out{}; | ||
| 15 | for (std::size_t i = 0xF; i <= 0xF; --i) { | 18 | for (std::size_t i = 0xF; i <= 0xF; --i) { |
| 16 | out[i] = sector_id & 0xFF; | 19 | out[i] = sector_id & 0xFF; |
| 17 | sector_id >>= 8; | 20 | sector_id >>= 8; |
| @@ -64,13 +67,6 @@ AESCipher<Key, KeySize>::~AESCipher() { | |||
| 64 | } | 67 | } |
| 65 | 68 | ||
| 66 | template <typename Key, std::size_t KeySize> | 69 | template <typename Key, std::size_t KeySize> |
| 67 | void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) { | ||
| 68 | ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) || | ||
| 69 | mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0, | ||
| 70 | "Failed to set IV on mbedtls ciphers."); | ||
| 71 | } | ||
| 72 | |||
| 73 | template <typename Key, std::size_t KeySize> | ||
| 74 | void AESCipher<Key, KeySize>::Transcode(const u8* src, std::size_t size, u8* dest, Op op) const { | 70 | void AESCipher<Key, KeySize>::Transcode(const u8* src, std::size_t size, u8* dest, Op op) const { |
| 75 | auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; | 71 | auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; |
| 76 | 72 | ||
| @@ -124,6 +120,13 @@ void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, std::size_t size, u8* | |||
| 124 | } | 120 | } |
| 125 | } | 121 | } |
| 126 | 122 | ||
| 123 | template <typename Key, std::size_t KeySize> | ||
| 124 | void AESCipher<Key, KeySize>::SetIVImpl(const u8* data, std::size_t size) { | ||
| 125 | ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, data, size) || | ||
| 126 | mbedtls_cipher_set_iv(&ctx->decryption_context, data, size)) == 0, | ||
| 127 | "Failed to set IV on mbedtls ciphers."); | ||
| 128 | } | ||
| 129 | |||
| 127 | template class AESCipher<Key128>; | 130 | template class AESCipher<Key128>; |
| 128 | template class AESCipher<Key256>; | 131 | template class AESCipher<Key256>; |
| 129 | } // namespace Core::Crypto | 132 | } // namespace Core::Crypto |
diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h index edc4ab910..e2a304186 100644 --- a/src/core/crypto/aes_util.h +++ b/src/core/crypto/aes_util.h | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <type_traits> | 8 | #include <type_traits> |
| 9 | #include <vector> | ||
| 10 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 11 | #include "core/file_sys/vfs.h" | 10 | #include "core/file_sys/vfs.h" |
| 12 | 11 | ||
| @@ -32,10 +31,12 @@ class AESCipher { | |||
| 32 | 31 | ||
| 33 | public: | 32 | public: |
| 34 | AESCipher(Key key, Mode mode); | 33 | AESCipher(Key key, Mode mode); |
| 35 | |||
| 36 | ~AESCipher(); | 34 | ~AESCipher(); |
| 37 | 35 | ||
| 38 | void SetIV(std::vector<u8> iv); | 36 | template <typename ContiguousContainer> |
| 37 | void SetIV(const ContiguousContainer& container) { | ||
| 38 | SetIVImpl(std::data(container), std::size(container)); | ||
| 39 | } | ||
| 39 | 40 | ||
| 40 | template <typename Source, typename Dest> | 41 | template <typename Source, typename Dest> |
| 41 | void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const { | 42 | void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const { |
| @@ -59,6 +60,8 @@ public: | |||
| 59 | std::size_t sector_size, Op op); | 60 | std::size_t sector_size, Op op); |
| 60 | 61 | ||
| 61 | private: | 62 | private: |
| 63 | void SetIVImpl(const u8* data, std::size_t size); | ||
| 64 | |||
| 62 | std::unique_ptr<CipherContext> ctx; | 65 | std::unique_ptr<CipherContext> ctx; |
| 63 | }; | 66 | }; |
| 64 | } // namespace Core::Crypto | 67 | } // namespace Core::Crypto |
diff --git a/src/core/crypto/ctr_encryption_layer.cpp b/src/core/crypto/ctr_encryption_layer.cpp index 902841c77..5c84bb0a4 100644 --- a/src/core/crypto/ctr_encryption_layer.cpp +++ b/src/core/crypto/ctr_encryption_layer.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <cstring> | 6 | #include <cstring> |
| 6 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 7 | #include "core/crypto/ctr_encryption_layer.h" | 8 | #include "core/crypto/ctr_encryption_layer.h" |
| @@ -10,8 +11,7 @@ namespace Core::Crypto { | |||
| 10 | 11 | ||
| 11 | CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, | 12 | CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, |
| 12 | std::size_t base_offset) | 13 | std::size_t base_offset) |
| 13 | : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR), | 14 | : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR) {} |
| 14 | iv(16, 0) {} | ||
| 15 | 15 | ||
| 16 | std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t offset) const { | 16 | std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t offset) const { |
| 17 | if (length == 0) | 17 | if (length == 0) |
| @@ -39,9 +39,8 @@ std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t o | |||
| 39 | return read + Read(data + read, length - read, offset + read); | 39 | return read + Read(data + read, length - read, offset + read); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | void CTREncryptionLayer::SetIV(const std::vector<u8>& iv_) { | 42 | void CTREncryptionLayer::SetIV(const IVData& iv_) { |
| 43 | const auto length = std::min(iv_.size(), iv.size()); | 43 | iv = iv_; |
| 44 | iv.assign(iv_.cbegin(), iv_.cbegin() + length); | ||
| 45 | } | 44 | } |
| 46 | 45 | ||
| 47 | void CTREncryptionLayer::UpdateIV(std::size_t offset) const { | 46 | void CTREncryptionLayer::UpdateIV(std::size_t offset) const { |
diff --git a/src/core/crypto/ctr_encryption_layer.h b/src/core/crypto/ctr_encryption_layer.h index a7bf810f4..a2429f001 100644 --- a/src/core/crypto/ctr_encryption_layer.h +++ b/src/core/crypto/ctr_encryption_layer.h | |||
| @@ -4,7 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <vector> | 7 | #include <array> |
| 8 | |||
| 8 | #include "core/crypto/aes_util.h" | 9 | #include "core/crypto/aes_util.h" |
| 9 | #include "core/crypto/encryption_layer.h" | 10 | #include "core/crypto/encryption_layer.h" |
| 10 | #include "core/crypto/key_manager.h" | 11 | #include "core/crypto/key_manager.h" |
| @@ -14,18 +15,20 @@ namespace Core::Crypto { | |||
| 14 | // Sits on top of a VirtualFile and provides CTR-mode AES decription. | 15 | // Sits on top of a VirtualFile and provides CTR-mode AES decription. |
| 15 | class CTREncryptionLayer : public EncryptionLayer { | 16 | class CTREncryptionLayer : public EncryptionLayer { |
| 16 | public: | 17 | public: |
| 18 | using IVData = std::array<u8, 16>; | ||
| 19 | |||
| 17 | CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, std::size_t base_offset); | 20 | CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, std::size_t base_offset); |
| 18 | 21 | ||
| 19 | std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override; | 22 | std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override; |
| 20 | 23 | ||
| 21 | void SetIV(const std::vector<u8>& iv); | 24 | void SetIV(const IVData& iv); |
| 22 | 25 | ||
| 23 | private: | 26 | private: |
| 24 | std::size_t base_offset; | 27 | std::size_t base_offset; |
| 25 | 28 | ||
| 26 | // Must be mutable as operations modify cipher contexts. | 29 | // Must be mutable as operations modify cipher contexts. |
| 27 | mutable AESCipher<Key128> cipher; | 30 | mutable AESCipher<Key128> cipher; |
| 28 | mutable std::vector<u8> iv; | 31 | mutable IVData iv{}; |
| 29 | 32 | ||
| 30 | void UpdateIV(std::size_t offset) const; | 33 | void UpdateIV(std::size_t offset) const; |
| 31 | }; | 34 | }; |
diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 7ed71ac3a..b31a81560 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp | |||
| @@ -346,10 +346,9 @@ FileSys::VirtualFile PartitionDataManager::GetPackage2Raw(Package2Type type) con | |||
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static bool AttemptDecrypt(const std::array<u8, 16>& key, Package2Header& header) { | 348 | static bool AttemptDecrypt(const std::array<u8, 16>& key, Package2Header& header) { |
| 349 | const std::vector<u8> iv(header.header_ctr.begin(), header.header_ctr.end()); | ||
| 350 | Package2Header temp = header; | 349 | Package2Header temp = header; |
| 351 | AESCipher<Key128> cipher(key, Mode::CTR); | 350 | AESCipher<Key128> cipher(key, Mode::CTR); |
| 352 | cipher.SetIV(iv); | 351 | cipher.SetIV(header.header_ctr); |
| 353 | cipher.Transcode(&temp.header_ctr, sizeof(Package2Header) - 0x100, &temp.header_ctr, | 352 | cipher.Transcode(&temp.header_ctr, sizeof(Package2Header) - 0x100, &temp.header_ctr, |
| 354 | Op::Decrypt); | 353 | Op::Decrypt); |
| 355 | if (temp.magic == Common::MakeMagic('P', 'K', '2', '1')) { | 354 | if (temp.magic == Common::MakeMagic('P', 'K', '2', '1')) { |
| @@ -388,7 +387,7 @@ void PartitionDataManager::DecryptPackage2(const std::array<Key128, 0x20>& packa | |||
| 388 | auto c = a->ReadAllBytes(); | 387 | auto c = a->ReadAllBytes(); |
| 389 | 388 | ||
| 390 | AESCipher<Key128> cipher(package2_keys[revision], Mode::CTR); | 389 | AESCipher<Key128> cipher(package2_keys[revision], Mode::CTR); |
| 391 | cipher.SetIV({header.section_ctr[1].begin(), header.section_ctr[1].end()}); | 390 | cipher.SetIV(header.section_ctr[1]); |
| 392 | cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); | 391 | cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); |
| 393 | 392 | ||
| 394 | const auto ini_file = std::make_shared<FileSys::VectorVfsFile>(c); | 393 | const auto ini_file = std::make_shared<FileSys::VectorVfsFile>(c); |
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 473245d5a..5039341c7 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -495,9 +495,10 @@ VirtualFile NCA::Decrypt(const NCASectionHeader& s_header, VirtualFile in, u64 s | |||
| 495 | 495 | ||
| 496 | auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(std::move(in), *key, | 496 | auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(std::move(in), *key, |
| 497 | starting_offset); | 497 | starting_offset); |
| 498 | std::vector<u8> iv(16); | 498 | Core::Crypto::CTREncryptionLayer::IVData iv{}; |
| 499 | for (u8 i = 0; i < 8; ++i) | 499 | for (std::size_t i = 0; i < 8; ++i) { |
| 500 | iv[i] = s_header.raw.section_ctr[0x8 - i - 1]; | 500 | iv[i] = s_header.raw.section_ctr[8 - i - 1]; |
| 501 | } | ||
| 501 | out->SetIV(iv); | 502 | out->SetIV(iv); |
| 502 | return std::static_pointer_cast<VfsFile>(out); | 503 | return std::static_pointer_cast<VfsFile>(out); |
| 503 | } | 504 | } |
diff --git a/src/core/file_sys/nca_patch.cpp b/src/core/file_sys/nca_patch.cpp index 0090cc6c4..fe7375e84 100644 --- a/src/core/file_sys/nca_patch.cpp +++ b/src/core/file_sys/nca_patch.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <array> | ||
| 6 | #include <cstddef> | 7 | #include <cstddef> |
| 7 | #include <cstring> | 8 | #include <cstring> |
| 8 | 9 | ||
| @@ -66,7 +67,7 @@ std::size_t BKTR::Read(u8* data, std::size_t length, std::size_t offset) const { | |||
| 66 | Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(key, Core::Crypto::Mode::CTR); | 67 | Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(key, Core::Crypto::Mode::CTR); |
| 67 | 68 | ||
| 68 | // Calculate AES IV | 69 | // Calculate AES IV |
| 69 | std::vector<u8> iv(16); | 70 | std::array<u8, 16> iv{}; |
| 70 | auto subsection_ctr = subsection.ctr; | 71 | auto subsection_ctr = subsection.ctr; |
| 71 | auto offset_iv = section_offset + base_offset; | 72 | auto offset_iv = section_offset + base_offset; |
| 72 | for (std::size_t i = 0; i < section_ctr.size(); ++i) | 73 | for (std::size_t i = 0; i < section_ctr.size(); ++i) |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index caca80dde..637b310d7 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -24,13 +24,13 @@ BufferQueue::~BufferQueue() = default; | |||
| 24 | void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { | 24 | void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { |
| 25 | LOG_WARNING(Service, "Adding graphics buffer {}", slot); | 25 | LOG_WARNING(Service, "Adding graphics buffer {}", slot); |
| 26 | 26 | ||
| 27 | Buffer buffer{}; | ||
| 28 | buffer.slot = slot; | ||
| 29 | buffer.igbp_buffer = igbp_buffer; | ||
| 30 | buffer.status = Buffer::Status::Free; | ||
| 31 | free_buffers.push_back(slot); | 27 | free_buffers.push_back(slot); |
| 28 | queue.push_back({ | ||
| 29 | .slot = slot, | ||
| 30 | .status = Buffer::Status::Free, | ||
| 31 | .igbp_buffer = igbp_buffer, | ||
| 32 | }); | ||
| 32 | 33 | ||
| 33 | queue.emplace_back(buffer); | ||
| 34 | buffer_wait_event.writable->Signal(); | 34 | buffer_wait_event.writable->Signal(); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| @@ -38,7 +38,7 @@ std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::Dequeue | |||
| 38 | u32 height) { | 38 | u32 height) { |
| 39 | 39 | ||
| 40 | if (free_buffers.empty()) { | 40 | if (free_buffers.empty()) { |
| 41 | return {}; | 41 | return std::nullopt; |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | auto f_itr = free_buffers.begin(); | 44 | auto f_itr = free_buffers.begin(); |
| @@ -69,7 +69,7 @@ std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::Dequeue | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | if (itr == queue.end()) { | 71 | if (itr == queue.end()) { |
| 72 | return {}; | 72 | return std::nullopt; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | itr->status = Buffer::Status::Dequeued; | 75 | itr->status = Buffer::Status::Dequeued; |
| @@ -103,14 +103,15 @@ std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::Ac | |||
| 103 | auto itr = queue.end(); | 103 | auto itr = queue.end(); |
| 104 | // Iterate to find a queued buffer matching the requested slot. | 104 | // Iterate to find a queued buffer matching the requested slot. |
| 105 | while (itr == queue.end() && !queue_sequence.empty()) { | 105 | while (itr == queue.end() && !queue_sequence.empty()) { |
| 106 | u32 slot = queue_sequence.front(); | 106 | const u32 slot = queue_sequence.front(); |
| 107 | itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) { | 107 | itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) { |
| 108 | return buffer.status == Buffer::Status::Queued && buffer.slot == slot; | 108 | return buffer.status == Buffer::Status::Queued && buffer.slot == slot; |
| 109 | }); | 109 | }); |
| 110 | queue_sequence.pop_front(); | 110 | queue_sequence.pop_front(); |
| 111 | } | 111 | } |
| 112 | if (itr == queue.end()) | 112 | if (itr == queue.end()) { |
| 113 | return {}; | 113 | return std::nullopt; |
| 114 | } | ||
| 114 | itr->status = Buffer::Status::Acquired; | 115 | itr->status = Buffer::Status::Acquired; |
| 115 | return *itr; | 116 | return *itr; |
| 116 | } | 117 | } |
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 2c5588933..86d17c6cb 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -704,7 +704,7 @@ struct Memory::Impl { | |||
| 704 | u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; | 704 | u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; |
| 705 | if (page_pointer != nullptr) { | 705 | if (page_pointer != nullptr) { |
| 706 | // NOTE: Avoid adding any extra logic to this fast-path block | 706 | // NOTE: Avoid adding any extra logic to this fast-path block |
| 707 | T volatile* pointer = reinterpret_cast<T volatile*>(&page_pointer[vaddr]); | 707 | auto* pointer = reinterpret_cast<volatile T*>(&page_pointer[vaddr]); |
| 708 | return Common::AtomicCompareAndSwap(pointer, data, expected); | 708 | return Common::AtomicCompareAndSwap(pointer, data, expected); |
| 709 | } | 709 | } |
| 710 | 710 | ||
| @@ -720,9 +720,8 @@ struct Memory::Impl { | |||
| 720 | case Common::PageType::RasterizerCachedMemory: { | 720 | case Common::PageType::RasterizerCachedMemory: { |
| 721 | u8* host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; | 721 | u8* host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; |
| 722 | system.GPU().InvalidateRegion(vaddr, sizeof(T)); | 722 | system.GPU().InvalidateRegion(vaddr, sizeof(T)); |
| 723 | T volatile* pointer = reinterpret_cast<T volatile*>(&host_ptr); | 723 | auto* pointer = reinterpret_cast<volatile T*>(&host_ptr); |
| 724 | return Common::AtomicCompareAndSwap(pointer, data, expected); | 724 | return Common::AtomicCompareAndSwap(pointer, data, expected); |
| 725 | break; | ||
| 726 | } | 725 | } |
| 727 | default: | 726 | default: |
| 728 | UNREACHABLE(); | 727 | UNREACHABLE(); |
| @@ -734,7 +733,7 @@ struct Memory::Impl { | |||
| 734 | u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; | 733 | u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; |
| 735 | if (page_pointer != nullptr) { | 734 | if (page_pointer != nullptr) { |
| 736 | // NOTE: Avoid adding any extra logic to this fast-path block | 735 | // NOTE: Avoid adding any extra logic to this fast-path block |
| 737 | u64 volatile* pointer = reinterpret_cast<u64 volatile*>(&page_pointer[vaddr]); | 736 | auto* pointer = reinterpret_cast<volatile u64*>(&page_pointer[vaddr]); |
| 738 | return Common::AtomicCompareAndSwap(pointer, data, expected); | 737 | return Common::AtomicCompareAndSwap(pointer, data, expected); |
| 739 | } | 738 | } |
| 740 | 739 | ||
| @@ -750,9 +749,8 @@ struct Memory::Impl { | |||
| 750 | case Common::PageType::RasterizerCachedMemory: { | 749 | case Common::PageType::RasterizerCachedMemory: { |
| 751 | u8* host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; | 750 | u8* host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; |
| 752 | system.GPU().InvalidateRegion(vaddr, sizeof(u128)); | 751 | system.GPU().InvalidateRegion(vaddr, sizeof(u128)); |
| 753 | u64 volatile* pointer = reinterpret_cast<u64 volatile*>(&host_ptr); | 752 | auto* pointer = reinterpret_cast<volatile u64*>(&host_ptr); |
| 754 | return Common::AtomicCompareAndSwap(pointer, data, expected); | 753 | return Common::AtomicCompareAndSwap(pointer, data, expected); |
| 755 | break; | ||
| 756 | } | 754 | } |
| 757 | default: | 755 | default: |
| 758 | UNREACHABLE(); | 756 | UNREACHABLE(); |