From f8e020b1d7859e074a08c654328f2808036b4c72 Mon Sep 17 00:00:00 2001 From: Alexey Gerenkov Date: Thu, 3 Aug 2023 16:25:53 +0300 Subject: [PATCH] feat(newlib): Implement getentropy() function Closes https://github.com/espressif/esp-idf/issues/11963 --- components/cxx/CMakeLists.txt | 11 ++++--- components/newlib/CMakeLists.txt | 1 + components/newlib/getentropy.c | 30 +++++++++++++++++++ .../newlib/platform_include/sys/unistd.h | 1 + docs/en/api-reference/system/random.rst | 19 ++++++++++++ 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 components/newlib/getentropy.c diff --git a/components/cxx/CMakeLists.txt b/components/cxx/CMakeLists.txt index 6841da161a..864c4386b0 100644 --- a/components/cxx/CMakeLists.txt +++ b/components/cxx/CMakeLists.txt @@ -53,15 +53,18 @@ target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxa_guard_dummy") # Furthermore, force libcxx to appear later than libgcc because some libgcc unwind code is wrapped, if C++ # exceptions are disabled. libcxx (this component) provides the unwind code wrappers. # This is to prevent linking of libgcc's unwind code which considerably increases the binary size. +# Also force libnewlib to appear later than libstdc++ in link line since libstdc++ depends on +# some functions in libnewlib, e.g. getentropy(). idf_component_get_property(pthread pthread COMPONENT_LIB) +idf_component_get_property(newlib newlib COMPONENT_LIB) idf_component_get_property(cxx cxx COMPONENT_LIB) -add_library(stdcpp_pthread INTERFACE) +add_library(stdcpp_deps INTERFACE) if(CMAKE_C_COMPILER_ID MATCHES "Clang") - target_link_libraries(stdcpp_pthread INTERFACE stdc++ c $) + target_link_libraries(stdcpp_deps INTERFACE stdc++ c $ $) else() - target_link_libraries(stdcpp_pthread INTERFACE stdc++ $) + target_link_libraries(stdcpp_deps INTERFACE stdc++ $ $) endif() -target_link_libraries(${COMPONENT_LIB} PUBLIC stdcpp_pthread) +target_link_libraries(${COMPONENT_LIB} PUBLIC stdcpp_deps) add_library(libgcc_cxx INTERFACE) target_link_libraries(libgcc_cxx INTERFACE ${CONFIG_COMPILER_RT_LIB_NAME} $) target_link_libraries(${COMPONENT_LIB} PUBLIC libgcc_cxx) diff --git a/components/newlib/CMakeLists.txt b/components/newlib/CMakeLists.txt index 9e1cd22582..42c5194ab1 100644 --- a/components/newlib/CMakeLists.txt +++ b/components/newlib/CMakeLists.txt @@ -12,6 +12,7 @@ set(srcs "poll.c" "pthread.c" "random.c" + "getentropy.c" "reent_init.c" "newlib_init.c" "syscalls.c" diff --git a/components/newlib/getentropy.c b/components/newlib/getentropy.c new file mode 100644 index 0000000000..e375cb9763 --- /dev/null +++ b/components/newlib/getentropy.c @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int getentropy(void *buffer, size_t length) +{ + ssize_t ret; + + if (buffer == NULL) { + errno = EFAULT; + return -1; + } + + if (length > 256) { + errno = EIO; + return -1; + } + + ret = getrandom(buffer, length, 0); + if (ret == -1) { + return -1; + } + + return 0; +} diff --git a/components/newlib/platform_include/sys/unistd.h b/components/newlib/platform_include/sys/unistd.h index 0cb4a14db7..483fd3cca8 100644 --- a/components/newlib/platform_include/sys/unistd.h +++ b/components/newlib/platform_include/sys/unistd.h @@ -16,6 +16,7 @@ extern "C" { int truncate(const char *, off_t __length); int gethostname(char *__name, size_t __len); +int getentropy(void *buffer, size_t length); #ifdef __cplusplus } diff --git a/docs/en/api-reference/system/random.rst b/docs/en/api-reference/system/random.rst index da4cb1e321..b9b003cb86 100644 --- a/docs/en/api-reference/system/random.rst +++ b/docs/en/api-reference/system/random.rst @@ -62,5 +62,24 @@ The ``flags`` argument is ignored, this function is always non-blocking but the Return value is -1 (with ``errno`` set to ``EFAULT``) if the ``buf`` argument is NULL, and equal to ``buflen`` otherwise. +getentropy +---------- + +A compatible version of the Linux ``getentropy()`` function is also provided for ease of porting: + +.. code-block:: c + + #include + + int getentropy(void *buffer, size_t length); + +This function is implemented by calling :cpp:func:`getrandom` internally. + +Strength of any random numbers is dependent on the same conditions described above. + +Return value is 0 on success and -1 otherwise with ``errno`` set to: + - ``EFAULT`` if the ``buffer`` argument is NULL. + - ``EIO`` if the ``length`` is more then 256. + .. _Dieharder: https://webhome.phy.duke.edu/~rgb/General/dieharder.php