From de40153fa4deeec7df404b53795196d3b7f60653 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Wed, 15 Nov 2023 01:15:50 +0100 Subject: [PATCH] Implement PS:GetRandomBytes and use openssl for random bytes (#7164) --- src/core/hle/service/ps/ps_ps.cpp | 17 ++++++++++++- src/core/hle/service/ssl/ssl_c.cpp | 38 ++++++++---------------------- src/core/hle/service/ssl/ssl_c.h | 5 ++-- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/src/core/hle/service/ps/ps_ps.cpp b/src/core/hle/service/ps/ps_ps.cpp index 32026fa0cfd..64f0a4355a9 100644 --- a/src/core/hle/service/ps/ps_ps.cpp +++ b/src/core/hle/service/ps/ps_ps.cpp @@ -9,6 +9,7 @@ #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/ps/ps_ps.h" +#include "core/hle/service/ssl/ssl_c.h" #include "core/hw/aes/arithmetic128.h" #include "core/hw/aes/key.h" @@ -146,6 +147,20 @@ void PS_PS::EncryptDecryptAes(Kernel::HLERequestContext& ctx) { rb.PushMappedBuffer(destination); } +void PS_PS::GenerateRandomBytes(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx); + const u32 size = rp.Pop(); + auto buffer = rp.PopMappedBuffer(); + + std::vector out_data(size); + SSL::GenerateRandomData(out_data); + buffer.Write(out_data.data(), 0, size); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); + rb.Push(RESULT_SUCCESS); + rb.PushMappedBuffer(buffer); +} + PS_PS::PS_PS() : ServiceFramework("ps:ps", DefaultMaxSessions) { static const FunctionInfo functions[] = { // clang-format off @@ -160,7 +175,7 @@ PS_PS::PS_PS() : ServiceFramework("ps:ps", DefaultMaxSessions) { {0x000A, nullptr, "GetLocalFriendCodeSeed"}, {0x000B, nullptr, "GetDeviceId"}, {0x000C, nullptr, "SeedRNG"}, - {0x000D, nullptr, "GenerateRandomBytes"}, + {0x000D, &PS_PS::GenerateRandomBytes, "GenerateRandomBytes"}, {0x000E, nullptr, "InterfaceForPXI_0x04010084"}, {0x000F, nullptr, "InterfaceForPXI_0x04020082"}, {0x0010, nullptr, "InterfaceForPXI_0x04030044"}, diff --git a/src/core/hle/service/ssl/ssl_c.cpp b/src/core/hle/service/ssl/ssl_c.cpp index df95a72aae9..43c2b6e3005 100644 --- a/src/core/hle/service/ssl/ssl_c.cpp +++ b/src/core/hle/service/ssl/ssl_c.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "common/archives.h" #include "common/common_types.h" #include "core/core.h" @@ -16,10 +17,6 @@ void SSL_C::Initialize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); rp.PopPID(); - // Seed random number generator when the SSL service is initialized - std::random_device rand_device; - rand_gen.seed(rand_device()); - // Stub, return success IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); rb.Push(RESULT_SUCCESS); @@ -27,33 +24,13 @@ void SSL_C::Initialize(Kernel::HLERequestContext& ctx) { void SSL_C::GenerateRandomData(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); - u32 size = rp.Pop(); + const u32 size = rp.Pop(); auto buffer = rp.PopMappedBuffer(); - // Fill the output buffer with random data. - u32 data = 0; - u32 i = 0; - while (i < size) { - if ((i % 4) == 0) { - // The random number generator returns 4 bytes worth of data, so generate new random - // data when i == 0 and when i is divisible by 4 - data = rand_gen(); - } - - if (size > 4) { - // Use up the entire 4 bytes of the random data for as long as possible - buffer.Write(&data, i, 4); - i += 4; - } else if (size == 2) { - buffer.Write(&data, i, 2); - i += 2; - } else { - buffer.Write(&data, i, 1); - i++; - } - } + std::vector out_data(size); + SSL::GenerateRandomData(out_data); + buffer.Write(out_data.data(), 0, size); - // Stub, return success IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(RESULT_SUCCESS); rb.PushMappedBuffer(buffer); @@ -96,4 +73,9 @@ void InstallInterfaces(Core::System& system) { std::make_shared()->InstallAsService(service_manager); } +void GenerateRandomData(std::vector& out) { + // Fill the output buffer with random data. + RAND_bytes(out.data(), static_cast(out.size())); +} + } // namespace Service::SSL diff --git a/src/core/hle/service/ssl/ssl_c.h b/src/core/hle/service/ssl/ssl_c.h index 30b87378a08..d4bcd144913 100644 --- a/src/core/hle/service/ssl/ssl_c.h +++ b/src/core/hle/service/ssl/ssl_c.h @@ -21,14 +21,13 @@ class SSL_C final : public ServiceFramework { void Initialize(Kernel::HLERequestContext& ctx); void GenerateRandomData(Kernel::HLERequestContext& ctx); - // TODO: Implement a proper CSPRNG in the future when actual security is needed - std::mt19937 rand_gen; - SERVICE_SERIALIZATION_SIMPLE }; void InstallInterfaces(Core::System& system); +void GenerateRandomData(std::vector& out); + } // namespace Service::SSL BOOST_CLASS_EXPORT_KEY(Service::SSL::SSL_C)