PRODINFO: Revamp blanking/write disallow policy. (#913)

* exo/fusee: hookup new prodinfo settings

* fusee: new scheme doesn't need FLAGS_DEFAULT

* fusee: fix c/p errors

* ams.mitm: completely revamp prodinfo backup mechanism

* ams.mitm: Implement revamped blanking/write policy

* strat: make early boot more debuggable

* exo: condense flag logic
This commit is contained in:
SciresM 2020-04-22 16:22:14 -07:00 committed by Michael Scire
parent fb3b3f4a72
commit d2de74155d
12 changed files with 174 additions and 16 deletions

View File

@ -22,4 +22,8 @@ namespace ams {
/* Will be called by libstratosphere on crash. */
void CrashHandler(ThreadExceptionDump *ctx);
/* API for boot sysmodule. */
void InitializeForBoot();
void SetInitialRebootPayload(const void *src, size_t src_size);
}

View File

@ -27,6 +27,11 @@ namespace ams::exosphere {
bool IsRcmBugPatched();
bool ShouldBlankProdInfo();
bool ShouldAllowWritesToProdInfo();
u64 GetDeviceId();
void CopyToIram(uintptr_t iram_dst, const void *dram_src, size_t size);
void CopyFromIram(void *dram_dst, uintptr_t iram_src, size_t size);

View File

@ -16,11 +16,13 @@
#pragma once
#include "settings/settings_types.hpp"
#include "settings/settings_fwdbg_types.hpp"
#include "settings/settings_fwdbg_api.hpp"
#include "settings/system/settings_error_report.hpp"
#include "settings/system/settings_firmware_version.hpp"
#include "settings/system/settings_product_model.hpp"
#include "settings/system/settings_region.hpp"
#include "settings/system/settings_serial_number.hpp"
#include <stratosphere/settings/settings_types.hpp>
#include <stratosphere/settings/settings_fwdbg_types.hpp>
#include <stratosphere/settings/settings_fwdbg_api.hpp>
#include <stratosphere/settings/factory/settings_serial_number.hpp>
#include <stratosphere/settings/factory/settings_device_certificate.hpp>
#include <stratosphere/settings/system/settings_error_report.hpp>
#include <stratosphere/settings/system/settings_firmware_version.hpp>
#include <stratosphere/settings/system/settings_product_model.hpp>
#include <stratosphere/settings/system/settings_region.hpp>
#include <stratosphere/settings/system/settings_serial_number.hpp>

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::settings::factory {
struct EccP256DeviceCertificate {
u8 data[0x180];
};
static_assert(sizeof(EccP256DeviceCertificate) == 0x180);
static_assert(std::is_pod<EccP256DeviceCertificate>::value);
struct EccB233DeviceCertificate {
u8 data[0x180];
};
static_assert(sizeof(EccB233DeviceCertificate) == 0x180);
static_assert(std::is_pod<EccB233DeviceCertificate>::value);
struct Rsa2048DeviceCertificate {
u8 data[0x240];
};
static_assert(sizeof(Rsa2048DeviceCertificate) == 0x240);
static_assert(std::is_pod<Rsa2048DeviceCertificate>::value);
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
namespace ams::settings::factory {
struct SerialNumber {
char str[0x18];
};
static_assert(sizeof(SerialNumber) == 0x18);
static_assert(std::is_pod<SerialNumber>::value);
}

View File

@ -27,4 +27,7 @@ namespace ams::spl {
bool IsMariko();
bool IsRecoveryBoot();
Result GenerateAesKek(AccessKey *access_key, const void *key_source, size_t key_source_size, u32 generation, u32 option);
Result GenerateAesKey(void *dst, size_t dst_size, const AccessKey &access_key, const void *key_source, size_t key_source_size);
}

View File

@ -183,6 +183,36 @@ namespace ams::spl {
static_assert(alignof(AccessKey) == alignof(u8), "KeySource definition!");
#pragma pack(pop)
enum class ConfigItem : u32 {
/* Standard config items. */
DisableProgramVerification = 1,
DramId = 2,
SecurityEngineIrqNumber = 3,
Version = 4,
HardwareType = 5,
IsRetail = 6,
IsRecoveryBoot = 7,
DeviceId = 8,
BootReason = 9,
MemoryMode = 10,
IsDebugMode = 11,
KernelConfiguration = 12,
IsChargerHiZModeEnabled = 13,
IsQuest = 14,
RegulatorType = 15,
DeviceUniqueKeyGeneration = 16,
Package2Hash = 17,
/* Extension config items for exosphere. */
ExosphereApiVersion = 65000,
ExosphereNeedsReboot = 65001,
ExosphereNeedsShutdown = 65002,
ExosphereGitCommitHash = 65003,
ExosphereHasRcmBugPatch = 65004,
ExosphereBlankProdInfo = 65005,
ExosphereAllowCalWrites = 65006,
};
}
/* Extensions to libnx spl config item enum. */
@ -191,3 +221,5 @@ constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsReboot = static_ca
constexpr inline SplConfigItem SplConfigItem_ExosphereNeedsShutdown = static_cast<SplConfigItem>(65002);
constexpr inline SplConfigItem SplConfigItem_ExosphereGitCommitHash = static_cast<SplConfigItem>(65003);
constexpr inline SplConfigItem SplConfigItem_ExosphereHasRcmBugPatch = static_cast<SplConfigItem>(65004);
constexpr inline SplConfigItem SplConfigItem_ExosphereBlankProdInfo = static_cast<SplConfigItem>(65005);
constexpr inline SplConfigItem SplConfigItem_ExosphereAllowCalWrites = static_cast<SplConfigItem>(65006);

View File

@ -24,6 +24,11 @@ NX_GENERATE_SERVICE_GUARD(amsBpc);
Result _amsBpcInitialize(void) {
Handle h;
Result rc = svcConnectToNamedPort(&h, "bpc:ams"); /* TODO: ams:bpc */
while (R_VALUE(rc) == KERNELRESULT(NotFound)) {
svcSleepThread(50000000ul);
rc = svcConnectToNamedPort(&h, "bpc:ams");
}
if (R_SUCCEEDED(rc)) serviceCreate(&g_amsBpcSrv, h);
return rc;
}
@ -44,3 +49,11 @@ Result amsBpcRebootToFatalError(void *ctx) {
.buffers = { { ctx, 0x450 } },
);
}
Result amsBpcSetInitialPayload(const void *src, size_t src_size) {
return serviceDispatch(&g_amsBpcSrv, 65001,
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias },
.buffers = { { src, src_size } },
);
}

View File

@ -28,6 +28,7 @@ void amsBpcExit(void);
Service *amsBpcGetServiceSession(void);
Result amsBpcRebootToFatalError(void *ctx);
Result amsBpcSetInitialPayload(const void *src, size_t src_size);
#ifdef __cplusplus
}

View File

@ -36,6 +36,14 @@ namespace ams {
extern ncm::ProgramId CurrentProgramId;
void InitializeForBoot() {
R_ABORT_UNLESS(amsBpcInitialize());
}
void SetInitialRebootPayload(const void *src, size_t src_size) {
R_ABORT_UNLESS(amsBpcSetInitialPayload(src, src_size));
}
void WEAK_SYMBOL ExceptionHandler(FatalErrorContext *ctx) {
R_ABORT_UNLESS(amsBpcInitialize());
R_ABORT_UNLESS(amsBpcRebootToFatalError(ctx));

View File

@ -51,19 +51,32 @@ namespace ams::exosphere {
namespace {
inline Result GetRcmBugPatched(bool *out) {
u64 tmp = 0;
R_TRY(spl::smc::ConvertResult(spl::smc::GetConfig(&tmp, 1, SplConfigItem_ExosphereHasRcmBugPatch)));
*out = (tmp != 0);
return ResultSuccess();
inline u64 GetU64ConfigItem(spl::ConfigItem cfg) {
u64 tmp;
R_ABORT_UNLESS(spl::smc::ConvertResult(spl::smc::GetConfig(std::addressof(tmp), 1, static_cast<::SplConfigItem>(cfg))));
return tmp;
}
inline bool GetBooleanConfigItem(spl::ConfigItem cfg) {
return GetU64ConfigItem(cfg) != 0;
}
}
bool IsRcmBugPatched() {
bool rcm_bug_patched;
R_ABORT_UNLESS(GetRcmBugPatched(&rcm_bug_patched));
return rcm_bug_patched;
return GetBooleanConfigItem(spl::ConfigItem::ExosphereHasRcmBugPatch);
}
bool ShouldBlankProdInfo() {
return GetBooleanConfigItem(spl::ConfigItem::ExosphereBlankProdInfo);
}
bool ShouldAllowWritesToProdInfo() {
return GetBooleanConfigItem(spl::ConfigItem::ExosphereAllowCalWrites);
}
u64 GetDeviceId() {
return GetU64ConfigItem(spl::ConfigItem::DeviceId);
}
}

View File

@ -78,4 +78,15 @@ namespace ams::spl {
}
}
Result GenerateAesKek(AccessKey *access_key, const void *key_source, size_t key_source_size, u32 generation, u32 option) {
AMS_ASSERT(key_source_size == sizeof(KeySource));
return splCryptoGenerateAesKek(key_source, generation, option, static_cast<void *>(access_key));
}
Result GenerateAesKey(void *dst, size_t dst_size, const AccessKey &access_key, const void *key_source, size_t key_source_size) {
AMS_ASSERT(dst_size == crypto::AesEncryptor128::KeySize);
AMS_ASSERT(key_source_size == sizeof(KeySource));
return splCryptoGenerateAesKey(std::addressof(access_key), key_source, dst);
}
}