Skip to content

Commit

Permalink
Implement PS:GetRandomBytes and use openssl for random bytes (#7164)
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloMK7 authored Nov 15, 2023
1 parent e9936e0 commit de40153
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 32 deletions.
17 changes: 16 additions & 1 deletion src/core/hle/service/ps/ps_ps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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<u32>();
auto buffer = rp.PopMappedBuffer();

std::vector<u8> 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
Expand All @@ -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"},
Expand Down
38 changes: 10 additions & 28 deletions src/core/hle/service/ssl/ssl_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#include <openssl/rand.h>
#include "common/archives.h"
#include "common/common_types.h"
#include "core/core.h"
Expand All @@ -16,44 +17,20 @@ 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);
}

void SSL_C::GenerateRandomData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx);
u32 size = rp.Pop<u32>();
const u32 size = rp.Pop<u32>();
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<u8> 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);
Expand Down Expand Up @@ -96,4 +73,9 @@ void InstallInterfaces(Core::System& system) {
std::make_shared<SSL_C>()->InstallAsService(service_manager);
}

void GenerateRandomData(std::vector<u8>& out) {
// Fill the output buffer with random data.
RAND_bytes(out.data(), static_cast<int>(out.size()));
}

} // namespace Service::SSL
5 changes: 2 additions & 3 deletions src/core/hle/service/ssl/ssl_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ class SSL_C final : public ServiceFramework<SSL_C> {
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<u8>& out);

} // namespace Service::SSL

BOOST_CLASS_EXPORT_KEY(Service::SSL::SSL_C)

0 comments on commit de40153

Please sign in to comment.