summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-08-25 11:48:23 -0400
committerGravatar Zach Hilman2018-09-04 14:27:33 -0400
commit5c8aff984e47c0f471e9eafd071031bc49ad8efc (patch)
treeac5ecdfc187f04a677b61f62eea6d6614326e636 /src
parentfile_sys: Add Nintendo Submission Package (NSP) (diff)
downloadyuzu-5c8aff984e47c0f471e9eafd071031bc49ad8efc.tar.gz
yuzu-5c8aff984e47c0f471e9eafd071031bc49ad8efc.tar.xz
yuzu-5c8aff984e47c0f471e9eafd071031bc49ad8efc.zip
card_image: Parse XCI secure partition with NSP
Eliminated duplicate code and adds support for Rev1+ carts
Diffstat (limited to 'src')
-rw-r--r--src/core/crypto/key_manager.h2
-rw-r--r--src/core/file_sys/card_image.cpp33
-rw-r--r--src/core/file_sys/card_image.h7
-rw-r--r--src/core/loader/xci.cpp7
4 files changed, 38 insertions, 11 deletions
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h
index bf51bf31f..ce67913bb 100644
--- a/src/core/crypto/key_manager.h
+++ b/src/core/crypto/key_manager.h
@@ -17,6 +17,8 @@ enum class ResultStatus : u16;
17 17
18namespace Core::Crypto { 18namespace Core::Crypto {
19 19
20constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180;
21
20using Key128 = std::array<u8, 0x10>; 22using Key128 = std::array<u8, 0x10>;
21using Key256 = std::array<u8, 0x20>; 23using Key256 = std::array<u8, 0x20>;
22using SHA256Hash = std::array<u8, 0x20>; 24using SHA256Hash = std::array<u8, 0x20>;
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp
index ce4423fa6..d0f1afac0 100644
--- a/src/core/file_sys/card_image.cpp
+++ b/src/core/file_sys/card_image.cpp
@@ -10,6 +10,7 @@
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11#include "core/file_sys/card_image.h" 11#include "core/file_sys/card_image.h"
12#include "core/file_sys/content_archive.h" 12#include "core/file_sys/content_archive.h"
13#include "core/file_sys/nca_metadata.h"
13#include "core/file_sys/partition_filesystem.h" 14#include "core/file_sys/partition_filesystem.h"
14#include "core/file_sys/vfs_offset.h" 15#include "core/file_sys/vfs_offset.h"
15#include "core/loader/loader.h" 16#include "core/loader/loader.h"
@@ -44,15 +45,19 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) {
44 partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw); 45 partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw);
45 } 46 }
46 47
47 program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA; 48 secure_partition = std::make_shared<NSP>(
49 main_hfs.GetFile(partition_names[static_cast<size_t>(XCIPartition::Secure)]));
48 50
49 auto result = AddNCAFromPartition(XCIPartition::Secure); 51 const auto secure_ncas = secure_partition->GetNCAsCollapsed();
50 if (result != Loader::ResultStatus::Success) { 52 std::copy(secure_ncas.begin(), secure_ncas.end(), std::back_inserter(ncas));
51 status = result; 53
52 return; 54 program_nca_status = Loader::ResultStatus::ErrorXCIMissingProgramNCA;
53 } 55 program =
56 secure_partition->GetNCA(secure_partition->GetProgramTitleID(), ContentRecordType::Program);
57 if (program != nullptr)
58 program_nca_status = program->GetStatus();
54 59
55 result = AddNCAFromPartition(XCIPartition::Update); 60 auto result = AddNCAFromPartition(XCIPartition::Update);
56 if (result != Loader::ResultStatus::Success) { 61 if (result != Loader::ResultStatus::Success) {
57 status = result; 62 status = result;
58 return; 63 return;
@@ -89,6 +94,10 @@ VirtualDir XCI::GetPartition(XCIPartition partition) const {
89 return partitions[static_cast<size_t>(partition)]; 94 return partitions[static_cast<size_t>(partition)];
90} 95}
91 96
97std::shared_ptr<NSP> XCI::GetSecurePartitionNSP() const {
98 return secure_partition;
99}
100
92VirtualDir XCI::GetSecurePartition() const { 101VirtualDir XCI::GetSecurePartition() const {
93 return GetPartition(XCIPartition::Secure); 102 return GetPartition(XCIPartition::Secure);
94} 103}
@@ -105,6 +114,16 @@ VirtualDir XCI::GetLogoPartition() const {
105 return GetPartition(XCIPartition::Logo); 114 return GetPartition(XCIPartition::Logo);
106} 115}
107 116
117std::shared_ptr<NCA> XCI::GetProgramNCA() const {
118 return program;
119}
120
121VirtualFile XCI::GetProgramNCAFile() const {
122 if (GetProgramNCA() == nullptr)
123 return nullptr;
124 return GetProgramNCA()->GetBaseFile();
125}
126
108const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const { 127const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const {
109 return ncas; 128 return ncas;
110} 129}
diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h
index 4f104d18a..b73f1d900 100644
--- a/src/core/file_sys/card_image.h
+++ b/src/core/file_sys/card_image.h
@@ -10,6 +10,8 @@
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/swap.h" 11#include "common/swap.h"
12#include "core/file_sys/vfs.h" 12#include "core/file_sys/vfs.h"
13#include "core/loader/loader.h"
14#include "submission_package.h"
13 15
14namespace Loader { 16namespace Loader {
15enum class ResultStatus : u16; 17enum class ResultStatus : u16;
@@ -71,11 +73,14 @@ public:
71 u8 GetFormatVersion() const; 73 u8 GetFormatVersion() const;
72 74
73 VirtualDir GetPartition(XCIPartition partition) const; 75 VirtualDir GetPartition(XCIPartition partition) const;
76 std::shared_ptr<NSP> GetSecurePartitionNSP() const;
74 VirtualDir GetSecurePartition() const; 77 VirtualDir GetSecurePartition() const;
75 VirtualDir GetNormalPartition() const; 78 VirtualDir GetNormalPartition() const;
76 VirtualDir GetUpdatePartition() const; 79 VirtualDir GetUpdatePartition() const;
77 VirtualDir GetLogoPartition() const; 80 VirtualDir GetLogoPartition() const;
78 81
82 std::shared_ptr<NCA> GetProgramNCA() const;
83 VirtualFile GetProgramNCAFile() const;
79 const std::vector<std::shared_ptr<NCA>>& GetNCAs() const; 84 const std::vector<std::shared_ptr<NCA>>& GetNCAs() const;
80 std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const; 85 std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const;
81 VirtualFile GetNCAFileByType(NCAContentType type) const; 86 VirtualFile GetNCAFileByType(NCAContentType type) const;
@@ -101,6 +106,8 @@ private:
101 Loader::ResultStatus program_nca_status; 106 Loader::ResultStatus program_nca_status;
102 107
103 std::vector<VirtualDir> partitions; 108 std::vector<VirtualDir> partitions;
109 std::shared_ptr<NSP> secure_partition;
110 std::shared_ptr<NCA> program;
104 std::vector<std::shared_ptr<NCA>> ncas; 111 std::vector<std::shared_ptr<NCA>> ncas;
105}; 112};
106} // namespace FileSys 113} // namespace FileSys
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index 9dc4d1f35..75b998faa 100644
--- a/src/core/loader/xci.cpp
+++ b/src/core/loader/xci.cpp
@@ -17,8 +17,7 @@ namespace Loader {
17 17
18AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) 18AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
19 : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)), 19 : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
20 nca_loader(std::make_unique<AppLoader_NCA>( 20 nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
21 xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {
22 if (xci->GetStatus() != ResultStatus::Success) 21 if (xci->GetStatus() != ResultStatus::Success)
23 return; 22 return;
24 const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); 23 const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
@@ -64,11 +63,11 @@ ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) {
64 if (xci->GetProgramNCAStatus() != ResultStatus::Success) 63 if (xci->GetProgramNCAStatus() != ResultStatus::Success)
65 return xci->GetProgramNCAStatus(); 64 return xci->GetProgramNCAStatus();
66 65
67 const auto nca = xci->GetNCAFileByType(FileSys::NCAContentType::Program); 66 const auto nca = xci->GetProgramNCA();
68 if (nca == nullptr && !Core::Crypto::KeyManager::KeyFileExists(false)) 67 if (nca == nullptr && !Core::Crypto::KeyManager::KeyFileExists(false))
69 return ResultStatus::ErrorMissingProductionKeyFile; 68 return ResultStatus::ErrorMissingProductionKeyFile;
70 69
71 auto result = nca_loader->Load(process); 70 const auto result = nca_loader->Load(process);
72 if (result != ResultStatus::Success) 71 if (result != ResultStatus::Success)
73 return result; 72 return result;
74 73