@@ -438,23 +438,17 @@ random_init(int argc, VALUE *argv, VALUE obj)
438438# define USE_DEV_URANDOM 0
439439#endif
440440
441- #ifdef HAVE_GETENTROPY
442- # define MAX_SEED_LEN_PER_READ 256
443- static int
444- fill_random_bytes_urandom (void * seed , size_t size )
445- {
446- unsigned char * p = (unsigned char * )seed ;
447- while (size ) {
448- size_t len = size < MAX_SEED_LEN_PER_READ ? size : MAX_SEED_LEN_PER_READ ;
449- if (getentropy (p , len ) != 0 ) {
450- return -1 ;
451- }
452- p += len ;
453- size -= len ;
454- }
455- return 0 ;
456- }
457- #elif USE_DEV_URANDOM
441+ #if ! defined HAVE_GETRANDOM && defined __linux__ && defined __NR_getrandom
442+ # ifndef GRND_NONBLOCK
443+ # define GRND_NONBLOCK 0x0001 /* not defined in musl libc */
444+ # endif
445+ # define getrandom (ptr , size , flags ) \
446+ (ssize_t)syscall(__NR_getrandom, (ptr), (size), (flags))
447+ # define HAVE_GETRANDOM 1
448+ #endif
449+
450+ /* fill random bytes by reading random device directly */
451+ #if USE_DEV_URANDOM
458452static int
459453fill_random_bytes_urandom (void * seed , size_t size )
460454{
@@ -494,15 +488,7 @@ fill_random_bytes_urandom(void *seed, size_t size)
494488# define fill_random_bytes_urandom (seed , size ) -1
495489#endif
496490
497- #if ! defined HAVE_GETRANDOM && defined __linux__ && defined __NR_getrandom
498- # ifndef GRND_NONBLOCK
499- # define GRND_NONBLOCK 0x0001 /* not defined in musl libc */
500- # endif
501- # define getrandom (ptr , size , flags ) \
502- (ssize_t)syscall(__NR_getrandom, (ptr), (size), (flags))
503- # define HAVE_GETRANDOM 1
504- #endif
505-
491+ /* fill random bytes by library */
506492#if 0
507493#elif defined MAC_OS_X_VERSION_10_7 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
508494
@@ -520,7 +506,7 @@ fill_random_bytes_urandom(void *seed, size_t size)
520506# endif
521507
522508static int
523- fill_random_bytes_syscall (void * seed , size_t size , int unused )
509+ fill_random_bytes_lib (void * seed , size_t size )
524510{
525511#if USE_COMMON_RANDOM
526512 CCRNGStatus status = CCRandomGenerateBytes (seed , size );
@@ -549,7 +535,7 @@ fill_random_bytes_syscall(void *seed, size_t size, int unused)
549535}
550536#elif defined(HAVE_ARC4RANDOM_BUF )
551537static int
552- fill_random_bytes_syscall (void * buf , size_t size , int unused )
538+ fill_random_bytes_lib (void * buf , size_t size )
553539{
554540#if (defined(__OpenBSD__ ) && OpenBSD >= 201411 ) || \
555541 (defined(__NetBSD__ ) && __NetBSD_Version__ >= 700000000 ) || \
@@ -638,11 +624,17 @@ fill_random_bytes_bcrypt(void *seed, size_t size)
638624}
639625
640626static int
641- fill_random_bytes_syscall (void * seed , size_t size , int unused )
627+ fill_random_bytes_lib (void * seed , size_t size )
642628{
643629 if (fill_random_bytes_bcrypt (seed , size ) == 0 ) return 0 ;
644630 return fill_random_bytes_crypt (seed , size );
645631}
632+ #else
633+ # define fill_random_bytes_lib (seed , size ) -1
634+ #endif
635+
636+ /* fill random bytes by dedicated syscall */
637+ #if 0
646638#elif defined HAVE_GETRANDOM
647639static int
648640fill_random_bytes_syscall (void * seed , size_t size , int need_secure )
@@ -666,6 +658,31 @@ fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
666658 }
667659 return -1 ;
668660}
661+ #elif defined(HAVE_GETENTROPY )
662+ /*
663+ * The Open Group Base Specifications Issue 8 - IEEE Std 1003.1-2024
664+ * https://pubs.opengroup.org/onlinepubs/9799919799/functions/getentropy.html
665+ *
666+ * NOTE: `getentropy`(3) on Linux is implemented using `getrandom`(2),
667+ * prefer the latter over this if both are defined.
668+ */
669+ #ifndef GETENTROPY_MAX
670+ # define GETENTROPY_MAX 256
671+ #endif
672+ static int
673+ fill_random_bytes_syscall (void * seed , size_t size , int need_secure )
674+ {
675+ unsigned char * p = (unsigned char * )seed ;
676+ while (size ) {
677+ size_t len = size < GETENTROPY_MAX ? size : GETENTROPY_MAX ;
678+ if (getentropy (p , len ) != 0 ) {
679+ return -1 ;
680+ }
681+ p += len ;
682+ size -= len ;
683+ }
684+ return 0 ;
685+ }
669686#else
670687# define fill_random_bytes_syscall (seed , size , need_secure ) -1
671688#endif
@@ -675,6 +692,7 @@ ruby_fill_random_bytes(void *seed, size_t size, int need_secure)
675692{
676693 int ret = fill_random_bytes_syscall (seed , size , need_secure );
677694 if (ret == 0 ) return ret ;
695+ if (fill_random_bytes_lib (seed , size ) == 0 ) return 0 ;
678696 return fill_random_bytes_urandom (seed , size );
679697}
680698
0 commit comments