diff --git a/CMakeLists.txt b/CMakeLists.txt index 84f10fc16..2c7ee12f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -485,6 +485,7 @@ if(NINTENDO_SWITCH) Source/platform/switch/network.cpp Source/platform/switch/keyboard.cpp Source/platform/switch/docking.cpp + Source/platform/switch/random.cpp Source/platform/switch/asio/net/if.c Source/platform/switch/asio/sys/signal.c) endif() diff --git a/Source/main.cpp b/Source/main.cpp index 258613052..9c2c7866c 100644 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -1,6 +1,7 @@ #include #ifdef __SWITCH__ #include "platform/switch/network.h" +#include "platform/switch/random.hpp" #endif #ifdef __3DS__ #include "platform/ctr/system.h" @@ -26,6 +27,7 @@ int main(int argc, char **argv) { #ifdef __SWITCH__ switch_enable_network(); + randombytes_switchrandom_init(); #endif #ifdef __3DS__ ctr_sys_init(); diff --git a/Source/platform/switch/random.cpp b/Source/platform/switch/random.cpp new file mode 100644 index 000000000..6c16d228c --- /dev/null +++ b/Source/platform/switch/random.cpp @@ -0,0 +1,54 @@ +#include +#include + +extern "C" { +#include +#include +} + +static const char *randombytes_switchrandom_implementation_name() +{ + return "switchrandom"; +} + +static bool randombytes_switchrandom_tryfill(void *const buf, const size_t size) +{ + Result res; + Service *csrngService = csrngGetServiceSession(); + if (!serviceIsActive(csrngService)) { + res = csrngInitialize(); + if (!R_SUCCEEDED(res)) + return false; + } + res = csrngGetRandomBytes(buf, size); + return R_SUCCEEDED(res); +} + +static uint32_t randombytes_switchrandom() +{ + uint32_t num; + if (!randombytes_switchrandom_tryfill(&num, sizeof(uint32_t))) + sodium_misuse(); + return num; +} + +static void randombytes_switchrandom_buf(void *const buf, const size_t size) +{ + if (!randombytes_switchrandom_tryfill(buf, size)) + sodium_misuse(); +} + +struct randombytes_implementation randombytes_switchrandom_implementation = { + randombytes_switchrandom_implementation_name, + randombytes_switchrandom, + nullptr, + nullptr, + randombytes_switchrandom_buf, + nullptr +}; + +void randombytes_switchrandom_init() +{ + randombytes_set_implementation(&randombytes_switchrandom_implementation); + atexit(csrngExit); +} diff --git a/Source/platform/switch/random.hpp b/Source/platform/switch/random.hpp new file mode 100644 index 000000000..5acd4d92b --- /dev/null +++ b/Source/platform/switch/random.hpp @@ -0,0 +1,2 @@ +#pragma once +void randombytes_switchrandom_init();