Просмотр исходного кода

Merge pull request #1670 from DarkLordZach/deterministic-rng

csrng: Add config option to set RNG seed
bunnei 7 лет назад
Родитель
Сommit
7f3c2525e6

+ 2 - 1
src/core/hle/kernel/svc.cpp

@@ -34,6 +34,7 @@
 #include "core/hle/lock.h"
 #include "core/hle/result.h"
 #include "core/hle/service/service.h"
+#include "core/settings.h"
 
 namespace Kernel {
 namespace {
@@ -558,7 +559,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
         *result = 0;
         break;
     case GetInfoType::RandomEntropy:
-        *result = 0;
+        *result = Settings::values.rng_seed.value_or(0);
         break;
     case GetInfoType::ASLRRegionBaseAddr:
         *result = vm_manager.GetASLRRegionBaseAddress();

+ 7 - 2
src/core/hle/service/spl/module.cpp

@@ -3,18 +3,23 @@
 // Refer to the license.txt file included.
 
 #include <algorithm>
+#include <chrono>
 #include <cstdlib>
+#include <ctime>
+#include <functional>
 #include <vector>
 #include "common/logging/log.h"
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/service/spl/csrng.h"
 #include "core/hle/service/spl/module.h"
 #include "core/hle/service/spl/spl.h"
+#include "core/settings.h"
 
 namespace Service::SPL {
 
 Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
-    : ServiceFramework(name), module(std::move(module)) {}
+    : ServiceFramework(name), module(std::move(module)),
+      rng(Settings::values.rng_seed.value_or(std::time(nullptr))) {}
 
 Module::Interface::~Interface() = default;
 
@@ -24,7 +29,7 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
     std::size_t size = ctx.GetWriteBufferSize();
 
     std::vector<u8> data(size);
-    std::generate(data.begin(), data.end(), std::rand);
+    std::generate(data.begin(), data.end(), rng);
 
     ctx.WriteBuffer(data);
 

+ 4 - 0
src/core/hle/service/spl/module.h

@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <random>
 #include "core/hle/service/service.h"
 
 namespace Service::SPL {
@@ -19,6 +20,9 @@ public:
 
     protected:
         std::shared_ptr<Module> module;
+
+    private:
+        std::mt19937 rng;
     };
 };
 

+ 2 - 0
src/core/settings.h

@@ -6,6 +6,7 @@
 
 #include <array>
 #include <atomic>
+#include <optional>
 #include <string>
 #include "common/common_types.h"
 
@@ -114,6 +115,7 @@ struct Values {
     // System
     bool use_docked_mode;
     bool enable_nfc;
+    std::optional<u64> rng_seed;
     s32 current_user;
     s32 language_index;
 

+ 12 - 0
src/yuzu/configuration/config.cpp

@@ -134,6 +134,14 @@ void Config::ReadValues() {
                                                     Service::Account::MAX_USERS - 1);
 
     Settings::values.language_index = qt_config->value("language_index", 1).toInt();
+
+    const auto enabled = qt_config->value("rng_seed_enabled", false).toBool();
+    if (enabled) {
+        Settings::values.rng_seed = qt_config->value("rng_seed", 0).toULongLong();
+    } else {
+        Settings::values.rng_seed = std::nullopt;
+    }
+
     qt_config->endGroup();
 
     qt_config->beginGroup("Miscellaneous");
@@ -272,6 +280,10 @@ void Config::SaveValues() {
     qt_config->setValue("current_user", Settings::values.current_user);
 
     qt_config->setValue("language_index", Settings::values.language_index);
+
+    qt_config->setValue("rng_seed_enabled", Settings::values.rng_seed.has_value());
+    qt_config->setValue("rng_seed", Settings::values.rng_seed.value_or(0));
+
     qt_config->endGroup();
 
     qt_config->beginGroup("Miscellaneous");

+ 20 - 0
src/yuzu/configuration/configure_system.cpp

@@ -137,6 +137,12 @@ ConfigureSystem::ConfigureSystem(QWidget* parent)
     connect(ui->pm_remove, &QPushButton::pressed, this, &ConfigureSystem::DeleteUser);
     connect(ui->pm_set_image, &QPushButton::pressed, this, &ConfigureSystem::SetUserImage);
 
+    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"));
+    });
+
     scene = new QGraphicsScene;
     ui->current_user_icon->setScene(scene);
 
@@ -155,6 +161,14 @@ void ConfigureSystem::setConfiguration() {
 
     PopulateUserList();
     UpdateCurrentUser();
+
+    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();
+    ui->rng_seed_edit->setText(rng_seed);
 }
 
 void ConfigureSystem::PopulateUserList() {
@@ -195,6 +209,12 @@ void ConfigureSystem::applyConfiguration() {
         return;
 
     Settings::values.language_index = ui->combo_language->currentIndex();
+
+    if (ui->rng_seed_checkbox->isChecked())
+        Settings::values.rng_seed = ui->rng_seed_edit->text().toULongLong(nullptr, 16);
+    else
+        Settings::values.rng_seed = std::nullopt;
+
     Settings::Apply();
 }
 

+ 128 - 100
src/yuzu/configuration/configure_system.ui

@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>360</width>
+    <width>366</width>
     <height>483</height>
    </rect>
   </property>
@@ -22,98 +22,6 @@
         <string>System Settings</string>
        </property>
        <layout class="QGridLayout" name="gridLayout">
-        <item row="1" column="0">
-         <widget class="QLabel" name="label_language">
-          <property name="text">
-           <string>Language</string>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="0">
-         <widget class="QLabel" name="label_birthday">
-          <property name="text">
-           <string>Birthday</string>
-          </property>
-         </widget>
-        </item>
-        <item row="3" column="0">
-         <widget class="QLabel" name="label_console_id">
-          <property name="text">
-           <string>Console ID:</string>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="1">
-         <layout class="QHBoxLayout" name="horizontalLayout_birthday2">
-          <item>
-           <widget class="QComboBox" name="combo_birthmonth">
-            <item>
-             <property name="text">
-              <string>January</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>February</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>March</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>April</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>May</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>June</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>July</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>August</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>September</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>October</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>November</string>
-             </property>
-            </item>
-            <item>
-             <property name="text">
-              <string>December</string>
-             </property>
-            </item>
-           </widget>
-          </item>
-          <item>
-           <widget class="QComboBox" name="combo_birthday"/>
-          </item>
-         </layout>
-        </item>
         <item row="1" column="1">
          <widget class="QComboBox" name="combo_language">
           <property name="toolTip">
@@ -206,6 +114,13 @@
           </item>
          </widget>
         </item>
+        <item row="3" column="0">
+         <widget class="QLabel" name="label_console_id">
+          <property name="text">
+           <string>Console ID:</string>
+          </property>
+         </widget>
+        </item>
         <item row="2" column="0">
          <widget class="QLabel" name="label_sound">
           <property name="text">
@@ -213,6 +128,100 @@
           </property>
          </widget>
         </item>
+        <item row="0" column="0">
+         <widget class="QLabel" name="label_birthday">
+          <property name="text">
+           <string>Birthday</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <layout class="QHBoxLayout" name="horizontalLayout_birthday2">
+          <item>
+           <widget class="QComboBox" name="combo_birthmonth">
+            <item>
+             <property name="text">
+              <string>January</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>February</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>March</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>April</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>May</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>June</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>July</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>August</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>September</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>October</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>November</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>December</string>
+             </property>
+            </item>
+           </widget>
+          </item>
+          <item>
+           <widget class="QComboBox" name="combo_birthday"/>
+          </item>
+         </layout>
+        </item>
+        <item row="3" column="1">
+         <widget class="QPushButton" name="button_regenerate_console_id">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="layoutDirection">
+           <enum>Qt::RightToLeft</enum>
+          </property>
+          <property name="text">
+           <string>Regenerate</string>
+          </property>
+         </widget>
+        </item>
         <item row="2" column="1">
          <widget class="QComboBox" name="combo_sound">
           <item>
@@ -232,19 +241,38 @@
           </item>
          </widget>
         </item>
-        <item row="3" column="1">
-         <widget class="QPushButton" name="button_regenerate_console_id">
+        <item row="1" column="0">
+         <widget class="QLabel" name="label_language">
+          <property name="text">
+           <string>Language</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="0">
+         <widget class="QCheckBox" name="rng_seed_checkbox">
+          <property name="text">
+           <string>RNG Seed</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="1">
+         <widget class="QLineEdit" name="rng_seed_edit">
           <property name="sizePolicy">
-           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
-          <property name="layoutDirection">
-           <enum>Qt::RightToLeft</enum>
+          <property name="font">
+           <font>
+            <family>Lucida Console</family>
+           </font>
           </property>
-          <property name="text">
-           <string>Regenerate</string>
+          <property name="inputMask">
+           <string>HHHHHHHHHHHHHHHH</string>
+          </property>
+          <property name="maxLength">
+           <number>16</number>
           </property>
          </widget>
         </item>

+ 7 - 0
src/yuzu_cmd/config.cpp

@@ -132,6 +132,13 @@ void Config::ReadValues() {
     Settings::values.current_user = std::clamp<int>(
         sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1);
 
+    const auto enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false);
+    if (enabled) {
+        Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0);
+    } else {
+        Settings::values.rng_seed = std::nullopt;
+    }
+
     // Miscellaneous
     Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
     Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false);

+ 5 - 0
src/yuzu_cmd/default_ini.h

@@ -178,6 +178,11 @@ use_docked_mode =
 # 1 (default): Yes, 0 : No
 enable_nfc =
 
+# Sets the seed for the RNG generator built into the switch
+# rng_seed will be ignored and randomly generated if rng_seed_enabled is false
+rng_seed_enabled =
+rng_seed =
+
 # Sets the account username, max length is 32 characters
 # yuzu (default)
 username = yuzu