aboutsummaryrefslogtreecommitdiffstats
path: root/librecrypt_fill_with_random_.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-04-26 22:36:47 +0200
committerMattias Andrée <m@maandree.se>2026-04-26 22:36:47 +0200
commitd77ab463184d113ca6119403887c9f4ed0dfdf0b (patch)
treeca8a1de443f90a4b7def56ea5b61c96aaa949f45 /librecrypt_fill_with_random_.c
downloadlibrecrypt-d77ab463184d113ca6119403887c9f4ed0dfdf0b.tar.gz
librecrypt-d77ab463184d113ca6119403887c9f4ed0dfdf0b.tar.bz2
librecrypt-d77ab463184d113ca6119403887c9f4ed0dfdf0b.tar.xz
First commit
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--librecrypt_fill_with_random_.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/librecrypt_fill_with_random_.c b/librecrypt_fill_with_random_.c
new file mode 100644
index 0000000..475a156
--- /dev/null
+++ b/librecrypt_fill_with_random_.c
@@ -0,0 +1,142 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifndef TEST
+
+
+int
+librecrypt_fill_with_random_(void *out, size_t n, ssize_t (*rng)(void *out, size_t n, void *user), void *user)
+{
+ char *buf = out;
+ ssize_t r;
+
+ if (!rng)
+ rng = &librecrypt_rng_;
+
+ while (n) {
+ r = (*rng)(buf, n, user);
+ if (r <= 0) {
+ if (!r)
+ abort();
+ return -1;
+ }
+ buf = &buf[(size_t)r];
+ n -= (size_t)r;
+ }
+
+ return 0;
+}
+
+
+#else
+
+
+static ssize_t
+zero(void *out, size_t n, void *user)
+{
+ (void) user;
+ memset(out, 0, n);
+ return (ssize_t)n;
+}
+
+
+static ssize_t
+seq(void *out, size_t n, void *user)
+{
+ unsigned char *restrict buf = out;
+ unsigned char *restrict num = user;
+ size_t i;
+ if (n > 64u)
+ n = 64u;
+ for (i = 0u; i < n; i++)
+ buf[i] = (*num)++;
+ return (ssize_t)n;
+}
+
+
+static ssize_t
+next(void *out, size_t n, void *user)
+{
+ unsigned char *restrict buf = out;
+ unsigned char *restrict num = user;
+ assert(n);
+ *buf = (*num)++;
+ return 1;
+}
+
+
+static ssize_t
+failer(void *out, size_t n, void *user)
+{
+ (void) out;
+ (void) n;
+ (void) user;
+ errno = EDOM;
+ return -1;
+}
+
+
+static ssize_t
+zero_ret(void *out, size_t n, void *user)
+{
+ (void) out;
+ (void) n;
+ (void) user;
+ return 0;
+}
+
+
+int
+main(void)
+{
+ unsigned char buf1[1024u];
+ unsigned char buf2[sizeof(buf1)];
+ unsigned char s;
+ size_t i;
+ int rv = 0;
+
+ INIT_TEST_ABORT();
+
+ SET_UP_ALARM();
+
+ EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), NULL, NULL) == 0);
+ EXPECT(librecrypt_fill_with_random_(buf2, sizeof(buf1), NULL, NULL) == 0);
+ EXPECT(memcmp(buf1, buf2, sizeof(buf1)));
+
+ memset(buf1, 99, sizeof(buf1));
+ errno = 0;
+ EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), &zero, NULL) == 0);
+ EXPECT(errno == 0);
+ for (s = 0u, i = 0u; i < sizeof(buf1); i++, s++)
+ EXPECT(!buf1[i]);
+
+ memset(buf1, 99, sizeof(buf1));
+ s = 0u;
+ errno = 0;
+ EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), &seq, &s) == 0);
+ EXPECT(errno == 0);
+ for (s = 0u, i = 0u; i < sizeof(buf1); i++, s++)
+ EXPECT(buf1[i] == s);
+
+ memset(buf1, 99, sizeof(buf1));
+ s = 0u;
+ errno = 0;
+ EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), &next, &s) == 0);
+ EXPECT(errno == 0);
+ for (s = 0u, i = 0u; i < sizeof(buf1); i++, s++)
+ EXPECT(buf1[i] == s);
+
+ memset(buf1, 99, sizeof(buf1));
+ s = 0u;
+ errno = 0;
+ EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), &failer, NULL) == -1);
+ EXPECT(errno == EDOM);
+ for (s = 0u, i = 0u; i < sizeof(buf1); i++, s++)
+ EXPECT(buf1[i] == 99);
+
+ EXPECT_ABORT(rv = librecrypt_fill_with_random_(buf1, sizeof(buf1), &zero_ret, NULL));
+
+ return rv;
+}
+
+
+#endif