From 266ffbc3e61570d08ec0ec84394ab49eb9b44e7d Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sun, 10 May 2026 22:05:40 +0200 Subject: Misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- argon2/make_settings.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 222 insertions(+), 8 deletions(-) (limited to 'argon2/make_settings.c') diff --git a/argon2/make_settings.c b/argon2/make_settings.c index 66ac3d6..396c48d 100644 --- a/argon2/make_settings.c +++ b/argon2/make_settings.c @@ -1,8 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include "../common.h" -#ifndef TEST - #include +#ifndef TEST static ssize_t @@ -43,11 +42,11 @@ make_settings(char *out_buffer, size_t size, const char *algorithm, size_t memco /* Get version */ p = algorithm; if (*p++ != '$') - abort(); + abort(); /* $covered$ */ p = strchr(p, '$'); algolen = p ? (size_t)(p - algorithm) : strlen(algorithm); - if (algolen > 64) /* just some small value absolute will fit all variants */ - abort(); + if (algolen > 32u) /* just some small value absolute will fit all variants */ + abort(); /* $covered$ */ if (p++ && *p++ == 'v') { if (!strncmp(p, "=16", 3u) && (!p[3u] || p[3u] == '$')) version = "16"; @@ -62,7 +61,7 @@ make_settings(char *out_buffer, size_t size, const char *algorithm, size_t memco (int)algolen, algorithm, version, memcost, (unsigned long long int)timecost); if (r < (int)sizeof("$argon2_$v=__$m=_,t=_,p=1$") - 1) - abort(); + abort(); /* $covered$ (impossible) */ ret = (size_t)r; min = size ? ret < size - 1u ? ret : size - 1u : 0u; out_buffer = &out_buffer[min]; @@ -129,16 +128,231 @@ IF__argon2ds__SUPPORTED(DECLARE_MAKE_SETTINGS(argon2ds)) #else -CONST int +static unsigned char saltbyte = 0u; +static ssize_t discarded_ssize; + + +static ssize_t +saltgen(void *out, size_t n, void *user) +{ + if (!n) + return 0; + *(unsigned char *)out = *(unsigned char *)user; + return 1; +} + + +static ssize_t +saltfail(void *out, size_t n, void *user) +{ + (void) out; + (void) n; + (void) user; + errno = EDOM; + return -1; +} + + +static void +check(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t, + int , ssize_t (*)(void *, size_t, void *), void *), + const char *algo_out, const char *algo_in) +{ + uintmax_t v, d; + char buf[1024]; + char buf2[sizeof(buf)]; + size_t off, i; + ssize_t r; + + if (!algo_out) { + errno = 0; + EXPECT((*gen)(buf, sizeof(buf), algo_in, 0u, 0u, 0, &saltgen, &saltbyte) == -1); + EXPECT(errno == ENOSYS); + return; + } + + off = strlen(algo_out); + + r = (*gen)(buf, sizeof(buf), algo_in, 0u, 0u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=4096,t=10,p=1$*16$*32")); + assert(LIBAR2_MIN_SALTLEN <= 16u && 16u <= LIBAR2_MAX_SALTLEN); + assert(LIBAR2_MIN_HASHLEN <= 32u && 32u <= LIBAR2_MAX_HASHLEN); + + EXPECT((*gen)(NULL, 0u, algo_in, 0u, 0u, 0, &saltgen, &saltbyte) == r); + for (i = 1u; i <= (size_t)r; i++) { + EXPECT((*gen)(buf2, i, algo_in, 0u, 0u, 0, &saltgen, &saltbyte) == r); + EXPECT(!buf2[i - 1u]); + EXPECT(!memcmp(buf2, buf, i - 1u)); + } + + r = (*gen)(buf, sizeof(buf), algo_in, 8192u << 10, 0u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=8192,t=5,p=1$*16$*32")); + + r = (*gen)(buf, sizeof(buf), algo_in, 8192u << 10, (uintmax_t)81920u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=8192,t=10,p=1$*16$*32")); + + saltbyte = 0u; + r = (*gen)(buf, sizeof(buf), algo_in, 8192u << 10, (uintmax_t)81920u, 1, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32")); + + EXPECT((*gen)(buf, sizeof(buf), algo_in, 8192u << 10, (uintmax_t)81920u, 1, &saltgen, &saltbyte) == r); + for (i = 1u; i <= (size_t)r; i++) { + EXPECT((*gen)(buf2, i, algo_in, 8192u << 10, (uintmax_t)81920u, 1, &saltgen, &saltbyte) == r); + EXPECT(!buf2[i - 1u]); + EXPECT(!memcmp(buf2, buf, i - 1u)); + } + + r = (*gen)(buf, sizeof(buf), algo_in, 8192u << 10, (uintmax_t)81920u, 1, NULL, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(strcmp(&buf[off], "m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32")); + memcpy(buf2, buf, (size_t)r); + memset(&buf[off + sizeof("m=8192,t=10,p=1$") - 1u], 'A', 22u); + EXPECT(!strcmp(&buf[off], "m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32")); + + EXPECT((*gen)(buf, sizeof(buf), algo_in, 8192u << 10, (uintmax_t)81920u, 1, NULL, &saltbyte) == r); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(memcmp(buf, buf2, (size_t)r)); + memset(&buf[off + sizeof("m=8192,t=10,p=1$") - 1u], 'A', 22u); + EXPECT(!strcmp(&buf[off], "m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32")); + + saltbyte = 255u; + r = (*gen)(buf, sizeof(buf), algo_in, 8192u << 10, (uintmax_t)81920u, 1, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=8192,t=10,p=1$/////////////////////w$*32")); + + r = (*gen)(buf, sizeof(buf), algo_in, 0u, (uintmax_t)81920u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=4096,t=20,p=1$*16$*32")); + + r = (*gen)(buf, sizeof(buf), algo_in, 1u, 1u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=8,t=1,p=1$*16$*32")); + + r = (*gen)(buf, sizeof(buf), algo_in, 1u, 1u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=8,t=1,p=1$*16$*32")); + + r = (*gen)(buf, sizeof(buf), algo_in, (10u << 10) + 512u, 1u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=11,t=1,p=1$*16$*32")); + + r = (*gen)(buf, sizeof(buf), algo_in, (10u << 10) + 511u, 1u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strcmp(&buf[off], "m=10,t=1,p=1$*16$*32")); + + r = (*gen)(buf, sizeof(buf), algo_in, SIZE_MAX, 1u, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strncmp(&buf[off], "m=", sizeof("m=") - 1u)); + i = off + sizeof("m=") - 1u; + EXPECT('0' <= buf[i] && buf[i] <= '9'); + for (v = 0; buf[i] != ','; i++) { + EXPECT('0' <= buf[i] && buf[i] <= '9'); + d = (uintmax_t)(buf[i] - '0'); + EXPECT(v <= (UINTMAX_MAX - d) / 10u); + v = v * 10u + d; + } + EXPECT(v <= (uintmax_t)LIBAR2_MAX_M_COST); + + r = (*gen)(buf, sizeof(buf), algo_in, 1u, UINTMAX_MAX, 0, &saltgen, &saltbyte); + EXPECT(r > 0 && (size_t)r < sizeof(buf)); + EXPECT(!buf[r] && (size_t)r == strlen(buf)); + EXPECT(!strncmp(buf, algo_out, off)); + EXPECT(!strncmp(&buf[off], "m=8,t=", sizeof("m=8,t=") - 1u)); + i = off + sizeof("m=8,t=") - 1u; + EXPECT('0' <= buf[i] && buf[i] <= '9'); + for (v = 0; buf[i] != ','; i++) { + EXPECT('0' <= buf[i] && buf[i] <= '9'); + d = (uintmax_t)(buf[i] - '0'); + EXPECT(v <= (UINTMAX_MAX - d) / 10u); + v = v * 10u + d; + } + EXPECT(v <= (uintmax_t)LIBAR2_MAX_T_COST); + + errno = 0; + EXPECT((*gen)(buf, sizeof(buf), algo_in, 0u, 0u, 1, &saltfail, NULL) == -1); + EXPECT(errno == EDOM); +} + + +static void +check_aborts(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t, + int , ssize_t (*)(void *, size_t, void *), void *)) +{ +#define SHORTTEXT "------------------------------------------------------------------------" +#define LONGTEXT SHORTTEXT SHORTTEXT SHORTTEXT SHORTTEXT SHORTTEXT SHORTTEXT SHORTTEXT + EXPECT_ABORT(discarded_ssize = (*gen)(NULL, 0, "argon2i$", 0u, 0u, 0, NULL, NULL)); + EXPECT_ABORT(discarded_ssize = (*gen)(NULL, 0, "$argon2"LONGTEXT"$", 0u, 0u, 0, NULL, NULL)); +} + + +#define CHECK(FUNC, ALGO)\ + do {\ + check(&(FUNC), "$"ALGO"$v=19$", NULL);\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$");\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO);\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$m=100,t=10,p=2$xxxx$*32");\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$m=100,t=10,p=2$*40$");\ + check(&(FUNC), "$"ALGO"$v=16$", "$"ALGO"$v=16");\ + check(&(FUNC), "$"ALGO"$v=16$", "$"ALGO"$v=16$");\ + check(&(FUNC), "$"ALGO"$v=16$", "$"ALGO"$v=16$m=100,t=10,p=2$xxxx$*32");\ + check(&(FUNC), "$"ALGO"$v=16$", "$"ALGO"$v=16$m=100,t=10,p=2$*40$");\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$v=19");\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$v=19$");\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$v=19$m=100,t=10,p=2$xxxx$*32");\ + check(&(FUNC), "$"ALGO"$v=19$", "$"ALGO"$v=19$m=100,t=10,p=2$*40$");\ + check(&(FUNC), NULL, "$"ALGO"$v=1");\ + check(&(FUNC), NULL, "$"ALGO"$v=");\ + check(&(FUNC), NULL, "$"ALGO"$v=160");\ + check(&(FUNC), NULL, "$"ALGO"$v=160$");\ + check(&(FUNC), NULL, "$"ALGO"$v=10$");\ + check_aborts(&(FUNC));\ + } while (0) + + +int main(void) { SET_UP_ALARM(); + INIT_TEST_ABORT(); INIT_RESOURCE_TEST(); + IF__argon2i__SUPPORTED(CHECK(librecrypt__argon2i__make_settings, "argon2i");) + IF__argon2d__SUPPORTED(CHECK(librecrypt__argon2d__make_settings, "argon2d");) + IF__argon2id__SUPPORTED(CHECK(librecrypt__argon2id__make_settings, "argon2id");) + IF__argon2ds__SUPPORTED(CHECK(librecrypt__argon2ds__make_settings, "argon2ds");) + STOP_RESOURCE_TEST(); return 0; } #endif -/* TODO test */ -- cgit v1.2.3-70-g09d2