summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/crypto/aes_util.cpp21
-rw-r--r--src/core/crypto/aes_util.h9
-rw-r--r--src/core/crypto/ctr_encryption_layer.cpp9
-rw-r--r--src/core/crypto/ctr_encryption_layer.h9
-rw-r--r--src/core/crypto/partition_data_manager.cpp5
-rw-r--r--src/core/file_sys/content_archive.cpp7
-rw-r--r--src/core/file_sys/nca_patch.cpp3
7 files changed, 36 insertions, 27 deletions
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
11namespace Core::Crypto { 12namespace Core::Crypto {
12namespace { 13namespace {
13std::vector<u8> CalculateNintendoTweak(std::size_t sector_id) { 14using NintendoTweak = std::array<u8, 16>;
14 std::vector<u8> out(0x10); 15
16NintendoTweak 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
66template <typename Key, std::size_t KeySize> 69template <typename Key, std::size_t KeySize>
67void 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
73template <typename Key, std::size_t KeySize>
74void AESCipher<Key, KeySize>::Transcode(const u8* src, std::size_t size, u8* dest, Op op) const { 70void 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
123template <typename Key, std::size_t KeySize>
124void 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
127template class AESCipher<Key128>; 130template class AESCipher<Key128>;
128template class AESCipher<Key256>; 131template 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
33public: 32public:
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
61private: 62private:
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
11CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, 12CTREncryptionLayer::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
16std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t offset) const { 16std::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
42void CTREncryptionLayer::SetIV(const std::vector<u8>& iv_) { 42void 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
47void CTREncryptionLayer::UpdateIV(std::size_t offset) const { 46void 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.
15class CTREncryptionLayer : public EncryptionLayer { 16class CTREncryptionLayer : public EncryptionLayer {
16public: 17public:
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
23private: 26private:
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
348static bool AttemptDecrypt(const std::array<u8, 16>& key, Package2Header& header) { 348static 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)