summaryrefslogtreecommitdiff
path: root/src/random.c
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2022-01-28 07:33:30 -0300
committerEuAndreh <eu@euandre.org>2024-01-01 12:35:01 -0300
commit9f554a72b01705ebf6be66143c5e69b09b3c1372 (patch)
treefadf04038b2d5df32fd4b5bc93ba291269c322a0 /src/random.c
downloadpindaiba-9f554a72b01705ebf6be66143c5e69b09b3c1372.tar.gz
pindaiba-9f554a72b01705ebf6be66143c5e69b09b3c1372.tar.xz
Init project: copy files and skeletons from others
Diffstat (limited to 'src/random.c')
-rw-r--r--src/random.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/random.c b/src/random.c
new file mode 100644
index 0000000..d92d533
--- /dev/null
+++ b/src/random.c
@@ -0,0 +1,122 @@
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "logerr.h"
+#include "random.h"
+
+#ifdef TEST
+#include "testing.h"
+#endif
+
+
+int
+urandom_bytes(const size_t n, uint8_t (*const addr)[]) {
+ int rc = 0;
+
+ FILE *f = NULL;
+
+ f = fopen("/dev/urandom", "r");
+ if (!f) {
+ logerr("fopen(\"/dev/urandom\", \"r\"): %s\n", strerror(errno));
+ rc = -1;
+ goto out;
+ }
+
+ const size_t read_count = fread(addr, 1, n, f);
+ if (ferror(f)) {
+ logerr("fread(addr, 1, n, f): %s\n", strerror(errno));
+ rc = -1;
+ goto out;
+ }
+ assert(read_count == n);
+
+out:
+ if (f) {
+ if (fclose(f)) {
+ logerr("fclose(f): %s\n", strerror(errno));
+ rc = -1;
+ }
+ }
+ return rc;
+}
+
+#ifdef TEST
+static int
+test_urandom_bytes(void) {
+ int rc = 0;
+
+ test_start("urandom_bytes()");
+
+ {
+ testing("we get to pick the size that comes out");
+
+ const size_t LEN = 256;
+ uint8_t arr[256 /* LEN */] = { 0 };
+
+ for (size_t n = 0; n < LEN; n++) {
+ if (urandom_bytes(n, &arr)) {
+ logerr("urandom_bytes(n, &arr);\n");
+ rc = -1;
+ goto out;
+ }
+ for (size_t i = n; i < LEN; i++) {
+ assert(arr[i] == 0);
+ }
+ }
+
+ test_ok();
+ }
+
+ {
+ testing("we always get a new value as a result");
+
+ const size_t LEN = 64;
+ uint8_t arr1[64 /* LEN */] = { 0 };
+ uint8_t arr2[64 /* LEN */] = { 0 };
+
+ if (urandom_bytes(LEN, &arr1)) {
+ logerr("urandom_bytes(LEN, &arr1);\n");
+ rc = -1;
+ goto out;
+ }
+
+ const size_t attempts = 10;
+ for (size_t n = 0; n < attempts; n++) {
+ if (urandom_bytes(LEN, &arr2)) {
+ logerr("urandom_bytes(LEN, &arr2);\n");
+ rc = -1;
+ goto out;
+ }
+ assert(memcmp(arr1, arr2, LEN) != 0);
+ }
+
+ test_ok();
+ }
+
+out:
+ return rc;
+}
+#endif
+
+
+#ifdef TEST
+int
+main(void) {
+ int rc = 0;
+
+ if (test_urandom_bytes()) {
+ logerr("test_urandom_bytes();\n");
+ rc = -1;
+ goto out;
+ }
+
+out:
+ return !!rc;
+}
+#endif