From 93dd933995792e5ad14261b240f25d527996ac35 Mon Sep 17 00:00:00 2001 From: noah the goodra Date: Wed, 8 Mar 2017 14:30:21 -0600 Subject: [PATCH] added support for loading aeskeydb.bin to the aes code This is an ammendment to pull request #2569 to allow it to both load from the text file and load from aeskeydb.bin. It contains if statements within the switch cases to check if the key is already initialized --- src/common/common_paths.h | 1 + src/core/hw/aes/key.cpp | 75 +++++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/common/common_paths.h b/src/common/common_paths.h index d5b510cdb..8ce3769e1 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -46,3 +46,4 @@ // Sys files #define SHARED_FONT "shared_font.bin" #define AES_KEYS "aes_keys.txt" +#define AES_KEYS_DB "aeskeydb.bin" diff --git a/src/core/hw/aes/key.cpp b/src/core/hw/aes/key.cpp index 4e8a8a59a..c644c4415 100644 --- a/src/core/hw/aes/key.cpp +++ b/src/core/hw/aes/key.cpp @@ -76,7 +76,29 @@ AESKey HexToKey(const std::string& hex) { return key; } -void LoadPresetKeys() { +void SetKeySlot(const AESKey& key, size_t slot_id, char key_type) { + switch (key_type) { + case 'X': + if (!key_slots.at(slot_id).x.is_initialized()) { + SetKeyX(slot_id, key); + } + break; + case 'Y': + if (!key_slots.at(slot_id).y.is_initialized()) { + SetKeyY(slot_id, key); + } + break; + case 'N': + if (!key_slots.at(slot_id).normal.is_initialized()) { + SetNormalKey(slot_id, key); + } + break; + default: + LOG_ERROR(HW_AES, "Invalid key type %c", key_type); + break; + } +} +void LoadKeysFromText() { const std::string filepath = FileUtil::GetUserPath(D_SYSDATA_IDX) + AES_KEYS; FileUtil::CreateFullPath(filepath); // Create path if not already created std::ifstream file; @@ -121,22 +143,45 @@ void LoadPresetKeys() { continue; } - switch (key_type) { - case 'X': - key_slots.at(slot_id).SetKeyX(key); - break; - case 'Y': - key_slots.at(slot_id).SetKeyY(key); - break; - case 'N': - key_slots.at(slot_id).SetNormalKey(key); - break; - default: - LOG_ERROR(HW_AES, "Invalid key type %c", key_type); - break; - } + SetKeySlot(key, slot_id, key_type); } } +/* + * This is used to load the aeskeydb.bin file from the sysdata directory. + * This file comes from Decrypt9 and can be built using the Build Key Database option. + * It requires bin files containing the key data following the format slot0x??key?.bin. + * The wiki describes that this database can be encrypted or decrypted however as of right now only + * the decrypted format is supported. + */ +void LoadKeysFromDB() { + // aeskeydb.bin struct taken from https://git.io/vyzHF + struct AesKeyInfo { + u8 slot; // keyslot, 0x00...0x3F + char type; // type 'X' / 'Y' / 'N' for normalKey + std::array id; // key ID for special keys, all zero for standard keys + u8 reserved[2]; // reserved space + u8 is_devkitkey; // 0 for retail units / 1 for DevKit units + u8 is_encrypted; // 0 if not / anything else if it is + AESKey key; + }; + + const std::string filepath = FileUtil::GetUserPath(D_SYSDATA_IDX) + AES_KEYS_DB; + FileUtil::CreateFullPath(filepath); // Create path if not already created + std::ifstream file; + OpenFStream(file, filepath, std::ios_base::in); + if (!file) { + return; + } + AesKeyInfo key_info; + while (!file.eof()) { + file.read((char*)&key_info, sizeof(key_info)); + SetKeySlot(key_info.key, key_info.slot, key_info.type); + } +} +void LoadPresetKeys() { + LoadKeysFromText(); + LoadKeysFromDB(); +} } // namespace