From 8e1736c48032d6a4d884cc28be3b3b71a440f472 Mon Sep 17 00:00:00 2001 From: fincs Date: Wed, 17 Oct 2018 17:17:05 +0200 Subject: [PATCH] Add RandomSeed (14) homebrew ABI key and related handling --- nx/include/switch/runtime/env.h | 14 ++++++++++++-- nx/source/kernel/random.c | 11 +++++++++++ nx/source/runtime/env.c | 17 +++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/nx/include/switch/runtime/env.h b/nx/include/switch/runtime/env.h index 8a409be6..ac311e17 100644 --- a/nx/include/switch/runtime/env.h +++ b/nx/include/switch/runtime/env.h @@ -30,9 +30,10 @@ enum { EntryType_SyscallAvailableHint=6, ///< Provides syscall availability hints. EntryType_AppletType=7, ///< Provides APT applet type. EntryType_AppletWorkaround=8, ///< Indicates that APT is broken and should not be used. - EntryType_StdioSockets=9, ///< Provides socket-based standard stream redirection information. + EntryType_Reserved9=9, ///< Unused/reserved entry type, formerly used by StdioSockets. EntryType_ProcessHandle=10, ///< Provides the process handle. - EntryType_LastLoadResult=11 ///< Provides the last load result. + EntryType_LastLoadResult=11, ///< Provides the last load result. + EntryType_RandomSeed=14, ///< Provides random data used to seed the pseudo-random number generator. }; enum { @@ -95,3 +96,12 @@ bool envHasNextLoad(void); /// Returns the Result from the last NRO. Result envGetLastLoadResult(void); + +/// Returns true if the environment provides a random seed. +bool envHasRandomSeed(void); + +/** + * @brief Retrieves the random seed provided by the environment. + * @param out Pointer to a u64[2] buffer which will contain the random seed on return. + */ +void envGetRandomSeed(u64 out[2]); diff --git a/nx/source/kernel/random.c b/nx/source/kernel/random.c index af8393c6..ba773178 100644 --- a/nx/source/kernel/random.c +++ b/nx/source/kernel/random.c @@ -13,6 +13,7 @@ #include "kernel/mutex.h" #include "kernel/svc.h" #include "kernel/random.h" +#include "runtime/env.h" #define ROTL32(x, n) (((x) << (n)) | ((x) >> (32-(n)))) @@ -139,6 +140,16 @@ static void _randomInit(void) fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadGetInfo_Rng)); } + if (envHasRandomSeed()) + { + u64 other_seed[2]; + envGetRandomSeed(other_seed); + seed[0] ^= other_seed[1]; + seed[1] ^= seed[0]; + seed[2] ^= other_seed[0]; + seed[3] ^= seed[2]; + } + u8 iv[8]; memset(iv, 0, sizeof iv); diff --git a/nx/source/runtime/env.c b/nx/source/runtime/env.c index 0300beb9..7fe4fdfa 100644 --- a/nx/source/runtime/env.c +++ b/nx/source/runtime/env.c @@ -18,6 +18,8 @@ static Handle g_processHandle = INVALID_HANDLE; static char* g_nextLoadPath = NULL; static char* g_nextLoadArgv = NULL; static Result g_lastLoadResult = 0; +static bool g_hasRandomSeed = false; +static u64 g_randomSeed[2] = { 0, 0 }; extern __attribute__((weak)) u32 __nx_applet_type; @@ -91,6 +93,12 @@ void envSetup(void* ctx, Handle main_thread, LoaderReturnFn saved_lr) g_lastLoadResult = ent->Value[0]; break; + case EntryType_RandomSeed: + g_hasRandomSeed = true; + g_randomSeed[0] = ent->Value[0]; + g_randomSeed[1] = ent->Value[1]; + break; + default: if (ent->Flags & EntryFlag_IsMandatory) { @@ -179,3 +187,12 @@ bool envHasNextLoad(void) { Result envGetLastLoadResult(void) { return g_lastLoadResult; } + +bool envHasRandomSeed(void) { + return g_hasRandomSeed; +} + +void envGetRandomSeed(u64 out[2]) { + out[0] = g_randomSeed[0]; + out[1] = g_randomSeed[1]; +}