diff options
| author | Mattias Andrée <m@maandree.se> | 2026-04-26 22:36:47 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-04-26 22:36:47 +0200 |
| commit | d77ab463184d113ca6119403887c9f4ed0dfdf0b (patch) | |
| tree | ca8a1de443f90a4b7def56ea5b61c96aaa949f45 /librecrypt_fill_with_random_.c | |
| download | librecrypt-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_.c | 142 |
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 |
