summaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/aws-c-common/source/posix/device_random.c
diff options
context:
space:
mode:
authorDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/restricted/aws/aws-c-common/source/posix/device_random.c
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/restricted/aws/aws-c-common/source/posix/device_random.c')
-rw-r--r--contrib/restricted/aws/aws-c-common/source/posix/device_random.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/contrib/restricted/aws/aws-c-common/source/posix/device_random.c b/contrib/restricted/aws/aws-c-common/source/posix/device_random.c
new file mode 100644
index 00000000000..f446002231b
--- /dev/null
+++ b/contrib/restricted/aws/aws-c-common/source/posix/device_random.c
@@ -0,0 +1,57 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/common/device_random.h>
+
+#include <aws/common/byte_buf.h>
+#include <aws/common/thread.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+static int s_rand_fd = -1;
+static aws_thread_once s_rand_init = AWS_THREAD_ONCE_STATIC_INIT;
+
+#ifdef O_CLOEXEC
+# define OPEN_FLAGS (O_RDONLY | O_CLOEXEC)
+#else
+# define OPEN_FLAGS (O_RDONLY)
+#endif
+static void s_init_rand(void *user_data) {
+ (void)user_data;
+ s_rand_fd = open("/dev/urandom", OPEN_FLAGS);
+
+ if (s_rand_fd == -1) {
+ s_rand_fd = open("/dev/urandom", O_RDONLY);
+
+ if (s_rand_fd == -1) {
+ abort();
+ }
+ }
+
+ if (-1 == fcntl(s_rand_fd, F_SETFD, FD_CLOEXEC)) {
+ abort();
+ }
+}
+
+static int s_fallback_device_random_buffer(struct aws_byte_buf *output) {
+
+ aws_thread_call_once(&s_rand_init, s_init_rand, NULL);
+
+ size_t diff = output->capacity - output->len;
+
+ ssize_t amount_read = read(s_rand_fd, output->buffer + output->len, diff);
+
+ if (amount_read != diff) {
+ return aws_raise_error(AWS_ERROR_RANDOM_GEN_FAILED);
+ }
+
+ output->len += diff;
+
+ return AWS_OP_SUCCESS;
+}
+
+int aws_device_random_buffer(struct aws_byte_buf *output) {
+ return s_fallback_device_random_buffer(output);
+}