Merge pull request #1670 from DarkLordZach/deterministic-rng

csrng: Add config option to set RNG seed
merge-requests/60/head
bunnei 2018-11-12 21:10:08 +07:00 committed by GitHub
commit 7f3c2525e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 187 additions and 103 deletions

@ -34,6 +34,7 @@
#include "core/hle/lock.h" #include "core/hle/lock.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
#include "core/settings.h"
namespace Kernel { namespace Kernel {
namespace { namespace {
@ -558,7 +559,7 @@ 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 = 0; *result = Settings::values.rng_seed.value_or(0);
break; break;
case GetInfoType::ASLRRegionBaseAddr: case GetInfoType::ASLRRegionBaseAddr:
*result = vm_manager.GetASLRRegionBaseAddress(); *result = vm_manager.GetASLRRegionBaseAddress();

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

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

@ -6,6 +6,7 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <optional>
#include <string> #include <string>
#include "common/common_types.h" #include "common/common_types.h"
@ -114,6 +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;
s32 current_user; s32 current_user;
s32 language_index; s32 language_index;

@ -134,6 +134,14 @@ void Config::ReadValues() {
Service::Account::MAX_USERS - 1); Service::Account::MAX_USERS - 1);
Settings::values.language_index = qt_config->value("language_index", 1).toInt(); 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->endGroup();
qt_config->beginGroup("Miscellaneous"); qt_config->beginGroup("Miscellaneous");
@ -272,6 +280,10 @@ void Config::SaveValues() {
qt_config->setValue("current_user", Settings::values.current_user); qt_config->setValue("current_user", Settings::values.current_user);
qt_config->setValue("language_index", Settings::values.language_index); 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->endGroup();
qt_config->beginGroup("Miscellaneous"); qt_config->beginGroup("Miscellaneous");

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

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>360</width> <width>366</width>
<height>483</height> <height>483</height>
</rect> </rect>
</property> </property>
@ -22,98 +22,6 @@
<string>System Settings</string> <string>System Settings</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <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"> <item row="1" column="1">
<widget class="QComboBox" name="combo_language"> <widget class="QComboBox" name="combo_language">
<property name="toolTip"> <property name="toolTip">
@ -206,6 +114,13 @@
</item> </item>
</widget> </widget>
</item> </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"> <item row="2" column="0">
<widget class="QLabel" name="label_sound"> <widget class="QLabel" name="label_sound">
<property name="text"> <property name="text">
@ -213,6 +128,100 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="2" column="1">
<widget class="QComboBox" name="combo_sound"> <widget class="QComboBox" name="combo_sound">
<item> <item>
@ -232,19 +241,38 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="1" column="0">
<widget class="QPushButton" name="button_regenerate_console_id"> <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"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="layoutDirection"> <property name="font">
<enum>Qt::RightToLeft</enum> <font>
<family>Lucida Console</family>
</font>
</property> </property>
<property name="text"> <property name="inputMask">
<string>Regenerate</string> <string>HHHHHHHHHHHHHHHH</string>
</property>
<property name="maxLength">
<number>16</number>
</property> </property>
</widget> </widget>
</item> </item>

@ -132,6 +132,13 @@ void Config::ReadValues() {
Settings::values.current_user = std::clamp<int>( Settings::values.current_user = std::clamp<int>(
sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); 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 // Miscellaneous
Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false); Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false);

@ -178,6 +178,11 @@ use_docked_mode =
# 1 (default): Yes, 0 : No # 1 (default): Yes, 0 : No
enable_nfc = 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 # Sets the account username, max length is 32 characters
# yuzu (default) # yuzu (default)
username = yuzu username = yuzu