summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/libc/getentropy.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/libc/getentropy.cc')
-rw-r--r--winsup/cygwin/libc/getentropy.cc70
1 files changed, 70 insertions, 0 deletions
diff --git a/winsup/cygwin/libc/getentropy.cc b/winsup/cygwin/libc/getentropy.cc
new file mode 100644
index 000000000..5918eb5d9
--- /dev/null
+++ b/winsup/cygwin/libc/getentropy.cc
@@ -0,0 +1,70 @@
+/* getentropy.cc: getentropy/getrandmom functions
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "winsup.h"
+#include <ntsecapi.h>
+#include <sys/param.h>
+#include <sys/random.h>
+#include "cygtls.h"
+#include "ntdll.h"
+
+extern "C" int
+getentropy (void *ptr, size_t len)
+{
+ /* Per BSD man page: The maximum buffer size permitted is 256 bytes.
+ If buflen exceeds this, an error of EIO will be indicated. */
+ if (len > 256)
+ {
+ debug_printf ("len (%U) > 256", len);
+ set_errno (EIO);
+ return -1;
+ }
+ __try
+ {
+ if (!RtlGenRandom (ptr, len))
+ {
+ debug_printf ("RtlGenRandom() = FALSE");
+ set_errno (EIO);
+ return -1;
+ }
+ }
+ __except (EFAULT)
+ {
+ return -1;
+ }
+ __endtry
+ return 0;
+}
+
+extern "C" ssize_t
+getrandom (void *ptr, size_t len, unsigned int flags)
+{
+ if (flags & ~(GRND_NONBLOCK | GRND_RANDOM))
+ {
+ debug_printf ("invalid flags: %y", flags);
+ set_errno (EINVAL);
+ return -1;
+ }
+ /* Max. bytes returned by Linux call. */
+ len = MAX (len, (flags & GRND_RANDOM) ? 512 : 33554431);
+ __try
+ {
+ if (!RtlGenRandom (ptr, len))
+ {
+ debug_printf ("RtlGenRandom() = FALSE");
+ set_errno (EIO);
+ return -1;
+ }
+ }
+ __except (EFAULT)
+ {
+ return -1;
+ }
+ __endtry
+ return len;
+}