From 86087e5f9cf4a0512ba36b4d01086b905574a47d Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 11 May 2026 23:15:33 +0200 Subject: Misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- librecrypt_realise_salts.c | 143 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 4 deletions(-) (limited to 'librecrypt_realise_salts.c') diff --git a/librecrypt_realise_salts.c b/librecrypt_realise_salts.c index a21c4df..58ba6d3 100644 --- a/librecrypt_realise_salts.c +++ b/librecrypt_realise_salts.c @@ -51,6 +51,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set for (i = 0u; settings[i] != '*'; i++); min = i < size ? i : size; memcpy(out_buffer, settings, min); + out_buffer = &out_buffer[min]; size -= min; settings = &settings[i]; ret += i; @@ -60,7 +61,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set /* If the '*' is not followed by an unsigned, * decimal integer include it literally */ - if ('0' > settings[1u] || settings[1u] > '9') { + if ('0' > settings[0u] || settings[0u] > '9') { if (size) { *out_buffer++ = '*'; size -= 1u; @@ -95,7 +96,9 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set * r==2: 3 base-64 characters, so 1 padding characters */ right = (r && pad) ? 3u - r : 0u; /* Get total length */ - if (q > ((size_t)SSIZE_MAX - right) / 4u) + if (q > ((size_t)SSIZE_MAX - (r + mid + right)) / 4u) + goto erange; + if (ret > (size_t)SSIZE_MAX - (left + mid + right)) goto erange; ret += left + mid + right; @@ -104,7 +107,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set * one variable for all random characters */ left += mid; if (left > size) { - left = 0u; + left = size; mid = 0u; } @@ -134,6 +137,7 @@ librecrypt_realise_salts(char *restrict out_buffer, size_t size, const char *set break; min = i < size ? i : size; memcpy(out_buffer, settings, min); + out_buffer = &out_buffer[min]; size -= min; settings = &settings[i]; ret += i; @@ -160,16 +164,147 @@ erange: #else +# define LARGE "99999999999999999999999999999999999999999999999999999999999999" +# define A10 "AAAAAAAAAA" +# define A40 A10 A10 A10 A10 + + +static unsigned char saltbyte = 0u; + + +static ssize_t +saltgen(void *out, size_t n, void *user) +{ + (void) user; + if (n > (size_t)SSIZE_MAX) + n = (size_t)SSIZE_MAX; + memset(out, *(unsigned char *)user, n); + return (ssize_t)n; +} + + +static ssize_t +saltfail(void *out, size_t n, void *user) +{ + (void) out; + (void) n; + (void) user; + errno = EDOM; + return -1; +} + + int main(void) { + char buf[1024], buf2[1024], conf[128]; + size_t i; + int r; + SET_UP_ALARM(); INIT_RESOURCE_TEST(); + errno = 0; + EXPECT(librecrypt_realise_salts(NULL, 0u, "$~no~such~algorithm~$", NULL, NULL) == -1); + EXPECT(errno == ENOSYS); + + EXPECT(librecrypt_realise_salts(NULL, 0u, "", NULL, NULL) == 0); + +#if defined(SUPPORT_ARGON2ID) +# define ALGO "$argon2id$" +#elif defined(SUPPORT_ARGON2I) +# define ALGO "$argon2i$" +#elif defined(SUPPORT_ARGON2D) +# define ALGO "$argon2d$" +#elif defined(SUPPORT_ARGON2DS) +# define ALGO "$argon2ds$" +#endif + +#if defined(ALGO) +# define CHECK(IN, OUT)\ + do {\ + EXPECT(librecrypt_realise_salts(NULL, 0u, (IN), NULL, NULL) == (ssize_t)sizeof(OUT) - 1);\ + EXPECT(librecrypt_realise_salts(buf, 0u, (IN), NULL, NULL) == (ssize_t)sizeof(OUT) - 1);\ + memset(buf, 99, sizeof(buf));\ + EXPECT(librecrypt_realise_salts(buf, sizeof(buf), (IN), &saltgen, &saltbyte) == (ssize_t)sizeof(OUT) - 1);\ + EXPECT(!strcmp(buf, (OUT)));\ + for (i = 0u; i < sizeof(OUT); i++) {\ + memset(buf, 99, sizeof(buf));\ + EXPECT(librecrypt_realise_salts(buf, i + 1u, (IN), &saltgen, &saltbyte) == (ssize_t)sizeof(OUT) - 1);\ + EXPECT(!memcmp(buf, (OUT), i));\ + EXPECT(!buf[i]);\ + }\ + } while (0) + + CHECK(ALGO, ALGO); + CHECK(ALGO"*100", ALGO "*100"); + CHECK(ALGO"*30$", ALGO A40 "$"); + CHECK(ALGO"*30$*100", ALGO A40 "$*100"); + CHECK(ALGO"*31$*100", ALGO A40 "AA$*100"); + CHECK(ALGO"*32$*100", ALGO A40 "AAA$*100"); + CHECK(ALGO"*33$*100", ALGO A40 "AAAA$*100"); + CHECK(ALGO"*1$*100", ALGO "AA$*100"); + CHECK(ALGO"*2$*100", ALGO "AAA$*100"); + CHECK(ALGO"*3$*100", ALGO "AAAA$*100"); + CHECK(ALGO"*033$*100", ALGO A40 "AAAA$*100"); + CHECK(ALGO"*0$*100", ALGO "$*100"); + CHECK(ALGO"*30*30$*100", ALGO A40 A40"$*100"); + CHECK(ALGO"*30*3$*100", ALGO A40 "AAAA$*100"); + CHECK(ALGO"*30$*30$*100", ALGO A40 "$" A40"$*100"); + CHECK(ALGO"*30$*3$*100", ALGO A40 "$AAAA$*100"); + CHECK(ALGO"*$*100", ALGO "*$*100"); + CHECK(ALGO"*x$*100", ALGO "*x$*100"); + CHECK(ALGO">"ALGO, ALGO">"ALGO); + CHECK(ALGO"*30$*100>"ALGO"*30$*10", ALGO A40 "$*100>" ALGO A40 "$*10"); + CHECK(ALGO"*30$>"ALGO"*30$", ALGO A40 "$>" ALGO A40 "$"); + +# undef CHECK + + errno = 0; + EXPECT(librecrypt_realise_salts(NULL, 0u, ALGO">$~no~such~algorithm~$", &saltgen, &saltbyte) == -1); + EXPECT(errno == ENOSYS); + errno = 0; + EXPECT(librecrypt_realise_salts(NULL, 0u, "$~no~such~algorithm~$>"ALGO, &saltgen, &saltbyte) == -1); + EXPECT(errno == ENOSYS); + errno = 0; + EXPECT(librecrypt_realise_salts(NULL, 0u, ALGO"*"LARGE"$", &saltgen, &saltbyte) == -1); + EXPECT(errno == ERANGE); + + EXPECT(librecrypt_realise_salts(buf, sizeof(ALGO) - 1u, ALGO"*3$", &saltfail, NULL) == (ssize_t)sizeof(ALGO"$") - 1 + 4); + errno = 0; + EXPECT(librecrypt_realise_salts(buf, sizeof(buf), ALGO"*3$", &saltfail, NULL) == -1); + EXPECT(errno == EDOM); + + r = snprintf(conf, sizeof(conf), "%s*%zu$", ALGO, (size_t)SSIZE_MAX / 4u * 3u + 3u); + assert(r > 0 && (size_t)r < sizeof(conf)); + errno = 0; + EXPECT(librecrypt_realise_salts(NULL, 0u, conf, &saltgen, &saltbyte) == -1); + EXPECT(errno == ERANGE); + + r = snprintf(conf, sizeof(conf), "%s*%zu$", ALGO, (size_t)SSIZE_MAX / 4u * 3u); + assert(r > 0 && (size_t)r < sizeof(conf)); + errno = 0; + EXPECT(librecrypt_realise_salts(NULL, 0u, conf, &saltgen, &saltbyte) == -1); + EXPECT(errno == ERANGE); + + r = snprintf(conf, sizeof(conf), "%s*%zu$abcdef", ALGO, ((size_t)SSIZE_MAX - (sizeof(ALGO) - 1u)) / 4u * 3u); + assert(r > 0 && (size_t)r < sizeof(conf)); + errno = 0; + EXPECT(librecrypt_realise_salts(NULL, 0u, conf, &saltgen, &saltbyte) == -1); + EXPECT(errno == ERANGE); + + memset(buf, 99, sizeof(buf)); + memset(buf2, 99, sizeof(buf2)); + EXPECT(librecrypt_realise_salts(buf, sizeof(buf), ALGO"*30$", NULL, NULL) == (ssize_t)sizeof(ALGO"$") - 1 + 40); + EXPECT(librecrypt_realise_salts(buf2, sizeof(buf2), ALGO"*30$", NULL, NULL) == (ssize_t)sizeof(ALGO"$") - 1 + 40); + EXPECT(!buf[sizeof(ALGO"$") - 1u + 40u]); + EXPECT(!buf2[sizeof(ALGO"$") - 1u + 40u]); + EXPECT(memcmp(buf, buf2, sizeof(ALGO"$") - 1u + 40u)); +#endif + STOP_RESOURCE_TEST(); return 0; } #endif -/* TODO test */ -- cgit v1.2.3-70-g09d2