Skip to content

Commit 32784b0

Browse files
xiaoxiang781216Alan C. Assis
authored andcommitted
libc: Refine the arc4random_buf implementation
fill the buffer with getrandom instead random pool and move the implementation to from crypto to libc Signed-off-by: Xiang Xiao <[email protected]>
1 parent b5e5cdd commit 32784b0

File tree

17 files changed

+103
-154
lines changed

17 files changed

+103
-154
lines changed

crypto/random_pool.c

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -508,15 +508,10 @@ void up_randompool_initialize(void)
508508
}
509509

510510
/****************************************************************************
511-
* Name: arc4random_buf
511+
* Name: up_rngbuf
512512
*
513513
* Description:
514-
* Fill a buffer of arbitrary length with randomness. This is the
515-
* preferred interface for getting random numbers. The traditional
516-
* /dev/random approach is susceptible for things like the attacker
517-
* exhausting file descriptors on purpose.
518-
*
519-
* Note that this function cannot fail, other than by asserting.
514+
* Fill a buffer of arbitrary length with randomness.
520515
*
521516
* Input Parameters:
522517
* bytes - Buffer for returned random bytes
@@ -527,33 +522,9 @@ void up_randompool_initialize(void)
527522
*
528523
****************************************************************************/
529524

530-
void arc4random_buf(FAR void *bytes, size_t nbytes)
525+
void up_rngbuf(FAR void *bytes, size_t nbytes)
531526
{
532527
nxmutex_lock(&g_rng.rd_lock);
533528
rng_buf_internal(bytes, nbytes);
534529
nxmutex_unlock(&g_rng.rd_lock);
535530
}
536-
537-
/****************************************************************************
538-
* Name: arc4random
539-
*
540-
* Description:
541-
* Returns a single 32-bit value. This is the preferred interface for
542-
* getting random numbers. The traditional /dev/random approach is
543-
* susceptible for things like the attacker exhausting file
544-
* descriptors on purpose.
545-
*
546-
* Note that this function cannot fail, other than by asserting.
547-
*
548-
* Returned Value:
549-
* a random 32-bit value.
550-
*
551-
****************************************************************************/
552-
553-
uint32_t arc4random(void)
554-
{
555-
uint32_t ret;
556-
557-
arc4random_buf(&ret, sizeof(ret));
558-
return ret;
559-
}

drivers/crypto/dev_urandom.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,8 @@ static ssize_t devurand_read(FAR struct file *filep, FAR char *buffer,
148148
#ifdef CONFIG_DEV_URANDOM_RANDOM_POOL
149149
if (len > 0)
150150
{
151-
arc4random_buf(buffer, len);
151+
up_rngbuf(buffer, len);
152152
}
153-
154153
#else
155154
size_t n;
156155
uint32_t rnd;

drivers/vhost/vhost-rng.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <debug.h>
2626
#include <errno.h>
2727
#include <stdio.h>
28-
#include <sys/random.h>
28+
#include <stdlib.h>
2929

3030
#include <nuttx/kmalloc.h>
3131
#include <nuttx/vhost/vhost.h>
@@ -99,12 +99,7 @@ static void vhost_rng_work(FAR void *arg)
9999
}
100100

101101
spin_unlock_irqrestore(&priv->lock, flags);
102-
ret = getrandom(buf, len, 0);
103-
if (ret < 0)
104-
{
105-
vhosterr("getrandom failed, ret=%zd\n", ret);
106-
ret = 0;
107-
}
102+
arc4random_buf(buf, len);
108103

109104
flags = spin_lock_irqsave(&priv->lock);
110105
virtqueue_add_consumed_buffer(vq, idx, (uint32_t)ret);

include/nuttx/random.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ void up_rngaddint(enum rnd_source_t kindof, int val);
131131
void up_rngaddentropy(enum rnd_source_t kindof, FAR const uint32_t *buf,
132132
size_t n);
133133

134+
/****************************************************************************
135+
* Name: up_rngbuf
136+
*
137+
* Description:
138+
* Fill a buffer of arbitrary length with randomness.
139+
*
140+
****************************************************************************/
141+
142+
void up_rngbuf(FAR void *bytes, size_t nbytes);
143+
134144
/****************************************************************************
135145
* Name: up_rngreseed
136146
*

include/stdlib.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,8 @@ double erand48(FAR unsigned short int xsubi[3]);
152152
#define srandom(s) srand(s)
153153
long random(void);
154154

155-
#ifdef CONFIG_CRYPTO_RANDOM_POOL
156155
void arc4random_buf(FAR void *bytes, size_t nbytes);
157156
uint32_t arc4random(void);
158-
#endif
159157

160158
/* Environment variable support */
161159

include/sys/syscall_lookup.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -384,14 +384,6 @@ SYSCALL_LOOKUP(munmap, 2)
384384
SYSCALL_LOOKUP(socketpair, 4)
385385
#endif
386386

387-
/* The following is defined only if entropy pool random number generator
388-
* is enabled.
389-
*/
390-
391-
#ifdef CONFIG_CRYPTO_RANDOM_POOL
392-
SYSCALL_LOOKUP(arc4random_buf, 2)
393-
#endif
394-
395387
SYSCALL_LOOKUP(nanosleep, 2)
396388

397389
/* I/O event notification facility */

libs/libc/libc.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"aio_suspend","aio.h","defined(CONFIG_FS_AIO)","int","FAR const struct aiocb * const []|FAR const struct aiocb * const *","int","FAR const struct timespec *"
1515
"alarm","unistd.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","unsigned int","unsigned int"
1616
"alphasort","dirent.h","","int","FAR const struct dirent **","FAR const struct dirent **"
17+
"arc4random","stdlib.h","","uint32_t"
18+
"arc4random_buf","stdlib.h","","void","FAR void *","size_t"
1719
"asprintf","stdio.h","","int","FAR char **","FAR const IPTR char *","..."
1820
"atof","stdlib.h","defined(CONFIG_HAVE_DOUBLE)","double","FAR const char *"
1921
"atoi","stdlib.h","","int","FAR const char *"

libs/libc/stdlib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ set(SRCS
6161
lib_wctomb.c
6262
lib_mbstowcs.c
6363
lib_wcstombs.c
64+
lib_arc4random.c
6465
lib_atexit.c)
6566

6667
if(CONFIG_PSEUDOTERM)

libs/libc/stdlib/Make.defs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ CSRCS += lib_strtoll.c lib_strtoul.c lib_strtoull.c lib_strtold.c
3030
CSRCS += lib_checkbase.c lib_mktemp.c lib_mkstemp.c lib_mkdtemp.c
3131
CSRCS += lib_aligned_alloc.c lib_posix_memalign.c lib_valloc.c lib_mblen.c
3232
CSRCS += lib_mbtowc.c lib_wctomb.c lib_mbstowcs.c lib_wcstombs.c lib_atexit.c
33-
CSRCS += lib_reallocarray.c
33+
CSRCS += lib_reallocarray.c lib_arc4random.c
3434

3535
ifeq ($(CONFIG_PSEUDOTERM),y)
3636
CSRCS += lib_ptsname.c lib_ptsnamer.c lib_unlockpt.c lib_openpty.c

net/utils/net_getrandom.c renamed to libs/libc/stdlib/lib_arc4random.c

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/****************************************************************************
2-
* net/utils/net_getrandom.c
2+
* libs/libc/stdlib/lib_arc4random.c
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -24,44 +24,79 @@
2424
* Included Files
2525
****************************************************************************/
2626

27-
#include <nuttx/config.h>
28-
27+
#include <errno.h>
2928
#include <stdint.h>
29+
#include <stdlib.h>
3030
#include <string.h>
3131
#include <sys/param.h>
3232
#include <sys/random.h>
3333

3434
#include <nuttx/clock.h>
3535
#include <nuttx/hashtable.h>
3636

37+
/****************************************************************************
38+
* Private Functions
39+
****************************************************************************/
40+
41+
#if defined(CONFIG_DEV_URANDOM) || defined(CONFIG_DEV_RANDOM)
42+
static int getrandom_all(FAR void *buf, size_t size, int flags)
43+
{
44+
FAR char *tmp = buf;
45+
46+
while (size > 0)
47+
{
48+
ssize_t ret = getrandom(tmp, size, flags);
49+
if (ret < 0)
50+
{
51+
if (get_errno() == EINTR)
52+
{
53+
continue;
54+
}
55+
56+
return ret;
57+
}
58+
59+
tmp += ret;
60+
size -= ret;
61+
}
62+
63+
return 0;
64+
}
65+
#endif
66+
3767
/****************************************************************************
3868
* Public Functions
3969
****************************************************************************/
4070

4171
/****************************************************************************
42-
* Name: net_getrandom
72+
* Name: arc4random_buf
4373
*
4474
* Description:
45-
* Fill a buffer of arbitrary length with randomness. This function is
46-
* guaranteed to be success.
75+
* Fill a buffer of arbitrary length with randomness. This is the
76+
* preferred interface for getting random numbers. The traditional
77+
* /dev/random approach is susceptible for things like the attacker
78+
* exhausting file descriptors on purpose.
79+
*
80+
* Note that this function cannot fail, other than by asserting.
4781
*
4882
* Input Parameters:
4983
* bytes - Buffer for returned random bytes
5084
* nbytes - Number of bytes requested.
5185
*
86+
* Returned Value:
87+
* None
88+
*
5289
****************************************************************************/
5390

54-
void net_getrandom(FAR void *bytes, size_t nbytes)
91+
void arc4random_buf(FAR void *bytes, size_t nbytes)
5592
{
5693
#if defined(CONFIG_DEV_URANDOM) || defined(CONFIG_DEV_RANDOM)
57-
ssize_t ret = getrandom(bytes, nbytes, 0);
58-
59-
if (ret < 0)
94+
if (getrandom_all(bytes, nbytes, GRND_RANDOM) >= 0)
6095
{
61-
ret = getrandom(bytes, nbytes, GRND_RANDOM);
96+
return;
6297
}
6398

64-
if (ret == nbytes)
99+
if (getrandom_all(bytes, nbytes, 0) >= 0)
65100
{
66101
return;
67102
}
@@ -82,3 +117,27 @@ void net_getrandom(FAR void *bytes, size_t nbytes)
82117
bytes = (FAR uint8_t *)bytes + ncopy;
83118
}
84119
}
120+
121+
/****************************************************************************
122+
* Name: arc4random
123+
*
124+
* Description:
125+
* Returns a single 32-bit value. This is the preferred interface for
126+
* getting random numbers. The traditional /dev/random approach is
127+
* susceptible for things like the attacker exhausting file
128+
* descriptors on purpose.
129+
*
130+
* Note that this function cannot fail, other than by asserting.
131+
*
132+
* Returned Value:
133+
* a random 32-bit value.
134+
*
135+
****************************************************************************/
136+
137+
uint32_t arc4random(void)
138+
{
139+
uint32_t ret;
140+
141+
arc4random_buf(&ret, sizeof(ret));
142+
return ret;
143+
}

0 commit comments

Comments
 (0)