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.
This commit is contained in:
noah the goodra 2017-03-08 14:30:21 -06:00
parent d2bb0a6f2d
commit a1e1fc8ac0
2 changed files with 76 additions and 15 deletions

View File

@ -46,3 +46,4 @@
// Sys files // Sys files
#define SHARED_FONT "shared_font.bin" #define SHARED_FONT "shared_font.bin"
#define AES_KEYS "aes_keys.txt" #define AES_KEYS "aes_keys.txt"
#define AES_KEYS_DB "aeskeydb.bin"

View File

@ -76,7 +76,30 @@ AESKey HexToKey(const std::string& hex) {
return key; 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; const std::string filepath = FileUtil::GetUserPath(D_SYSDATA_IDX) + AES_KEYS;
FileUtil::CreateFullPath(filepath); // Create path if not already created FileUtil::CreateFullPath(filepath); // Create path if not already created
std::ifstream file; std::ifstream file;
@ -121,21 +144,58 @@ void LoadPresetKeys() {
continue; continue;
} }
switch (key_type) { SetKeySlot(key, slot_id, 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;
} }
} }
/**
* 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<char, 10> 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;
// Create path if not already created
FileUtil::CreateFullPath(filepath);
auto file = FileUtil::IOFile(filepath, "r");
if (!file) {
return;
}
AesKeyInfo key_info;
while (file.IsGood()) {
file.ReadArray(&key_info, 1);
if (key_info.slot >= MaxKeySlotID) {
LOG_ERROR(HW_AES, "Out of range slot ID 0x%zX", key_info.slot);
continue;
}
if (key_info.is_encrypted) {
LOG_ERROR(HW_AES, "Key with slot ID 0x%zX is encrypted", key_info.slot);
continue;
}
if (key_info.id[0] != 0x00) {
LOG_WARNING(HW_AES, "Key with slot ID 0x%zX is a special key, ignoring", key_info.slot);
continue;
}
SetKeySlot(key_info.key, key_info.slot, key_info.type);
}
}
void LoadPresetKeys() {
LoadKeysFromText();
LoadKeysFromDB();
} }
} // namespace } // namespace