Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libc: Refine the arc4random_buf implementation #14509

Merged
merged 1 commit into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 3 additions & 32 deletions crypto/random_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,15 +508,10 @@ void up_randompool_initialize(void)
}

/****************************************************************************
* Name: arc4random_buf
* Name: up_rngbuf
*
* Description:
* Fill a buffer of arbitrary length with randomness. This is the
* preferred interface for getting random numbers. The traditional
* /dev/random approach is susceptible for things like the attacker
* exhausting file descriptors on purpose.
*
* Note that this function cannot fail, other than by asserting.
* Fill a buffer of arbitrary length with randomness.
*
* Input Parameters:
* bytes - Buffer for returned random bytes
Expand All @@ -527,33 +522,9 @@ void up_randompool_initialize(void)
*
****************************************************************************/

void arc4random_buf(FAR void *bytes, size_t nbytes)
void up_rngbuf(FAR void *bytes, size_t nbytes)
{
nxmutex_lock(&g_rng.rd_lock);
rng_buf_internal(bytes, nbytes);
nxmutex_unlock(&g_rng.rd_lock);
}

/****************************************************************************
* Name: arc4random
*
* Description:
* Returns a single 32-bit value. This is the preferred interface for
* getting random numbers. The traditional /dev/random approach is
* susceptible for things like the attacker exhausting file
* descriptors on purpose.
*
* Note that this function cannot fail, other than by asserting.
*
* Returned Value:
* a random 32-bit value.
*
****************************************************************************/

uint32_t arc4random(void)
{
uint32_t ret;

arc4random_buf(&ret, sizeof(ret));
return ret;
}
3 changes: 1 addition & 2 deletions drivers/crypto/dev_urandom.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,8 @@ static ssize_t devurand_read(FAR struct file *filep, FAR char *buffer,
#ifdef CONFIG_DEV_URANDOM_RANDOM_POOL
if (len > 0)
{
arc4random_buf(buffer, len);
up_rngbuf(buffer, len);
}

#else
size_t n;
uint32_t rnd;
Expand Down
9 changes: 2 additions & 7 deletions drivers/vhost/vhost-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <debug.h>
#include <errno.h>
#include <stdio.h>
#include <sys/random.h>
#include <stdlib.h>

#include <nuttx/kmalloc.h>
#include <nuttx/vhost/vhost.h>
Expand Down Expand Up @@ -99,12 +99,7 @@ static void vhost_rng_work(FAR void *arg)
}

spin_unlock_irqrestore(&priv->lock, flags);
ret = getrandom(buf, len, 0);
if (ret < 0)
{
vhosterr("getrandom failed, ret=%zd\n", ret);
ret = 0;
}
arc4random_buf(buf, len);

flags = spin_lock_irqsave(&priv->lock);
virtqueue_add_consumed_buffer(vq, idx, (uint32_t)ret);
Expand Down
10 changes: 10 additions & 0 deletions include/nuttx/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ void up_rngaddint(enum rnd_source_t kindof, int val);
void up_rngaddentropy(enum rnd_source_t kindof, FAR const uint32_t *buf,
size_t n);

/****************************************************************************
* Name: up_rngbuf
*
* Description:
* Fill a buffer of arbitrary length with randomness.
*
****************************************************************************/

void up_rngbuf(FAR void *bytes, size_t nbytes);

/****************************************************************************
* Name: up_rngreseed
*
Expand Down
2 changes: 0 additions & 2 deletions include/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,8 @@ double erand48(FAR unsigned short int xsubi[3]);
#define srandom(s) srand(s)
long random(void);

#ifdef CONFIG_CRYPTO_RANDOM_POOL
void arc4random_buf(FAR void *bytes, size_t nbytes);
uint32_t arc4random(void);
#endif

/* Environment variable support */

Expand Down
8 changes: 0 additions & 8 deletions include/sys/syscall_lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,6 @@ SYSCALL_LOOKUP(munmap, 2)
SYSCALL_LOOKUP(socketpair, 4)
#endif

/* The following is defined only if entropy pool random number generator
* is enabled.
*/

#ifdef CONFIG_CRYPTO_RANDOM_POOL
SYSCALL_LOOKUP(arc4random_buf, 2)
#endif

SYSCALL_LOOKUP(nanosleep, 2)

/* I/O event notification facility */
Expand Down
2 changes: 2 additions & 0 deletions libs/libc/libc.csv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"aio_suspend","aio.h","defined(CONFIG_FS_AIO)","int","FAR const struct aiocb * const []|FAR const struct aiocb * const *","int","FAR const struct timespec *"
"alarm","unistd.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","unsigned int","unsigned int"
"alphasort","dirent.h","","int","FAR const struct dirent **","FAR const struct dirent **"
"arc4random","stdlib.h","","uint32_t"
"arc4random_buf","stdlib.h","","void","FAR void *","size_t"
"asprintf","stdio.h","","int","FAR char **","FAR const IPTR char *","..."
"atof","stdlib.h","defined(CONFIG_HAVE_DOUBLE)","double","FAR const char *"
"atoi","stdlib.h","","int","FAR const char *"
Expand Down
1 change: 1 addition & 0 deletions libs/libc/stdlib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ set(SRCS
lib_wctomb.c
lib_mbstowcs.c
lib_wcstombs.c
lib_arc4random.c
lib_atexit.c)

if(CONFIG_PSEUDOTERM)
Expand Down
2 changes: 1 addition & 1 deletion libs/libc/stdlib/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ CSRCS += lib_strtoll.c lib_strtoul.c lib_strtoull.c lib_strtold.c
CSRCS += lib_checkbase.c lib_mktemp.c lib_mkstemp.c lib_mkdtemp.c
CSRCS += lib_aligned_alloc.c lib_posix_memalign.c lib_valloc.c lib_mblen.c
CSRCS += lib_mbtowc.c lib_wctomb.c lib_mbstowcs.c lib_wcstombs.c lib_atexit.c
CSRCS += lib_reallocarray.c
CSRCS += lib_reallocarray.c lib_arc4random.c

ifeq ($(CONFIG_PSEUDOTERM),y)
CSRCS += lib_ptsname.c lib_ptsnamer.c lib_unlockpt.c lib_openpty.c
Expand Down
83 changes: 71 additions & 12 deletions net/utils/net_getrandom.c → libs/libc/stdlib/lib_arc4random.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/****************************************************************************
* net/utils/net_getrandom.c
* libs/libc/stdlib/lib_arc4random.c
*
* SPDX-License-Identifier: Apache-2.0
*
Expand All @@ -24,44 +24,79 @@
* Included Files
****************************************************************************/

#include <nuttx/config.h>

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/random.h>

#include <nuttx/clock.h>
#include <nuttx/hashtable.h>

/****************************************************************************
* Private Functions
****************************************************************************/

#if defined(CONFIG_DEV_URANDOM) || defined(CONFIG_DEV_RANDOM)
static int getrandom_all(FAR void *buf, size_t size, int flags)
{
FAR char *tmp = buf;

while (size > 0)
{
ssize_t ret = getrandom(tmp, size, flags);
if (ret < 0)
{
if (get_errno() == EINTR)
{
continue;
}

return ret;
}

tmp += ret;
size -= ret;
}

return 0;
}
#endif

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: net_getrandom
* Name: arc4random_buf
*
* Description:
* Fill a buffer of arbitrary length with randomness. This function is
* guaranteed to be success.
* Fill a buffer of arbitrary length with randomness. This is the
* preferred interface for getting random numbers. The traditional
* /dev/random approach is susceptible for things like the attacker
* exhausting file descriptors on purpose.
*
* Note that this function cannot fail, other than by asserting.
*
* Input Parameters:
* bytes - Buffer for returned random bytes
* nbytes - Number of bytes requested.
*
* Returned Value:
* None
*
****************************************************************************/

void net_getrandom(FAR void *bytes, size_t nbytes)
void arc4random_buf(FAR void *bytes, size_t nbytes)
{
#if defined(CONFIG_DEV_URANDOM) || defined(CONFIG_DEV_RANDOM)
ssize_t ret = getrandom(bytes, nbytes, 0);

if (ret < 0)
if (getrandom_all(bytes, nbytes, GRND_RANDOM) >= 0)
{
ret = getrandom(bytes, nbytes, GRND_RANDOM);
return;
}

if (ret == nbytes)
if (getrandom_all(bytes, nbytes, 0) >= 0)
{
return;
}
Expand All @@ -82,3 +117,27 @@ void net_getrandom(FAR void *bytes, size_t nbytes)
bytes = (FAR uint8_t *)bytes + ncopy;
}
}

/****************************************************************************
* Name: arc4random
*
* Description:
* Returns a single 32-bit value. This is the preferred interface for
* getting random numbers. The traditional /dev/random approach is
* susceptible for things like the attacker exhausting file
* descriptors on purpose.
*
* Note that this function cannot fail, other than by asserting.
*
* Returned Value:
* a random 32-bit value.
*
****************************************************************************/

uint32_t arc4random(void)
{
uint32_t ret;

arc4random_buf(&ret, sizeof(ret));
return ret;
}
22 changes: 2 additions & 20 deletions libs/libc/unistd/lib_getentropy.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
* Included Files
****************************************************************************/

#include <sys/random.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

/****************************************************************************
Expand Down Expand Up @@ -56,30 +56,12 @@

int getentropy(FAR void *buffer, size_t length)
{
FAR char *pos = buffer;

if (length > 256)
{
set_errno(EIO);
return -1;
}

while (length > 0)
{
int ret = getrandom(pos, length, 0);
if (ret < 0)
{
if (get_errno() == EINTR)
{
continue;
}

return ret;
}

pos += ret;
length -= ret;
}

arc4random_buf(buffer, length);
return 0;
}
48 changes: 1 addition & 47 deletions libs/libc/uuid/lib_uuid_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,10 @@
* Included Files
****************************************************************************/

#include <sys/random.h>
#include <errno.h>
#include <stdlib.h>
#include <uuid.h>

/****************************************************************************
* Private Functions
****************************************************************************/

static int uuid_getrandom(FAR void *buf, size_t size, int flags)
{
FAR char *tmp = buf;

while (size > 0)
{
ssize_t ret = getrandom(tmp, size, flags);
if (ret < 0)
{
if (get_errno() == EINTR)
{
continue;
}

return ret;
}

tmp += ret;
size -= ret;
}

return 0;
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand All @@ -74,24 +45,7 @@ static int uuid_getrandom(FAR void *buf, size_t size, int flags)

void uuid_create(FAR uuid_t *u, FAR uint32_t *status)
{
int ret;

ret = uuid_getrandom(u, sizeof(uuid_t), GRND_RANDOM);
if (ret < 0)
{
ret = uuid_getrandom(u, sizeof(uuid_t), 0);
}

if (ret < 0)
{
FAR unsigned long *beg = (FAR unsigned long *)u;
FAR unsigned long *end = (FAR unsigned long *)(u + 1);

while (beg < end)
{
*beg++ = rand();
}
}
arc4random_buf(u, sizeof(uuid_t));

u->clock_seq_hi_and_reserved &= ~(1 << 6);
u->clock_seq_hi_and_reserved |= (1 << 7);
Expand Down
Loading
Loading