posix: Introduce getentropy() function
The function writes random data to the provided buffer. Maximum permitted buffer size is 256 bytes. On success the function returns 0, otherwise it returns -1 and sets errno to appropriate value. Signed-off-by: Patryk Duda <patrykd@google.com>
This commit is contained in:
parent
1542140e4e
commit
ef258166ba
|
@ -263,6 +263,7 @@ extern char *optarg;
|
||||||
extern int opterr, optind, optopt;
|
extern int opterr, optind, optopt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int getentropy(void *buffer, size_t length);
|
||||||
pid_t getpid(void);
|
pid_t getpid(void);
|
||||||
unsigned sleep(unsigned int seconds);
|
unsigned sleep(unsigned int seconds);
|
||||||
int usleep(useconds_t useconds);
|
int usleep(useconds_t useconds);
|
||||||
|
|
|
@ -36,6 +36,7 @@ zephyr_library()
|
||||||
add_subdirectory_ifdef(CONFIG_GETOPT getopt)
|
add_subdirectory_ifdef(CONFIG_GETOPT getopt)
|
||||||
zephyr_library_sources_ifdef(CONFIG_EVENTFD eventfd.c)
|
zephyr_library_sources_ifdef(CONFIG_EVENTFD eventfd.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_FNMATCH fnmatch.c)
|
zephyr_library_sources_ifdef(CONFIG_FNMATCH fnmatch.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_GETENTROPY getentropy.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_POSIX_API perror.c)
|
zephyr_library_sources_ifdef(CONFIG_POSIX_API perror.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_POSIX_ASYNCHRONOUS_IO aio.c)
|
zephyr_library_sources_ifdef(CONFIG_POSIX_ASYNCHRONOUS_IO aio.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK clock.c)
|
zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK clock.c)
|
||||||
|
|
|
@ -35,6 +35,7 @@ rsource "Kconfig.eventfd"
|
||||||
rsource "Kconfig.fdtable"
|
rsource "Kconfig.fdtable"
|
||||||
rsource "Kconfig.fnmatch"
|
rsource "Kconfig.fnmatch"
|
||||||
rsource "Kconfig.fs"
|
rsource "Kconfig.fs"
|
||||||
|
rsource "Kconfig.getentropy"
|
||||||
rsource "Kconfig.getopt"
|
rsource "Kconfig.getopt"
|
||||||
rsource "Kconfig.key"
|
rsource "Kconfig.key"
|
||||||
rsource "Kconfig.mqueue"
|
rsource "Kconfig.mqueue"
|
||||||
|
|
14
lib/posix/options/Kconfig.getentropy
Normal file
14
lib/posix/options/Kconfig.getentropy
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Copyright (c) 2024 Google LLC
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
DT_CHOSEN_ZEPHYR_ENTROPY := zephyr,entropy
|
||||||
|
|
||||||
|
config GETENTROPY
|
||||||
|
bool "Support for getentropy"
|
||||||
|
depends on !NATIVE_APPLICATION
|
||||||
|
select NATIVE_LIBC_INCOMPATIBLE
|
||||||
|
depends on ENTROPY_HAS_DRIVER
|
||||||
|
depends on $(dt_chosen_enabled,$(DT_CHOSEN_ZEPHYR_ENTROPY))
|
||||||
|
help
|
||||||
|
Enable support for getentropy() function.
|
45
lib/posix/options/getentropy.c
Normal file
45
lib/posix/options/getentropy.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Google LLC
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <zephyr/drivers/entropy.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/posix/unistd.h>
|
||||||
|
|
||||||
|
#define ENTROPY_NODE DT_CHOSEN(zephyr_entropy)
|
||||||
|
|
||||||
|
int getentropy(void *buffer, size_t length)
|
||||||
|
{
|
||||||
|
const struct device * const entropy = DEVICE_DT_GET(ENTROPY_NODE);
|
||||||
|
|
||||||
|
if (!buffer) {
|
||||||
|
errno = EFAULT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 256) {
|
||||||
|
errno = EIO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_is_ready(entropy)) {
|
||||||
|
errno = EIO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getentropy() uses size_t to represent buffer size, but Zephyr uses
|
||||||
|
* uint16_t. The length check above allows us to safely cast without
|
||||||
|
* overflow.
|
||||||
|
*/
|
||||||
|
if (entropy_get_entropy(entropy, buffer, (uint16_t)length)) {
|
||||||
|
errno = EIO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
10
tests/posix/getentropy/CMakeLists.txt
Normal file
10
tests/posix/getentropy/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Copyright (c) 2024 Google LLC
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(getentropy)
|
||||||
|
|
||||||
|
FILE(GLOB app_sources src/*.c)
|
||||||
|
target_sources(app PRIVATE ${app_sources})
|
4
tests/posix/getentropy/prj.conf
Normal file
4
tests/posix/getentropy/prj.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
CONFIG_ENTROPY_GENERATOR=y
|
||||||
|
CONFIG_GETENTROPY=y
|
||||||
|
CONFIG_POSIX_API=y
|
||||||
|
CONFIG_ZTEST=y
|
57
tests/posix/getentropy/src/main.c
Normal file
57
tests/posix/getentropy/src/main.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Google LLC
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/ztest.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
ZTEST(getentropy_test_suite, test_getentropy_too_large)
|
||||||
|
{
|
||||||
|
uint8_t buf[256 + 1] = { 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = getentropy(buf, sizeof(buf));
|
||||||
|
zassert_equal(ret, -1);
|
||||||
|
zassert_equal(errno, EIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZTEST(getentropy_test_suite, test_getentropy_null_buffer)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = getentropy(NULL, 0);
|
||||||
|
zassert_equal(ret, -1);
|
||||||
|
zassert_equal(errno, EFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZTEST(getentropy_test_suite, test_getentropy_max_size)
|
||||||
|
{
|
||||||
|
uint8_t buf[256] = { 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = getentropy(buf, sizeof(buf));
|
||||||
|
zassert_equal(ret, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZTEST(getentropy_test_suite, test_getentropy)
|
||||||
|
{
|
||||||
|
uint8_t zero[16] = { 0 };
|
||||||
|
uint8_t buf1[16];
|
||||||
|
uint8_t buf2[16];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = getentropy(buf1, sizeof(buf1));
|
||||||
|
zassert_equal(ret, 0);
|
||||||
|
|
||||||
|
ret = getentropy(buf2, sizeof(buf2));
|
||||||
|
zassert_equal(ret, 0);
|
||||||
|
|
||||||
|
zassert_true(memcmp(buf1, zero, sizeof(zero)) != 0);
|
||||||
|
zassert_true(memcmp(buf2, zero, sizeof(zero)) != 0);
|
||||||
|
zassert_true(memcmp(buf1, buf2, sizeof(buf1)) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZTEST_SUITE(getentropy_test_suite, NULL, NULL, NULL, NULL, NULL);
|
20
tests/posix/getentropy/testcase.yaml
Normal file
20
tests/posix/getentropy/testcase.yaml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
common:
|
||||||
|
filter: dt_chosen_enabled("zephyr,entropy") and CONFIG_ENTROPY_HAS_DRIVER and
|
||||||
|
not CONFIG_NATIVE_LIBC
|
||||||
|
integration_platforms:
|
||||||
|
- native_sim
|
||||||
|
tags:
|
||||||
|
- posix
|
||||||
|
- getentropy
|
||||||
|
tests:
|
||||||
|
portability.posix.getentropy: {}
|
||||||
|
portability.posix.getentropy.newlib:
|
||||||
|
filter: CONFIG_NEWLIB_LIBC_SUPPORTED
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_NEWLIB_LIBC=y
|
||||||
|
- CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=4096
|
||||||
|
portability.posix.getentropy.picolibc:
|
||||||
|
tags: picolibc
|
||||||
|
filter: CONFIG_PICOLIBC_SUPPORTED
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_PICOLIBC=y
|
Loading…
Reference in a new issue