From bb3a8a888fd5f2da6e6f4b749c480ec31dd497a3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 16 May 2020 03:29:50 -0700 Subject: [PATCH] exo2: fix a number of bugs, add temp debug-log code --- .../program/source/boot/secmon_boot_setup.cpp | 2 +- .../program/source/secmon_key_storage.cpp | 4 +- exosphere2/program/source/secmon_map.cpp | 2 +- .../program/source/smc/secmon_smc_aes.cpp | 2 +- .../program/source/smc/secmon_smc_handler.cpp | 43 +++++++++++++++++++ 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/exosphere2/program/source/boot/secmon_boot_setup.cpp b/exosphere2/program/source/boot/secmon_boot_setup.cpp index d0daa30d9..eacfd9940 100644 --- a/exosphere2/program/source/boot/secmon_boot_setup.cpp +++ b/exosphere2/program/source/boot/secmon_boot_setup.cpp @@ -166,7 +166,7 @@ namespace ams::secmon::boot { se::DecryptAes128(work_block, se::AesBlockSize, slot, is_prod ? MasterKeyVectorsProd[i] : MasterKeyVectorsDev[i], se::AesBlockSize); /* Set the old master key. */ - SetMasterKey(generation - 1, work_block, se::AesBlockSize); + SetMasterKey(i - 1, work_block, se::AesBlockSize); /* Set the old master key into a temporary keyslot. */ se::SetAesKey(pkg1::AesKeySlot_Temporary, work_block, se::AesBlockSize); diff --git a/exosphere2/program/source/secmon_key_storage.cpp b/exosphere2/program/source/secmon_key_storage.cpp index 8e823deec..419b82cdb 100644 --- a/exosphere2/program/source/secmon_key_storage.cpp +++ b/exosphere2/program/source/secmon_key_storage.cpp @@ -86,7 +86,7 @@ namespace ams::secmon { } void LoadMasterKey(int slot, int generation) { - const int index = std::min(0, generation - pkg1::KeyGeneration_Min); + const int index = std::max(0, generation - pkg1::KeyGeneration_Min); se::SetEncryptedAesKey128(slot, pkg1::AesKeySlot_RandomForKeyStorageWrap, GetMasterKeyStorage(index), se::AesBlockSize); } @@ -96,7 +96,7 @@ namespace ams::secmon { } void LoadDeviceMasterKey(int slot, int generation) { - const int index = std::min(0, generation - pkg1::KeyGeneration_4_0_0); + const int index = std::max(0, generation - pkg1::KeyGeneration_4_0_0); se::SetEncryptedAesKey128(slot, pkg1::AesKeySlot_RandomForKeyStorageWrap, GetDeviceMasterKeyStorage(index), se::AesBlockSize); } diff --git a/exosphere2/program/source/secmon_map.cpp b/exosphere2/program/source/secmon_map.cpp index f41d73ad1..f8e5d9b1d 100644 --- a/exosphere2/program/source/secmon_map.cpp +++ b/exosphere2/program/source/secmon_map.cpp @@ -101,7 +101,7 @@ namespace ams::secmon { } uintptr_t MapSmcUserPage(uintptr_t address) { - if (g_smc_user_page_physical_address != 0) { + if (g_smc_user_page_physical_address == 0) { if (!(MemoryRegionDram.GetAddress() <= address && address <= MemoryRegionDramHigh.GetEndAddress() - MemoryRegionVirtualSmcUserPage.GetSize())) { return 0; } diff --git a/exosphere2/program/source/smc/secmon_smc_aes.cpp b/exosphere2/program/source/smc/secmon_smc_aes.cpp index b007c8b12..7d1796838 100644 --- a/exosphere2/program/source/smc/secmon_smc_aes.cpp +++ b/exosphere2/program/source/smc/secmon_smc_aes.cpp @@ -26,7 +26,7 @@ namespace ams::secmon::smc { namespace { constexpr inline auto AesKeySize = se::AesBlockSize; - constexpr inline size_t CmacSizeMax = 4_KB; + constexpr inline size_t CmacSizeMax = 1_KB; enum SealKey { SealKey_LoadAesKey = 0, diff --git a/exosphere2/program/source/smc/secmon_smc_handler.cpp b/exosphere2/program/source/smc/secmon_smc_handler.cpp index 9d9b92ea6..4a27bf6d8 100644 --- a/exosphere2/program/source/smc/secmon_smc_handler.cpp +++ b/exosphere2/program/source/smc/secmon_smc_handler.cpp @@ -231,9 +231,48 @@ namespace ams::secmon::smc { return info.handler(args); } + constinit std::atomic g_logged = 0; + + constexpr int LogMin = 0x100; + constexpr int LogMax = 0x120; + + constexpr size_t LogBufSize = 0x5000; + + void DebugLog(SmcArguments &args) { + const int current = g_logged.fetch_add(1); + + if (current == 0) { + std::memset(MemoryRegionVirtualDebug.GetPointer(), 0xCC, LogBufSize); + } + + if (current < LogMin) { + return; + } + + + const int ind = current - LogMin; + const int ofs = (ind * sizeof(args)) % LogBufSize; + + for (size_t i = 0; i < sizeof(args) / sizeof(u32); ++i) { + ((volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + ofs))[i] = reinterpret_cast(std::addressof(args))[i]; + } + + if (current >= LogMax) { + *(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x50) = 0x02; + *(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x00) = 0x10; + + util::WaitMicroSeconds(1000); + } + + } + } void HandleSmc(int type, SmcArguments &args) { + if (type == HandlerType_User) { + DebugLog(args); + } + /* Get the table. */ const auto &table = GetHandlerTable(static_cast(type), args.r[0]); @@ -243,6 +282,10 @@ namespace ams::secmon::smc { /* Set the invocation result. */ args.r[0] = static_cast(InvokeSmcHandler(info, args)); + if (type == HandlerType_User) { + DebugLog(args); + } + /* TODO: For debugging. Remove this when exo2 is complete. */ #if 1 if (args.r[0] == static_cast(SmcResult::NotImplemented)) {