diff options
author | EuAndreh <eu@euandre.org> | 2022-01-28 07:33:30 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2024-01-01 12:35:01 -0300 |
commit | 9f554a72b01705ebf6be66143c5e69b09b3c1372 (patch) | |
tree | fadf04038b2d5df32fd4b5bc93ba291269c322a0 /src/random.c | |
download | pindaiba-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.c | 122 |
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 |