summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-08-16 17:01:32 -0400
committerGravatar Zach Hilman2018-08-23 11:52:44 -0400
commitc4845df3d4b9fc3fc19dd936af87090ffb3fbdf2 (patch)
tree7bca82326831ee20fc73a4fb2d609825cce8fad3 /src
parentaes_util: Make XTSTranscode stricter about sizes (diff)
downloadyuzu-c4845df3d4b9fc3fc19dd936af87090ffb3fbdf2.tar.gz
yuzu-c4845df3d4b9fc3fc19dd936af87090ffb3fbdf2.tar.xz
yuzu-c4845df3d4b9fc3fc19dd936af87090ffb3fbdf2.zip
xts_encryption_layer: Implement XTSEncryptionLayer
Diffstat (limited to 'src')
-rw-r--r--src/core/crypto/xts_encryption_layer.cpp54
-rw-r--r--src/core/crypto/xts_encryption_layer.h26
-rw-r--r--src/core/file_sys/content_archive.cpp2
3 files changed, 81 insertions, 1 deletions
diff --git a/src/core/crypto/xts_encryption_layer.cpp b/src/core/crypto/xts_encryption_layer.cpp
new file mode 100644
index 000000000..431099580
--- /dev/null
+++ b/src/core/crypto/xts_encryption_layer.cpp
@@ -0,0 +1,54 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstring>
6#include "common/assert.h"
7#include "core/crypto/xts_encryption_layer.h"
8
9namespace Core::Crypto {
10
11XTSEncryptionLayer::XTSEncryptionLayer(FileSys::VirtualFile base_, Key256 key_)
12 : EncryptionLayer(std::move(base_)), cipher(key_, Mode::XTS) {}
13
14size_t XTSEncryptionLayer::Read(u8* data, size_t length, size_t offset) const {
15 if (length == 0)
16 return 0;
17
18 const auto sector_offset = offset & 0x3FFF;
19 if (sector_offset == 0) {
20 if (length % 0x4000 == 0) {
21 std::vector<u8> raw = base->ReadBytes(length, offset);
22 cipher.XTSTranscode(raw.data(), raw.size(), data, offset / 0x4000, 0x4000, Op::Decrypt);
23 return raw.size();
24 }
25 if (length > 0x4000) {
26 const auto rem = length % 0x4000;
27 const auto read = length - rem;
28 return Read(data, read, offset) + Read(data + read, rem, offset + read);
29 }
30 std::vector<u8> buffer = base->ReadBytes(0x4000, offset);
31 if (buffer.size() < 0x4000)
32 buffer.resize(0x4000);
33 cipher.XTSTranscode(buffer.data(), buffer.size(), buffer.data(), offset / 0x4000, 0x4000,
34 Op::Decrypt);
35 std::memcpy(data, buffer.data(), std::min(buffer.size(), length));
36 return std::min(buffer.size(), length);
37 }
38
39 // offset does not fall on block boundary (0x4000)
40 std::vector<u8> block = base->ReadBytes(0x4000, offset - sector_offset);
41 if (block.size() < 0x4000)
42 block.resize(0x4000);
43 cipher.XTSTranscode(block.data(), block.size(), block.data(), (offset - sector_offset) / 0x4000,
44 0x4000, Op::Decrypt);
45 const size_t read = 0x4000 - sector_offset;
46
47 if (length + sector_offset < 0x4000) {
48 std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read));
49 return std::min<u64>(length, read);
50 }
51 std::memcpy(data, block.data() + sector_offset, read);
52 return read + Read(data + read, length - read, offset + read);
53}
54} // namespace Core::Crypto
diff --git a/src/core/crypto/xts_encryption_layer.h b/src/core/crypto/xts_encryption_layer.h
new file mode 100644
index 000000000..1e1acaf4a
--- /dev/null
+++ b/src/core/crypto/xts_encryption_layer.h
@@ -0,0 +1,26 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <vector>
8#include "core/crypto/aes_util.h"
9#include "core/crypto/encryption_layer.h"
10#include "core/crypto/key_manager.h"
11
12namespace Core::Crypto {
13
14// Sits on top of a VirtualFile and provides XTS-mode AES decription.
15class XTSEncryptionLayer : public EncryptionLayer {
16public:
17 XTSEncryptionLayer(FileSys::VirtualFile base, Key256 key);
18
19 size_t Read(u8* data, size_t length, size_t offset) const override;
20
21private:
22 // Must be mutable as operations modify cipher contexts.
23 mutable AESCipher<Key256> cipher;
24};
25
26} // namespace Core::Crypto
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index 47afcad9b..008e11d8c 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -178,7 +178,7 @@ VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting
178 return std::static_pointer_cast<VfsFile>(out); 178 return std::static_pointer_cast<VfsFile>(out);
179 } 179 }
180 case NCASectionCryptoType::XTS: 180 case NCASectionCryptoType::XTS:
181 // TODO(DarkLordZach): Implement XTSEncryptionLayer. 181 // TODO(DarkLordZach): Find a test case for XTS-encrypted NCAs
182 default: 182 default:
183 LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}", 183 LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}",
184 static_cast<u8>(s_header.raw.header.crypto_type)); 184 static_cast<u8>(s_header.raw.header.crypto_type));