diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index efb1916621..bddb4f04b0 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -336,6 +336,8 @@ add_library(core IOS/Device.h IOS/DeviceStub.cpp IOS/DeviceStub.h + IOS/Crypto/AesDevice.cpp + IOS/Crypto/AesDevice.h IOS/Crypto/Sha.cpp IOS/Crypto/Sha.h IOS/DI/DI.cpp diff --git a/Source/Core/Core/IOS/Crypto/AesDevice.cpp b/Source/Core/Core/IOS/Crypto/AesDevice.cpp new file mode 100644 index 0000000000..04614a37ca --- /dev/null +++ b/Source/Core/Core/IOS/Crypto/AesDevice.cpp @@ -0,0 +1,89 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "Core/IOS/Crypto/AesDevice.h" + +#include +#include +#include +#include +#include +#include + +#include "Common/Assert.h" +#include "Common/ChunkFile.h" +#include "Common/CommonTypes.h" +#include "Common/Crypto/AES.h" +#include "Core/HW/MMIO.h" +#include "Core/HW/Memmap.h" +#include "Core/System.h" + +namespace IOS::HLE +{ +AesDevice::AesDevice(EmulationKernel& ios, const std::string& device_name) + : EmulationDevice(ios, device_name) +{ +} + +std::optional AesDevice::Open(const OpenRequest& request) +{ + return Device::Open(request); +} + +std::optional AesDevice::IOCtlV(const IOCtlVRequest& request) +{ + auto& system = GetSystem(); + auto& memory = system.GetMemory(); + HLE::ReturnCode return_code = IPC_EINVAL; + AesIoctlv command = static_cast(request.request); + + switch (command) + { + case AesIoctlv::Copy: + { + if (!request.HasNumberOfValidVectors(1, 1)) + break; + + std::vector input = std::vector(request.in_vectors[0].size); + memory.CopyFromEmu(input.data(), request.in_vectors[0].address, input.size()); + memory.CopyToEmu(request.io_vectors[0].address, input.data(), input.size()); + return_code = ReturnCode::IPC_SUCCESS; + break; + } + case AesIoctlv::Decrypt: + case AesIoctlv::Encrypt: + { + if (!request.HasNumberOfValidVectors(2, 2)) + break; + + if (request.in_vectors[1].size != 0x10 || (request.in_vectors[1].address & 3) != 0 || + request.io_vectors[1].size != 0x10 || (request.io_vectors[1].address & 3) != 0) + { + break; + } + + std::vector input = std::vector(request.in_vectors[0].size); + std::vector output = std::vector(request.io_vectors[0].size); + std::array key = {0}; + std::array iv = {0}; + memory.CopyFromEmu(input.data(), request.in_vectors[0].address, input.size()); + memory.CopyFromEmu(key.data(), request.in_vectors[1].address, key.size()); + memory.CopyFromEmu(iv.data(), request.io_vectors[1].address, iv.size()); + + auto context = command == AesIoctlv::Encrypt ? Common::AES::CreateContextEncrypt(key.data()) : + Common::AES::CreateContextDecrypt(key.data()); + + context->Crypt(iv.data(), iv.data(), input.data(), output.data(), + std::min(output.size(), input.size())); + + memory.CopyToEmu(request.io_vectors[0].address, output.data(), output.size()); + memory.CopyToEmu(request.io_vectors[1].address, iv.data(), iv.size()); + return_code = ReturnCode::IPC_SUCCESS; + break; + } + } + + return IPCReply(return_code); +} + +} // namespace IOS::HLE diff --git a/Source/Core/Core/IOS/Crypto/AesDevice.h b/Source/Core/Core/IOS/Crypto/AesDevice.h new file mode 100644 index 0000000000..4ec83fc156 --- /dev/null +++ b/Source/Core/Core/IOS/Crypto/AesDevice.h @@ -0,0 +1,25 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "Common/Crypto/AES.h" +#include "Core/IOS/Device.h" + +namespace IOS::HLE +{ +class AesDevice final : public EmulationDevice +{ +public: + AesDevice(EmulationKernel& ios, const std::string& device_name); + std::optional Open(const OpenRequest& request) override; + std::optional IOCtlV(const IOCtlVRequest& request) override; + + enum class AesIoctlv : u32 + { + Copy = 0x00, + Encrypt = 0x02, + Decrypt = 0x03, + }; +}; +} // namespace IOS::HLE diff --git a/Source/Core/Core/IOS/IOS.cpp b/Source/Core/Core/IOS/IOS.cpp index 329b912950..8c08c64001 100644 --- a/Source/Core/Core/IOS/IOS.cpp +++ b/Source/Core/Core/IOS/IOS.cpp @@ -28,6 +28,7 @@ #include "Core/CoreTiming.h" #include "Core/HW/Memmap.h" #include "Core/HW/WII_IPC.h" +#include "Core/IOS/Crypto/AesDevice.h" #include "Core/IOS/Crypto/Sha.h" #include "Core/IOS/DI/DI.h" #include "Core/IOS/Device.h" @@ -334,7 +335,8 @@ EmulationKernel::EmulationKernel(Core::System& system, u64 title_id) m_fs = FS::MakeFileSystem(IOS::HLE::FS::Location::Session, Core::GetActiveNandRedirects()); ASSERT(m_fs); - + + AddDevice(std::make_unique(*this, "/dev/aes")); AddDevice(std::make_unique(*this, "/dev/sha")); m_fs_core = std::make_unique(*this); @@ -659,6 +661,8 @@ std::shared_ptr EmulationKernel::GetDeviceByFileDescriptor(const int fd) switch (fd) { + case 0x10000: + return GetDeviceByName("/dev/aes"); case 0x10001: return GetDeviceByName("/dev/sha"); default: diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 37d1c13795..2cf663e399 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -344,6 +344,7 @@ + @@ -985,6 +986,7 @@ +