@@ -447,30 +447,8 @@ random_init(int argc, VALUE *argv, VALUE obj)
447447# define HAVE_GETRANDOM 1
448448#endif
449449
450- #if defined(HAVE_GETENTROPY ) && !defined(HAVE_GETRANDOM )
451- /*
452- * In the case both `getentropy` and `getrandom` are defined, assume
453- * that the former is implemented using the latter, and use the latter
454- * in the `syscall` version.
455- * Otherwise, in the case only `getentropy`, assume it is defined as
456- * the replacement for security purpose of `/dev/urandom`.
457- */
458- # define MAX_SEED_LEN_PER_READ 256
459- static int
460- fill_random_bytes_urandom (void * seed , size_t size )
461- {
462- unsigned char * p = (unsigned char * )seed ;
463- while (size ) {
464- size_t len = size < MAX_SEED_LEN_PER_READ ? size : MAX_SEED_LEN_PER_READ ;
465- if (getentropy (p , len ) != 0 ) {
466- return -1 ;
467- }
468- p += len ;
469- size -= len ;
470- }
471- return 0 ;
472- }
473- #elif USE_DEV_URANDOM
450+ /* fill random bytes by reading random device directly */
451+ #if USE_DEV_URANDOM
474452static int
475453fill_random_bytes_urandom (void * seed , size_t size )
476454{
@@ -510,6 +488,7 @@ fill_random_bytes_urandom(void *seed, size_t size)
510488# define fill_random_bytes_urandom (seed , size ) -1
511489#endif
512490
491+ /* fill random bytes by library */
513492#if 0
514493#elif defined MAC_OS_X_VERSION_10_7 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
515494
@@ -527,7 +506,7 @@ fill_random_bytes_urandom(void *seed, size_t size)
527506# endif
528507
529508static int
530- fill_random_bytes_syscall (void * seed , size_t size , int unused )
509+ fill_random_bytes_lib (void * seed , size_t size )
531510{
532511#if USE_COMMON_RANDOM
533512 CCRNGStatus status = CCRandomGenerateBytes (seed , size );
@@ -560,7 +539,7 @@ fill_random_bytes_syscall(void *seed, size_t size, int unused)
560539 (defined(__FreeBSD__ ) && __FreeBSD_version >= 1200079 ))
561540// [Bug #15039] arc4random_buf(3) should used only if we know it is fork-safe
562541static int
563- fill_random_bytes_syscall (void * buf , size_t size , int unused )
542+ fill_random_bytes_lib (void * buf , size_t size )
564543{
565544 arc4random_buf (buf , size );
566545 return 0 ;
@@ -643,11 +622,17 @@ fill_random_bytes_bcrypt(void *seed, size_t size)
643622}
644623
645624static int
646- fill_random_bytes_syscall (void * seed , size_t size , int unused )
625+ fill_random_bytes_lib (void * seed , size_t size )
647626{
648627 if (fill_random_bytes_bcrypt (seed , size ) == 0 ) return 0 ;
649628 return fill_random_bytes_crypt (seed , size );
650629}
630+ #else
631+ # define fill_random_bytes_lib (seed , size ) -1
632+ #endif
633+
634+ /* fill random bytes by dedicated syscall */
635+ #if 0
651636#elif defined HAVE_GETRANDOM
652637static int
653638fill_random_bytes_syscall (void * seed , size_t size , int need_secure )
@@ -671,6 +656,31 @@ fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
671656 }
672657 return -1 ;
673658}
659+ #elif defined(HAVE_GETENTROPY )
660+ /*
661+ * The Open Group Base Specifications Issue 8 - IEEE Std 1003.1-2024
662+ * https://pubs.opengroup.org/onlinepubs/9799919799/functions/getentropy.html
663+ *
664+ * NOTE: `getentropy`(3) on Linux is implemented using `getrandom`(2),
665+ * prefer the latter over this if both are defined.
666+ */
667+ #ifndef GETENTROPY_MAX
668+ # define GETENTROPY_MAX 256
669+ #endif
670+ static int
671+ fill_random_bytes_syscall (void * seed , size_t size , int need_secure )
672+ {
673+ unsigned char * p = (unsigned char * )seed ;
674+ while (size ) {
675+ size_t len = size < GETENTROPY_MAX ? size : GETENTROPY_MAX ;
676+ if (getentropy (p , len ) != 0 ) {
677+ return -1 ;
678+ }
679+ p += len ;
680+ size -= len ;
681+ }
682+ return 0 ;
683+ }
674684#else
675685# define fill_random_bytes_syscall (seed , size , need_secure ) -1
676686#endif
@@ -680,6 +690,7 @@ ruby_fill_random_bytes(void *seed, size_t size, int need_secure)
680690{
681691 int ret = fill_random_bytes_syscall (seed , size , need_secure );
682692 if (ret == 0 ) return ret ;
693+ if (fill_random_bytes_lib (seed , size ) == 0 ) return 0 ;
683694 return fill_random_bytes_urandom (seed , size );
684695}
685696
0 commit comments