From b70e2bce58a8f7e5d77b8027b337e99e35a56364 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 4 Sep 2018 12:27:48 -0400 Subject: [PATCH] HW/AES: add common key loading and selecting --- src/core/hw/aes/key.cpp | 35 +++++++++++++++++++++++++---------- src/core/hw/aes/key.h | 5 +++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/core/hw/aes/key.cpp b/src/core/hw/aes/key.cpp index 8d20ee781..f7493015c 100644 --- a/src/core/hw/aes/key.cpp +++ b/src/core/hw/aes/key.cpp @@ -25,26 +25,26 @@ struct KeySlot { boost::optional y; boost::optional normal; - void SetKeyX(const AESKey& key) { + void SetKeyX(boost::optional key) { x = key; - if (y && generator_constant) { - GenerateNormalKey(); - } + GenerateNormalKey(); } - void SetKeyY(const AESKey& key) { + void SetKeyY(boost::optional key) { y = key; - if (x && generator_constant) { - GenerateNormalKey(); - } + GenerateNormalKey(); } - void SetNormalKey(const AESKey& key) { + void SetNormalKey(boost::optional key) { normal = key; } void GenerateNormalKey() { - normal = Lrot128(Add128(Xor128(Lrot128(*x, 2), *y), *generator_constant), 87); + if (x && y && generator_constant) { + normal = Lrot128(Add128(Xor128(Lrot128(*x, 2), *y), *generator_constant), 87); + } else { + normal = boost::none; + } } void Clear() { @@ -55,6 +55,7 @@ struct KeySlot { }; std::array key_slots; +std::array, 6> common_key_y_slots; AESKey HexToKey(const std::string& hex) { if (hex.size() < 32) { @@ -102,6 +103,16 @@ void LoadPresetKeys() { continue; } + std::size_t common_key_index; + if (std::sscanf(name.c_str(), "common%zd", &common_key_index) == 1) { + if (common_key_index >= common_key_y_slots.size()) { + LOG_ERROR(HW_AES, "Invalid common key index {}", common_key_index); + } else { + common_key_y_slots[common_key_index] = key; + } + continue; + } + std::size_t slot_id; char key_type; if (std::sscanf(name.c_str(), "slot0x%zXKey%c", &slot_id, &key_type) != 2) { @@ -165,5 +176,9 @@ AESKey GetNormalKey(std::size_t slot_id) { return key_slots.at(slot_id).normal.value_or(AESKey{}); } +void SelectCommonKeyIndex(u8 index) { + key_slots[KeySlotID::TicketCommonKey].SetKeyY(common_key_y_slots.at(index)); +} + } // namespace AES } // namespace HW diff --git a/src/core/hw/aes/key.h b/src/core/hw/aes/key.h index b2c7311af..3d6664fd2 100644 --- a/src/core/hw/aes/key.h +++ b/src/core/hw/aes/key.h @@ -28,6 +28,9 @@ enum KeySlotID : std::size_t { // AES keyslot used for APT:Wrap/Unwrap functions APTWrap = 0x31, + // AES keyslot used for decrypting ticket title key + TicketCommonKey = 0x3D, + MaxKeySlotID = 0x40, }; @@ -45,5 +48,7 @@ void SetNormalKey(std::size_t slot_id, const AESKey& key); bool IsNormalKeyAvailable(std::size_t slot_id); AESKey GetNormalKey(std::size_t slot_id); +void SelectCommonKeyIndex(u8 index); + } // namespace AES } // namespace HW