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

Provide fallback implementation for getentropy() #2000

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

arkq
Copy link

@arkq arkq commented Nov 6, 2022

Commit ba3396f changed getRandomBytes() implementation from c++ std uniform distribution to getentropy(). The getentropy() function first appeared in glibc 2.25. In order to provide backward compatibility for older glibc (e.g. Android SDK <= 19) restore previous getRandomBytes() implementation as a fallback.

Testing

Right now compilation succeeds with NDK r19c: https://github.com/android/ndk/wiki/Unsupported-Downloads#r19c

Commit ba3396f changed getRandomBytes() implementation from c++ std
uniform distribution to getentropy(). The getentropy() function first
appeared in glibc 2.25. In order to provide backward compatibility for
older glibc (e.g. Android SDK <= 19) restore previous getRandomBytes()
implementation as a fallback.
@anzz1
Copy link

anzz1 commented Aug 1, 2023

Tested working in Linux 3.10 with glibc 2.24 ! 👍

Just need to add the definition for HAVE_GETENTROPY in configure.ac so it gets configured accordingly.

configure.ac

AC_CHECK_FUNCS([strptime],
        [AM_CONDITIONAL([HAVE_STRPTIME], true)],
        [AM_CONDITIONAL([HAVE_STRPTIME], false)])
+AC_CHECK_FUNCS([getentropy],
+        [AM_CONDITIONAL([HAVE_GETENTROPY], true)],
+        [AM_CONDITIONAL([HAVE_GETENTROPY], false)])
AC_CHECK_FUNCS([daemon], [have_daemon=yes])
AM_CONDITIONAL([HAVE_DAEMON], [test "x$have_daemon" = "xyes"])

Submitted PR to the patch fork : arkq#1
edit: PR is now merged in this PR

getentropy() requires glibc >=2.25
defines HAVE_GETENTROPY if callable
@anzz1
Copy link

anzz1 commented Aug 1, 2023

While this already works fine as-is, it could be further improved by adding another fallback:
getentropy() -> /dev/urandom -> std::uniform_int_distribution

SimpleRandomizer.cc

#if !HAVE_GETENTROPY
  auto getentropy = [this](void *buffer, size_t length) {
#if HAVE_URANDOM
    FILE *fp = fopen("/dev/urandom", "rb");
    if (fp) {
      size_t r = fread(buffer, length, 1, fp);
      fclose(fp);
      if (r == 1) {
        return 0;
      }
    }
#endif // HAVE_URANDOM
    auto buf = reinterpret_cast<unsigned int*>(buffer);
    auto dis = std::uniform_int_distribution<unsigned int>();
    for (size_t q = length / sizeof(unsigned int); q > 0; --q, ++buf) {
      *buf = dis(gen_);
    }
    const size_t r = length % sizeof(unsigned int);
    auto last = dis(gen_);
    memcpy(buf, &last, r);
    return 0;
  };
#endif // !HAVE_GETENTROPY

configure.ac

+AC_CHECK_FILE("/dev/urandom",
+        [AM_CONDITIONAL([HAVE_URANDOM], true)],
+        [AM_CONDITIONAL([HAVE_URANDOM], false)]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants