spl: continue implementing.

This commit is contained in:
Michael Scire 2019-04-24 05:38:11 -07:00
parent 9858d6fc95
commit 2dfa1c96d1
8 changed files with 628 additions and 10 deletions

View file

@ -18,6 +18,40 @@
#include <stratosphere.hpp>
#include "spl_secmon_wrapper.hpp"
#include "spl_smc_wrapper.hpp"
#include "spl_ctr_drbg.hpp"
/* Globals. */
static CtrDrbg g_drbg;
static Event g_se_event;
static __attribute__((aligned(0x1000))) u8 g_work_buffer[0x1000];
void SecureMonitorWrapper::InitializeCtrDrbg() {
u8 seed[CtrDrbg::SeedSize];
if (SmcWrapper::GenerateRandomBytes(seed, sizeof(seed)) != SmcResult_Success) {
std::abort();
}
g_drbg.Initialize(seed);
}
void SecureMonitorWrapper::InitializeSeInterruptEvent() {
u64 irq_num;
SmcWrapper::GetConfig(&irq_num, 1, SplConfigItem_SecurityEngineIrqNumber);
Handle hnd;
if (R_FAILED(svcCreateInterruptEvent(&hnd, irq_num, 1))) {
std::abort();
}
eventLoadRemote(&g_se_event, hnd, true);
}
void SecureMonitorWrapper::Initialize() {
/* Initialize the Drbg. */
InitializeCtrDrbg();
/* Initialize SE interrupt event. */
InitializeSeInterruptEvent();
}
Result SecureMonitorWrapper::ConvertToSplResult(SmcResult result) {
if (result == SmcResult_Success) {
@ -30,8 +64,25 @@ Result SecureMonitorWrapper::ConvertToSplResult(SmcResult result) {
}
Result SecureMonitorWrapper::GetConfig(u64 *out, SplConfigItem which) {
/* TODO */
return ResultKernelConnectionClosed;
/* Nintendo explicitly blacklists package2 hash here, amusingly. */
/* This is not blacklisted in safemode, but we're never in safe mode... */
if (which == SplConfigItem_Package2Hash) {
return ResultSplInvalidArgument;
}
SmcResult res = SmcWrapper::GetConfig(out, 1, which);
/* Nintendo has some special handling here for hardware type/is_retail. */
if (which == SplConfigItem_HardwareType && res == SmcResult_InvalidArgument) {
*out = 0;
res = SmcResult_Success;
}
if (which == SplConfigItem_IsRetail && res == SmcResult_InvalidArgument) {
*out = 0;
res = SmcResult_Success;
}
return ConvertToSplResult(res);
}
Result SecureMonitorWrapper::ExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *exp, size_t exp_size, const void *mod, size_t mod_size) {
@ -40,13 +91,42 @@ Result SecureMonitorWrapper::ExpMod(void *out, size_t out_size, const void *base
}
Result SecureMonitorWrapper::SetConfig(SplConfigItem which, u64 value) {
/* TODO */
return ResultKernelConnectionClosed;
return ConvertToSplResult(SmcWrapper::SetConfig(which, &value, 1));
}
Result SecureMonitorWrapper::GenerateRandomBytesInternal(void *out, size_t size) {
if (!g_drbg.GenerateRandomBytes(out, size)) {
/* We need to reseed. */
{
u8 seed[CtrDrbg::SeedSize];
SmcResult res = SmcWrapper::GenerateRandomBytes(seed, sizeof(seed));
if (res != SmcResult_Success) {
return ConvertToSplResult(res);
}
g_drbg.Reseed(seed);
g_drbg.GenerateRandomBytes(out, size);
}
}
return ResultSuccess;
}
Result SecureMonitorWrapper::GenerateRandomBytes(void *out, size_t size) {
/* TODO */
return ResultKernelConnectionClosed;
u8 *cur_dst = reinterpret_cast<u8 *>(out);
for (size_t ofs = 0; ofs < size; ofs += CtrDrbg::MaxRequestSize) {
const size_t cur_size = std::min(size - ofs, CtrDrbg::MaxRequestSize);
Result rc = GenerateRandomBytesInternal(cur_dst, size);
if (R_FAILED(rc)) {
return rc;
}
cur_dst += cur_size;
}
return ResultSuccess;
}
Result SecureMonitorWrapper::IsDevelopment(bool *out) {