From f07a9f80fb6f3099d75534c1e64f448d4b397931 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 14 May 2026 22:20:02 +0200 Subject: Fix minor errors in the test and check that we are not writing out of bounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- argon2/hash.c | 22 +++++++++++++++------- argon2/make_settings.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) (limited to 'argon2') diff --git a/argon2/hash.c b/argon2/hash.c index fd4609a..9223e55 100644 --- a/argon2/hash.c +++ b/argon2/hash.c @@ -160,7 +160,7 @@ static int discarded_int; static void -check(const char *phrase, const char *settings, const char *hash, size_t hashlen) +check(const char *phrase, const char *settings, const char *hash, size_t hashlen, size_t scratchsize) { size_t i, len = strlen(phrase); size_t prefix = strlen(settings); @@ -176,21 +176,26 @@ check(const char *phrase, const char *settings, const char *hash, size_t hashlen argon2__PAD, argon2__STRICT_PAD); assert(r > 0 && (size_t)r == hashlen); - memset(buf, 0, sizeof(buf)); + CANARY_FILL(buf); EXPECT(librecrypt__argon2__hash(buf, sizeof(buf), phrase, len, settings, prefix, NULL) == 0); EXPECT(!memcmp(expected, buf, hashlen)); + CANARY_X_CHECK(buf, hashlen, scratchsize); - memset(buf, 0, sizeof(buf)); + CANARY_FILL(buf); EXPECT(librecrypt__argon2__hash(buf, hashlen, phrase, len, settings, prefix, NULL) == 0); EXPECT(!memcmp(expected, buf, hashlen)); + CANARY_X_CHECK(buf, hashlen, scratchsize); + CANARY_FILL(buf); EXPECT(librecrypt__argon2__hash(buf, 0u, phrase, len, settings, prefix, NULL) == 0); + CANARY_X_CHECK(buf, 0u, 0u); EXPECT(librecrypt__argon2__hash(NULL, 0u, phrase, len, settings, prefix, NULL) == 0); for (i = 1u; i <= hashlen * 2u; i++) { - memset(buf, 0, sizeof(buf)); + CANARY_FILL(buf); EXPECT(librecrypt__argon2__hash(buf, i, phrase, len, settings, prefix, NULL) == 0); EXPECT(!memcmp(expected, buf, MIN(i, hashlen))); + CANARY_X_CHECK(buf, MIN(i, hashlen), scratchsize); } } @@ -201,10 +206,11 @@ check(const char *phrase, const char *settings, const char *hash, size_t hashlen #define CHECK(PHRASE, CONF, HASHLEN, HASH)\ do {\ - check(PHRASE, CONF HASH, HASH, (size_t)HASHLEN);\ + size_t scratchsize = GET_SCRATCH_SIZE(HASHLEN);\ + check(PHRASE, CONF HASH, HASH, (size_t)HASHLEN, scratchsize);\ if ((size_t)HASHLEN == argon2__HASH_SIZE)\ - check(PHRASE, CONF, HASH, (size_t)HASHLEN);\ - check(PHRASE, CONF "*" #HASHLEN, HASH, (size_t)HASHLEN);\ + check(PHRASE, CONF, HASH, (size_t)HASHLEN, scratchsize);\ + check(PHRASE, CONF "*" #HASHLEN, HASH, (size_t)HASHLEN, scratchsize);\ } while (0) @@ -268,6 +274,7 @@ main(void) INIT_TEST_ABORT(); INIT_RESOURCE_TEST(); +#define GET_SCRATCH_SIZE(HASHLEN) ((HASHLEN) > 64u ? ((HASHLEN) + 63u) & ~31u : (HASHLEN)) #if defined(SUPPORT_ARGON2I) CHECK("password", "$argon2i$" "m=256,t=2,p=1$c29tZXNhbHQ$", 32, "/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY"); CHECK("password", "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$", 32, "iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8"); @@ -287,6 +294,7 @@ main(void) "yLKZMg+DIOXVc9z1po9ZlZG8+Gp4g5brqfza3lvkR9vw"); CHECK_BAD("$argon2d$"); #endif +#undef GET_SCRATCH_SIZE STOP_RESOURCE_TEST(); return 0; diff --git a/argon2/make_settings.c b/argon2/make_settings.c index 924b33f..4354196 100644 --- a/argon2/make_settings.c +++ b/argon2/make_settings.c @@ -164,14 +164,17 @@ check(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t, ssize_t r; if (!algo_out) { + CANARY_FILL(buf); errno = 0; EXPECT((*gen)(buf, sizeof(buf), algo_in, 0u, 0u, 0, &saltgen, &saltbyte) == -1); EXPECT(errno == ENOSYS); + CANARY_CHECK(buf, 0u); return; } off = strlen(algo_out); + CANARY_FILL(buf); 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)); @@ -179,40 +182,53 @@ check(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t, 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); + CANARY_CHECK(buf, (size_t)r + 1u); EXPECT((*gen)(NULL, 0u, algo_in, 0u, 0u, 0, &saltgen, &saltbyte) == r); for (i = 1u; i <= (size_t)r; i++) { + CANARY_FILL(buf2); EXPECT((*gen)(buf2, i, algo_in, 0u, 0u, 0, &saltgen, &saltbyte) == r); EXPECT(!buf2[i - 1u]); EXPECT(!memcmp(buf2, buf, i - 1u)); + CANARY_CHECK(buf2, i); } + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); EXPECT((*gen)(buf, sizeof(buf), algo_in, 8192u << 10, (uintmax_t)81920u, 1, &saltgen, &saltbyte) == r); for (i = 1u; i <= (size_t)r; i++) { + CANARY_FILL(buf2); 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)); + CANARY_CHECK(buf2, i); } + CANARY_FILL(buf); 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)); @@ -221,51 +237,67 @@ check(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t, 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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")); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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)); @@ -280,7 +312,9 @@ check(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t, v = v * 10u + d; } EXPECT(v <= (uintmax_t)LIBAR2_MAX_M_COST); + CANARY_CHECK(buf, (size_t)r + 1u); + CANARY_FILL(buf); 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)); @@ -295,6 +329,7 @@ check(ssize_t (*gen)(char *, size_t, const char *, size_t, uintmax_t, v = v * 10u + d; } EXPECT(v <= (uintmax_t)LIBAR2_MAX_T_COST); + CANARY_CHECK(buf, (size_t)r + 1u); errno = 0; EXPECT((*gen)(buf, sizeof(buf), algo_in, 0u, 0u, 1, &saltfail, NULL) == -1); -- cgit v1.2.3-70-g09d2