From ab552e4a252b66ca02c04724a1773edbefec6837 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 13 Nov 2018 12:25:43 -0500 Subject: [PATCH] svc: Use proper random entropy generation algorithm --- src/core/hle/kernel/process.cpp | 6 ++++++ src/core/hle/kernel/process.h | 11 +++++++++++ src/core/hle/kernel/svc.cpp | 11 ++++++++++- src/core/settings.h | 2 +- src/yuzu/configuration/configure_system.cpp | 7 +++---- src/yuzu/configuration/configure_system.ui | 4 ++-- 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 420218d59..6e5b36d6f 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -17,6 +17,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" +#include "core/settings.h" namespace Kernel { @@ -35,6 +36,11 @@ SharedPtr Process::Create(KernelCore& kernel, std::string&& name) { process->process_id = kernel.CreateNewProcessID(); process->svc_access_mask.set(); + std::mt19937 rng(Settings::values.rng_seed.value_or(0)); + std::uniform_int_distribution distribution; + std::generate(process->random_entropy.begin(), process->random_entropy.end(), + [&] { return distribution(rng); }); + kernel.AppendNewProcess(process); return process; } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 8d2616c79..95aa63ea1 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -119,6 +120,8 @@ struct CodeSet final { class Process final : public Object { public: + static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; + static SharedPtr Create(KernelCore& kernel, std::string&& name); std::string GetTypeName() const override { @@ -212,6 +215,11 @@ public: total_process_running_time_ticks += ticks; } + /// Gets 8 bytes of random data for svcGetInfo RandomEntropy + u64 GetRandomEntropy(std::size_t index) const { + return random_entropy.at(index); + } + /** * Loads process-specifics configuration info with metadata provided * by an executable. @@ -321,6 +329,9 @@ private: /// Per-process handle table for storing created object handles in. HandleTable handle_table; + /// Random values for svcGetInfo RandomEntropy + std::array random_entropy; + std::string name; }; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0bfe1e3be..b0b6508d9 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -559,7 +559,16 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) *result = 0; break; case GetInfoType::RandomEntropy: - *result = Settings::values.rng_seed.value_or(0); + if (handle != 0) { + return ERR_INVALID_HANDLE; + } + + if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { + return ERR_INVALID_COMBINATION_KERNEL; + } + + *result = current_process->GetRandomEntropy(info_sub_id); + return RESULT_SUCCESS; break; case GetInfoType::ASLRRegionBaseAddr: *result = vm_manager.GetASLRRegionBaseAddress(); diff --git a/src/core/settings.h b/src/core/settings.h index 83a1a7069..84dc5050b 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -115,7 +115,7 @@ struct Values { // System bool use_docked_mode; bool enable_nfc; - std::optional rng_seed; + std::optional rng_seed; s32 current_user; s32 language_index; diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 67f07ecb1..ab5d46492 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -140,7 +140,7 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) { ui->rng_seed_edit->setEnabled(checked); if (!checked) - ui->rng_seed_edit->setText(QStringLiteral("0000000000000000")); + ui->rng_seed_edit->setText(QStringLiteral("00000000")); }); scene = new QGraphicsScene; @@ -165,9 +165,8 @@ void ConfigureSystem::setConfiguration() { ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.has_value()); ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.has_value()); - const auto rng_seed = QString("%1") - .arg(Settings::values.rng_seed.value_or(0), 16, 16, QLatin1Char{'0'}) - .toUpper(); + const auto rng_seed = + QString("%1").arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'}).toUpper(); ui->rng_seed_edit->setText(rng_seed); } diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui index d0fcd0163..4ee233ed7 100644 --- a/src/yuzu/configuration/configure_system.ui +++ b/src/yuzu/configuration/configure_system.ui @@ -269,10 +269,10 @@ - HHHHHHHHHHHHHHHH + HHHHHHHH - 16 + 8