Browse Source

Merge pull request #1679 from DarkLordZach/deterministic-rng-2

svc: Use proper random entropy generation algorithm
bunnei 7 years ago
parent
commit
e1ea8cc721

+ 6 - 0
src/core/hle/kernel/process.cpp

@@ -15,6 +15,7 @@
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/vm_manager.h"
 #include "core/hle/kernel/vm_manager.h"
 #include "core/memory.h"
 #include "core/memory.h"
+#include "core/settings.h"
 
 
 namespace Kernel {
 namespace Kernel {
 
 
@@ -33,6 +34,11 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
     process->process_id = kernel.CreateNewProcessID();
     process->process_id = kernel.CreateNewProcessID();
     process->svc_access_mask.set();
     process->svc_access_mask.set();
 
 
+    std::mt19937 rng(Settings::values.rng_seed.value_or(0));
+    std::uniform_int_distribution<u64> distribution;
+    std::generate(process->random_entropy.begin(), process->random_entropy.end(),
+                  [&] { return distribution(rng); });
+
     kernel.AppendNewProcess(process);
     kernel.AppendNewProcess(process);
     return process;
     return process;
 }
 }

+ 11 - 0
src/core/hle/kernel/process.h

@@ -8,6 +8,7 @@
 #include <bitset>
 #include <bitset>
 #include <cstddef>
 #include <cstddef>
 #include <memory>
 #include <memory>
+#include <random>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 #include <boost/container/static_vector.hpp>
 #include <boost/container/static_vector.hpp>
@@ -119,6 +120,8 @@ struct CodeSet final {
 
 
 class Process final : public Object {
 class Process final : public Object {
 public:
 public:
+    static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
+
     static SharedPtr<Process> Create(KernelCore& kernel, std::string&& name);
     static SharedPtr<Process> Create(KernelCore& kernel, std::string&& name);
 
 
     std::string GetTypeName() const override {
     std::string GetTypeName() const override {
@@ -212,6 +215,11 @@ public:
         total_process_running_time_ticks += ticks;
         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
      * Loads process-specifics configuration info with metadata provided
      * by an executable.
      * by an executable.
@@ -310,6 +318,9 @@ private:
     /// Per-process handle table for storing created object handles in.
     /// Per-process handle table for storing created object handles in.
     HandleTable handle_table;
     HandleTable handle_table;
 
 
+    /// Random values for svcGetInfo RandomEntropy
+    std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy;
+
     std::string name;
     std::string name;
 };
 };
 
 

+ 10 - 1
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;
         *result = 0;
         break;
         break;
     case GetInfoType::RandomEntropy:
     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;
         break;
     case GetInfoType::ASLRRegionBaseAddr:
     case GetInfoType::ASLRRegionBaseAddr:
         *result = vm_manager.GetASLRRegionBaseAddress();
         *result = vm_manager.GetASLRRegionBaseAddress();

+ 1 - 1
src/core/settings.h

@@ -115,7 +115,7 @@ struct Values {
     // System
     // System
     bool use_docked_mode;
     bool use_docked_mode;
     bool enable_nfc;
     bool enable_nfc;
-    std::optional<u64> rng_seed;
+    std::optional<u32> rng_seed;
     s32 current_user;
     s32 current_user;
     s32 language_index;
     s32 language_index;
 
 

+ 3 - 4
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) {
     connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) {
         ui->rng_seed_edit->setEnabled(checked);
         ui->rng_seed_edit->setEnabled(checked);
         if (!checked)
         if (!checked)
-            ui->rng_seed_edit->setText(QStringLiteral("0000000000000000"));
+            ui->rng_seed_edit->setText(QStringLiteral("00000000"));
     });
     });
 
 
     scene = new QGraphicsScene;
     scene = new QGraphicsScene;
@@ -165,9 +165,8 @@ void ConfigureSystem::setConfiguration() {
     ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.has_value());
     ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.has_value());
     ui->rng_seed_edit->setEnabled(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);
     ui->rng_seed_edit->setText(rng_seed);
 }
 }
 
 

+ 2 - 2
src/yuzu/configuration/configure_system.ui

@@ -269,10 +269,10 @@
            </font>
            </font>
           </property>
           </property>
           <property name="inputMask">
           <property name="inputMask">
-           <string>HHHHHHHHHHHHHHHH</string>
+           <string>HHHHHHHH</string>
           </property>
           </property>
           <property name="maxLength">
           <property name="maxLength">
-           <number>16</number>
+           <number>8</number>
           </property>
           </property>
          </widget>
          </widget>
         </item>
         </item>