IOS: implement /dev/aes

This commit is contained in:
DacoTaco 2023-10-17 20:09:04 +02:00
parent d4c18f3f31
commit 2241aaf168
5 changed files with 123 additions and 1 deletions

View File

@ -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

View File

@ -0,0 +1,89 @@
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/IOS/Crypto/AesDevice.h"
#include <algorithm>
#include <array>
#include <iterator>
#include <memory>
#include <optional>
#include <vector>
#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<IPCReply> AesDevice::Open(const OpenRequest& request)
{
return Device::Open(request);
}
std::optional<IPCReply> AesDevice::IOCtlV(const IOCtlVRequest& request)
{
auto& system = GetSystem();
auto& memory = system.GetMemory();
HLE::ReturnCode return_code = IPC_EINVAL;
AesIoctlv command = static_cast<AesIoctlv>(request.request);
switch (command)
{
case AesIoctlv::Copy:
{
if (!request.HasNumberOfValidVectors(1, 1))
break;
std::vector<u8> input = std::vector<u8>(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<u8> input = std::vector<u8>(request.in_vectors[0].size);
std::vector<u8> output = std::vector<u8>(request.io_vectors[0].size);
std::array<u8, 10> key = {0};
std::array<u8, 10> 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

View File

@ -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<IPCReply> Open(const OpenRequest& request) override;
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
enum class AesIoctlv : u32
{
Copy = 0x00,
Encrypt = 0x02,
Decrypt = 0x03,
};
};
} // namespace IOS::HLE

View File

@ -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<AesDevice>(*this, "/dev/aes"));
AddDevice(std::make_unique<ShaDevice>(*this, "/dev/sha"));
m_fs_core = std::make_unique<FSCore>(*this);
@ -659,6 +661,8 @@ std::shared_ptr<Device> EmulationKernel::GetDeviceByFileDescriptor(const int fd)
switch (fd)
{
case 0x10000:
return GetDeviceByName("/dev/aes");
case 0x10001:
return GetDeviceByName("/dev/sha");
default:

View File

@ -344,6 +344,7 @@
<ClInclude Include="Core\HW\WiiSave.h" />
<ClInclude Include="Core\HW\WiiSaveStructs.h" />
<ClInclude Include="Core\IOS\Crypto\Sha.h" />
<ClInclude Include="Core\IOS\Crypto\AesDevice.h" />
<ClInclude Include="Core\IOS\Device.h" />
<ClInclude Include="Core\IOS\DeviceStub.h" />
<ClInclude Include="Core\IOS\DI\DI.h" />
@ -985,6 +986,7 @@
<ClCompile Include="Core\HW\WiimoteReal\WiimoteReal.cpp" />
<ClCompile Include="Core\HW\WiiSave.cpp" />
<ClCompile Include="Core\IOS\Crypto\Sha.cpp" />
<ClCompile Include="Core\IOS\Crypto\AesDevice.cpp" />
<ClCompile Include="Core\IOS\Device.cpp" />
<ClCompile Include="Core\IOS\DeviceStub.cpp" />
<ClCompile Include="Core\IOS\DI\DI.cpp" />