summaryrefslogtreecommitdiff
path: root/src/core/crypto/key_manager.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2018-10-13 08:12:00 -0400
committerGravatar Lioncash2018-10-13 08:24:18 -0400
commitef5639bfbbeb7d83bd66e3faf3e88e4aa1e05a6e (patch)
tree80c8f1dbccfb4dd33978e317d097befa8886ab74 /src/core/crypto/key_manager.cpp
parentkey_manager: Remove unnecessary seek in DeriveSDSeed() (diff)
downloadyuzu-ef5639bfbbeb7d83bd66e3faf3e88e4aa1e05a6e.tar.gz
yuzu-ef5639bfbbeb7d83bd66e3faf3e88e4aa1e05a6e.tar.xz
yuzu-ef5639bfbbeb7d83bd66e3faf3e88e4aa1e05a6e.zip
key_manager: Don't assume file seeks and reads will always succeed
Given the filesystem should always be assumed to be volatile, we should check and bail out if a seek operation isn't successful. This'll prevent potentially writing/returning garbage data from the function in rare cases. This also allows removing a check to see if an offset is within the bounds of a file before perfoming a seek operation. If a seek is attempted beyond the end of a file, it will fail, so this essentially combines two checks into one in one place.
Diffstat (limited to 'src/core/crypto/key_manager.cpp')
-rw-r--r--src/core/crypto/key_manager.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp
index 4ade67d23..14d53bef9 100644
--- a/src/core/crypto/key_manager.cpp
+++ b/src/core/crypto/key_manager.cpp
@@ -147,30 +147,38 @@ boost::optional<Key128> DeriveSDSeed() {
147 "rb+"); 147 "rb+");
148 if (!save_43.IsOpen()) 148 if (!save_43.IsOpen())
149 return boost::none; 149 return boost::none;
150
150 const FileUtil::IOFile sd_private( 151 const FileUtil::IOFile sd_private(
151 FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+"); 152 FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+");
152 if (!sd_private.IsOpen()) 153 if (!sd_private.IsOpen())
153 return boost::none; 154 return boost::none;
154 155
155 std::array<u8, 0x10> private_seed{}; 156 std::array<u8, 0x10> private_seed{};
156 if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != 0x10) 157 if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) {
157 return boost::none; 158 return boost::none;
159 }
158 160
159 std::array<u8, 0x10> buffer{}; 161 std::array<u8, 0x10> buffer{};
160 std::size_t offset = 0; 162 std::size_t offset = 0;
161 for (; offset + 0x10 < save_43.GetSize(); ++offset) { 163 for (; offset + 0x10 < save_43.GetSize(); ++offset) {
162 save_43.Seek(offset, SEEK_SET); 164 if (!save_43.Seek(offset, SEEK_SET)) {
165 return boost::none;
166 }
167
163 save_43.ReadBytes(buffer.data(), buffer.size()); 168 save_43.ReadBytes(buffer.data(), buffer.size());
164 if (buffer == private_seed) 169 if (buffer == private_seed) {
165 break; 170 break;
171 }
166 } 172 }
167 173
168 if (offset + 0x10 >= save_43.GetSize()) 174 if (!save_43.Seek(offset + 0x10, SEEK_SET)) {
169 return boost::none; 175 return boost::none;
176 }
170 177
171 Key128 seed{}; 178 Key128 seed{};
172 save_43.Seek(offset + 0x10, SEEK_SET); 179 if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) {
173 save_43.ReadBytes(seed.data(), seed.size()); 180 return boost::none;
181 }
174 return seed; 182 return seed;
175} 183}
176 184
@@ -233,7 +241,9 @@ std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save) {
233 return {}; 241 return {};
234 242
235 std::vector<u8> buffer(ticket_save.GetSize()); 243 std::vector<u8> buffer(ticket_save.GetSize());
236 ticket_save.ReadBytes(buffer.data(), buffer.size()); 244 if (ticket_save.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) {
245 return {};
246 }
237 247
238 std::vector<TicketRaw> out; 248 std::vector<TicketRaw> out;
239 u32 magic{}; 249 u32 magic{};