aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--argon2/hash.c22
-rw-r--r--argon2/make_settings.c35
-rw-r--r--common.h26
-rw-r--r--librecrypt_add_algorithm.c33
-rw-r--r--librecrypt_crypt.c46
-rw-r--r--librecrypt_decode.c30
-rw-r--r--librecrypt_decompose_chain.c27
-rw-r--r--librecrypt_decompose_chain1.c2
-rw-r--r--librecrypt_encode.c10
-rw-r--r--librecrypt_fill_with_random_.c20
-rw-r--r--librecrypt_hash.c34
-rw-r--r--librecrypt_hash_.c29
-rw-r--r--librecrypt_hash_binary.c26
-rw-r--r--librecrypt_make_settings.c20
-rw-r--r--librecrypt_realise_salts.c8
-rw-r--r--librecrypt_rng_.c6
16 files changed, 295 insertions, 79 deletions
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);
diff --git a/common.h b/common.h
index f64399a..02b99fa 100644
--- a/common.h
+++ b/common.h
@@ -556,4 +556,30 @@ int librecrypt_check_settings_(const char *settings, size_t len, const char *fmt
exit(2);\
}\
} while (0)
+
+# define CANARY_FILL(BUF) CANARY_C_FILL(99, BUF)
+# define CANARY_CHECK(BUF, OFF) CANARY_C_CHECK(99, BUF, OFF)
+# define CANARY_X_CHECK(BUF, OFF1, OFF2) CANARY_XC_CHECK(99, BUF, OFF1, OFF2)
+
+# define CANARY_C_FILL(C, BUF)\
+ memset((BUF), (C), sizeof(BUF))
+
+# define CANARY_C_CHECK(C, BUF, OFF)\
+ do {\
+ size_t canary_i__;\
+ for (canary_i__ = (OFF); canary_i__ < sizeof(BUF); canary_i__++)\
+ EXPECT(((unsigned char *)(BUF))[canary_i__] == (unsigned char)(C));\
+ } while (0)
+
+# define CANARY_XC_CHECK(C, BUF, OFF1, OFF2)\
+ CANARY_XCC_CHECK(0, C, BUF, OFF1, OFF2)
+
+# define CANARY_XCC_CHECK(C1, C2, BUF, OFF1, OFF2)\
+ do {\
+ if ((OFF2) > (OFF1))\
+ CANARY_C_CHECK((C2), (BUF), (OFF2));\
+ memset(&(BUF)[(OFF1)], (C1), sizeof(BUF) - (OFF1));\
+ CANARY_C_CHECK((C1), (BUF), (OFF1));\
+ } while (0)
+
#endif
diff --git a/librecrypt_add_algorithm.c b/librecrypt_add_algorithm.c
index cf7f6eb..920577d 100644
--- a/librecrypt_add_algorithm.c
+++ b/librecrypt_add_algorithm.c
@@ -184,40 +184,55 @@ main(void)
#define CHECK(AUGEND, AUGMENT, RESULT)\
do {\
+ CANARY_FILL(buf);\
r = librecrypt_add_algorithm(buf, sizeof(buf), (AUGEND), (AUGMENT), NULL);\
EXPECT(r > 0);\
EXPECT((size_t)r == strlen(RESULT));\
assert((size_t)r < sizeof(buf) + 1u);\
EXPECT(!buf[r]);\
EXPECT(!memcmp(buf, (RESULT), (size_t)r));\
+ CANARY_CHECK(buf, (size_t)r + 1u);\
\
for (i = (size_t)r + 2u;; i--) {\
- memset(buf, 99, sizeof(buf));\
+ CANARY_FILL(buf);\
EXPECT(librecrypt_add_algorithm(buf, i, (AUGEND), (AUGMENT), NULL) == r);\
- if (!i)\
+ if (!i) {\
+ CANARY_CHECK(buf, 0u);\
break;\
+ }\
min = MIN(i - 1u, (size_t)r);\
EXPECT(!buf[min]);\
EXPECT(!memcmp(buf, (RESULT), min));\
+ CANARY_CHECK(buf, min + 1u);\
}\
\
EXPECT(librecrypt_add_algorithm(NULL, 0u, (AUGEND), (AUGMENT), NULL) == r);\
\
assert(sizeof(buf) > strlen(AUGEND));\
- stpcpy(buf, (AUGEND));\
\
+ CANARY_FILL(buf);\
+ stpcpy(buf, (AUGEND));\
EXPECT(librecrypt_add_algorithm(buf, sizeof(buf), buf, (AUGMENT), NULL) == r);\
EXPECT(!buf[r]);\
EXPECT(!memcmp(buf, (RESULT), (size_t)r));\
+ n = strlen(AUGEND) + 1u;\
+ n = MAX(n, (size_t)r + 1u);\
+ CANARY_CHECK(buf, n);\
\
for (i = (size_t)r + 2u;; i--) {\
+ CANARY_FILL(buf);\
stpcpy(buf, (AUGEND));\
+ n = strlen(AUGEND) + 1u;\
EXPECT(librecrypt_add_algorithm(buf, i, buf, (AUGMENT), NULL) == r);\
- if (!i)\
+ if (!i) {\
+ CANARY_CHECK(buf, n);\
break;\
+ }\
min = MIN(i - 1u, (size_t)r);\
EXPECT(!buf[min]);\
EXPECT(!memcmp(buf, (RESULT), min));\
+ n = MAX(n, min + 1u);\
+ CANARY_CHECK(buf, n);\
}\
} while (0)
@@ -262,10 +277,12 @@ main(void)
CHECK("$argon2d$m=8,t=1,p=1$$", "$argon2i$m=8,t=4,p=2$$",
"$argon2d$m=8,t=1,p=1$$>" "$argon2i$m=8,t=4,p=2$$");
+ CANARY_FILL(buf);
errno = 0;
EXPECT(librecrypt_add_algorithm(buf, sizeof(buf), "$argon2d$m=8,t=1,p=1$"SALT1"$"HASH1,
"$argon2i$m=8,t=4,p=1$$", NULL) == -1);
EXPECT(errno == EINVAL);
+ CANARY_CHECK(buf, sizeof("$argon2d$m=8,t=1,p=1$"SALT1"$"HASH1));
errno = 0;
EXPECT(librecrypt_add_algorithm(NULL, 0u, "$argon2d$m=8,t=1,p=1$"SALT1"$"HASH1,
@@ -294,32 +311,40 @@ main(void)
"$argon2i$m=8,t=4,p=1$"SALT2"$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", expected);
if (libtest_have_custom_malloc()) {
+ CANARY_FILL(buf);
libtest_set_alloc_failure_in(1u);
errno = 0;
EXPECT(librecrypt_add_algorithm(buf, sizeof(buf), "$argon2d$m=8,t=1,p=1$"SALT1"$"HASH1,
"$argon2d$m=8,t=1,p=1$"SALT2"$", NULL) == -1);
EXPECT(errno == ENOMEM);
assert(libtest_get_alloc_failure_in() == 0u);
+ CANARY_CHECK(buf, 0u);
}
+ CANARY_FILL(buf);
errno = 0;
EXPECT(librecrypt_add_algorithm(buf, sizeof(buf),
"$argon2d$m=8,t=1,p=1$"SALT1"$"
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
"$argon2d$m=8,t=1,p=1$"SALT2"$", NULL) == -1);
EXPECT(errno == EINVAL);
+ CANARY_CHECK(buf, 0u);
#endif
+ CANARY_FILL(buf);
errno = 0;
EXPECT(librecrypt_add_algorithm(buf, sizeof(buf), "$argon2d$m=8,t=1,p=1$"SALT1"$"HASH1,
"$~no~such~algorithm~$", NULL) == -1);
EXPECT(errno == ENOSYS);
+ CANARY_CHECK(buf, sizeof("$argon2d$m=8,t=1,p=1$"SALT1"$"HASH1));
+ CANARY_FILL(buf);
errno = 0;
EXPECT(librecrypt_add_algorithm(buf, sizeof(buf), "$~no~such~algorithm~$"HASH1,
"$argon2d$m=8,t=1,p=1$"SALT1"$", NULL) == -1);
EXPECT(errno == ENOSYS);
+ CANARY_CHECK(buf, 0u);
STOP_RESOURCE_TEST();
return 0;
diff --git a/librecrypt_crypt.c b/librecrypt_crypt.c
index ac35191..d116f87 100644
--- a/librecrypt_crypt.c
+++ b/librecrypt_crypt.c
@@ -14,7 +14,8 @@ librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phrase, siz
static void
-check(const char *phrase, const char *settings, const char *chain, size_t chain_prefix, const char *hash, size_t hash_prefix)
+check(const char *phrase, const char *settings, const char *chain, size_t chain_prefix, const char *hash,
+ size_t hash_prefix, size_t scratchsize)
{
size_t hashlen = strlen(hash);
size_t len = strlen(phrase);
@@ -25,27 +26,32 @@ check(const char *phrase, const char *settings, const char *chain, size_t chain_
assert(hashlen <= sizeof(buf));
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_crypt(buf, sizeof(buf), phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, hashlen + 1u));
+ CANARY_X_CHECK(buf, hashlen + 1u, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_crypt(buf, hashlen + 1u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, hashlen + 1u));
+ CANARY_X_CHECK(buf, hashlen + 1u, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_crypt(buf, hashlen, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, hashlen - 1u));
- EXPECT(!buf[hashlen]);
+ EXPECT(!buf[hashlen - 1u]);
+ CANARY_X_CHECK(buf, hashlen, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_crypt(buf, 2u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, 1u));
EXPECT(!buf[1u]);
+ CANARY_X_CHECK(buf, 2u, 2u);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_crypt(buf, 1u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!buf[0u]);
+ CANARY_X_CHECK(buf, 1u, 1u);
EXPECT(librecrypt_crypt(buf, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(librecrypt_crypt(NULL, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
@@ -55,22 +61,29 @@ check(const char *phrase, const char *settings, const char *chain, size_t chain_
r = librecrypt_decode(expected, sizeof(expected), &hash[hash_prefix], hashlen - hash_prefix, lut, pad, strict_pad);
assert(r > 0 && (size_t)r <= sizeof(expected));
+ CANARY_FILL(buf);
+ CANARY_FILL(buf2);
EXPECT(librecrypt_crypt(buf, sizeof(buf), expected, (size_t)r, settings, NULL) == (ssize_t)hashlen);
errno = 0;
EXPECT(librecrypt_crypt(buf2, sizeof(buf2), phrase, len, chain, NULL) == (ssize_t)(hashlen - hash_prefix + chain_prefix));
EXPECT(!memcmp(buf2, chain, chain_prefix));
EXPECT(!memcmp(&buf[hash_prefix], &buf2[chain_prefix], hashlen - hash_prefix + 1u));
+ CANARY_X_CHECK(buf, hashlen, scratchsize);
+ CANARY_X_CHECK(buf2, hashlen - hash_prefix + chain_prefix, scratchsize);
}
#define CHECK(PHRASE, CONF, HASHLEN, IS_DEFAULT_HASHLEN, HASH)\
do {\
+ size_t scratchsize = GET_SCRATCH_SIZE(HASHLEN);\
check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH,\
- sizeof(CONF "*" #HASHLEN ">" CONF) - 1u, CONF HASH, sizeof(CONF) - 1u);\
+ sizeof(CONF "*" #HASHLEN ">" CONF) - 1u, CONF HASH, sizeof(CONF) - 1u, scratchsize);\
check(PHRASE, CONF "*" #HASHLEN, CONF "*" #HASHLEN ">" CONF "*" #HASHLEN,\
- sizeof(CONF "*" #HASHLEN ">" CONF) - 1u, CONF HASH, sizeof(CONF) - 1u);\
- if (IS_DEFAULT_HASHLEN)\
- check(PHRASE, CONF, CONF ">" CONF, sizeof(CONF ">" CONF) - 1u, CONF HASH, sizeof(CONF) - 1u);\
+ sizeof(CONF "*" #HASHLEN ">" CONF) - 1u, CONF HASH, sizeof(CONF) - 1u, scratchsize);\
+ if (IS_DEFAULT_HASHLEN) {\
+ check(PHRASE, CONF, CONF ">" CONF, sizeof(CONF ">" CONF) - 1u,\
+ CONF HASH, sizeof(CONF) - 1u, scratchsize);\
+ }\
} while (0)
@@ -96,6 +109,7 @@ main(void)
libtest_getrandom_error = ENOSYS;
#endif
+#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, 1, "/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY");
CHECK("password", "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$", 32, 1, "iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8");
@@ -115,7 +129,6 @@ main(void)
"yLKZMg+DIOXVc9z1po9ZlZG8+Gp4g5brqfza3lvkR9vw");
CHECK_BAD("$argon2d$");
#endif
-
#if defined(SUPPORT_ARGON2ID)
assert(!libtest_getentropy_error);
@@ -127,6 +140,7 @@ main(void)
* of "ABCD", rather the become "AAECAwABAgMAAQIDAAECAwAB" */
libtest_random_pattern_length = 4u;
libtest_random_pattern_offset = 0u;
+ CANARY_FILL(buf);
r = librecrypt_crypt(buf, sizeof(buf), "", 0u, "$argon2id$v=19$m=8,t=1,p=1$*18$*33", NULL);
libtest_random_pattern = NULL;
libtest_random_pattern_length = 0u;
@@ -136,15 +150,19 @@ main(void)
assert((size_t)r < sizeof(buf));
EXPECT((size_t)r == sizeof("$argon2id$v=19$m=8,t=1,p=1$$") - 1u + 24u + 44u);
EXPECT(!buf[r]);
+ CANARY_FILL(buf2);
EXPECT(librecrypt_crypt(buf2, sizeof(buf2), "", 0u, buf, NULL) == r);
EXPECT(!memcmp(buf, buf2, (size_t)r + 1u));
EXPECT(!memcmp(buf, "$argon2id$v=19$m=8,t=1,p=1$ABCDABCDABCDABCDABCDABCD$",
sizeof("$argon2id$v=19$m=8,t=1,p=1$ABCDABCDABCDABCDABCDABCD$") - 1u));
+ CANARY_X_CHECK(buf, (size_t)r + 1u, 33u);
+ CANARY_X_CHECK(buf2, (size_t)r + 1u, 33u);
libtest_getentropy_real = 0;
libtest_random_pattern = (const unsigned char *)"\x00\x01\x02\03";
libtest_random_pattern_length = 4u;
libtest_random_pattern_offset = 0u;
+ CANARY_FILL(buf);
r = librecrypt_crypt(buf, sizeof(buf), "", 0u, "$argon2id$v=19$m=8,t=1,p=1$*18$*33>"
"$argon2id$v=19$m=8,t=1,p=1$*18$*33", NULL);
libtest_random_pattern = NULL;
@@ -155,13 +173,17 @@ main(void)
assert((size_t)r < sizeof(buf));
EXPECT((size_t)r == sizeof("$argon2id$v=19$m=8,t=1,p=1$$*33>$argon2id$v=19$m=8,t=1,p=1$$") - 1u + 2u * 24u + 44u);
EXPECT(!buf[r]);
+ CANARY_FILL(buf2);
EXPECT(librecrypt_crypt(buf2, sizeof(buf2), "", 0u, buf, NULL) == r);
EXPECT(!memcmp(buf, buf2, (size_t)r + 1u));
EXPECT(!memcmp(buf, "$argon2id$v=19$m=8,t=1,p=1$ABCDABCDABCDABCDABCDABCD$*33>"
"$argon2id$v=19$m=8,t=1,p=1$ABCDABCDABCDABCDABCDABCD$",
sizeof("$argon2id$v=19$m=8,t=1,p=1$ABCDABCDABCDABCDABCDABCD$*33>"
"$argon2id$v=19$m=8,t=1,p=1$ABCDABCDABCDABCDABCDABCD$") - 1u));
+ CANARY_X_CHECK(buf, (size_t)r + 1u, 33u);
+ CANARY_X_CHECK(buf2, (size_t)r + 1u, 33u);
#endif
+#undef GET_SCRATCH_SIZE
#if defined(__linux__)
libtest_getrandom_real = 1;
diff --git a/librecrypt_decode.c b/librecrypt_decode.c
index 3981612..5d09efa 100644
--- a/librecrypt_decode.c
+++ b/librecrypt_decode.c
@@ -184,34 +184,30 @@ check(const char *binary, size_t binary_len, const char *ascii, size_t unpadded_
/* Test output, with and without truncation */
for (i = 0u; i < sizeof(buf); i++) {
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_decode(buf, i, ascii, unpadded_len, lut, '\0', 0) == (ssize_t)binary_len);
j = MIN(i, binary_len);
EXPECT(!memcmp(buf, binary, j));
- for (; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, j);
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_decode(buf, i, ascii, unpadded_len, lut, '\0', 1) == (ssize_t)binary_len);
j = MIN(i, binary_len);
EXPECT(!memcmp(buf, binary, j));
- for (; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, j);
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_decode(buf, i, ascii, unpadded_len, lut, '=', 0) == (ssize_t)binary_len);
j = MIN(i, binary_len);
EXPECT(!memcmp(buf, binary, j));
- for (; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, j);
if (padded_len == unpadded_len) {
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_decode(buf, i, ascii, unpadded_len, lut, '=', 1) == (ssize_t)binary_len);
j = MIN(i, binary_len);
EXPECT(!memcmp(buf, binary, j));
- for (; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, j);
} else {
errno = 0;
EXPECT(librecrypt_decode(buf, i, ascii, unpadded_len, lut, '=', 1) == -1);
@@ -226,20 +222,18 @@ check(const char *binary, size_t binary_len, const char *ascii, size_t unpadded_
EXPECT(errno == EINVAL);
}
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_decode(buf, i, ascii, padded_len, lut, '=', 0) == (ssize_t)binary_len);
j = MIN(i, binary_len);
EXPECT(!memcmp(buf, binary, j));
- for (; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, j);
if (check_good_padding) {
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_decode(buf, i, ascii, padded_len, lut, '=', 1) == (ssize_t)binary_len);
j = MIN(i, binary_len);
EXPECT(!memcmp(buf, binary, j));
- for (; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, j);
}
}
diff --git a/librecrypt_decompose_chain.c b/librecrypt_decompose_chain.c
index ae58c6c..9db1d6c 100644
--- a/librecrypt_decompose_chain.c
+++ b/librecrypt_decompose_chain.c
@@ -46,26 +46,33 @@ main(void)
INIT_RESOURCE_TEST();
/* Check HASH_1 with different sizes of `chain` */
+ CANARY_FILL(buf);
stpcpy(buf, HASH_1);
EXPECT(librecrypt_decompose_chain(buf, chain, 0u) == 1u);
EXPECT(!strcmp(buf, HASH_1));
+ CANARY_CHECK(buf, sizeof(HASH_1));
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 1u) == 1u);
EXPECT(!strcmp(buf, HASH_1));
EXPECT(chain[0u] == buf);
+ CANARY_CHECK(buf, sizeof(HASH_1));
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, ELEMSOF(chain)) == 1u);
EXPECT(!strcmp(buf, HASH_1));
EXPECT(chain[0u] == buf);
+ CANARY_CHECK(buf, sizeof(HASH_1));
/* Check HASH_2 with different sizes of `chain` */
+ CANARY_FILL(buf);
stpcpy(buf, HASH_2);
EXPECT(librecrypt_decompose_chain(buf, chain, 0u) == 3u);
EXPECT(!strcmp(buf, HASH_2));
+ CANARY_CHECK(buf, sizeof(HASH_2));
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 1u) == 3u);
EXPECT(!strcmp(buf, HASH_2));
EXPECT(chain[0u] == buf);
+ CANARY_CHECK(buf, sizeof(HASH_2));
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 2u) == 3u);
EXPECT(chain[0u] != NULL);
@@ -73,6 +80,9 @@ main(void)
EXPECT(chain[2u] == NULL);
EXPECT(!strcmp(chain[0u], HASH_2_A));
EXPECT(!strcmp(chain[1u], HASH_2_BC));
+ CANARY_CHECK(buf, sizeof(HASH_2));
+
+ CANARY_FILL(buf);
stpcpy(buf, HASH_2);
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, ELEMSOF(chain)) == 3u);
@@ -83,15 +93,19 @@ main(void)
EXPECT(!strcmp(chain[0u], HASH_2_A));
EXPECT(!strcmp(chain[1u], HASH_2_B));
EXPECT(!strcmp(chain[2u], HASH_2_C));
+ CANARY_CHECK(buf, sizeof(HASH_2));
/* Check HASH_3 with different sizes of `chain` */
+ CANARY_FILL(buf);
stpcpy(buf, HASH_3);
EXPECT(librecrypt_decompose_chain(buf, chain, 0u) == 5u);
EXPECT(!strcmp(buf, HASH_3));
+ CANARY_CHECK(buf, sizeof(HASH_3));
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 1u) == 5u);
EXPECT(!strcmp(buf, HASH_3));
EXPECT(chain[0u] == buf);
+ CANARY_CHECK(buf, sizeof(HASH_3));
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 2u) == 5u);
EXPECT(chain[0u] != NULL);
@@ -99,6 +113,9 @@ main(void)
EXPECT(chain[2u] == NULL);
EXPECT(!strcmp(chain[0u], HASH_3_A));
EXPECT(!strcmp(chain[1u], HASH_3_BCDE));
+ CANARY_CHECK(buf, sizeof(HASH_3));
+
+ CANARY_FILL(buf);
stpcpy(buf, HASH_3);
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 3u) == 5u);
@@ -109,6 +126,9 @@ main(void)
EXPECT(!strcmp(chain[0u], HASH_3_A));
EXPECT(!strcmp(chain[1u], HASH_3_B));
EXPECT(!strcmp(chain[2u], HASH_3_CDE));
+ CANARY_CHECK(buf, sizeof(HASH_3));
+
+ CANARY_FILL(buf);
stpcpy(buf, HASH_3);
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 4u) == 5u);
@@ -121,6 +141,9 @@ main(void)
EXPECT(!strcmp(chain[1u], HASH_3_B));
EXPECT(!strcmp(chain[2u], HASH_3_C));
EXPECT(!strcmp(chain[3u], HASH_3_DE));
+ CANARY_CHECK(buf, sizeof(HASH_3));
+
+ CANARY_FILL(buf);
stpcpy(buf, HASH_3);
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 5u) == 5u);
@@ -135,6 +158,9 @@ main(void)
EXPECT(!strcmp(chain[2u], HASH_3_C));
EXPECT(!strcmp(chain[3u], HASH_3_D));
EXPECT(!strcmp(chain[4u], HASH_3_E));
+ CANARY_CHECK(buf, sizeof(HASH_3));
+
+ CANARY_FILL(buf);
stpcpy(buf, HASH_3);
NULL_OUT(chain);
EXPECT(librecrypt_decompose_chain(buf, chain, 6u) == 5u);
@@ -149,6 +175,7 @@ main(void)
EXPECT(!strcmp(chain[2u], HASH_3_C));
EXPECT(!strcmp(chain[3u], HASH_3_D));
EXPECT(!strcmp(chain[4u], HASH_3_E));
+ CANARY_CHECK(buf, sizeof(HASH_3));
STOP_RESOURCE_TEST();
return 0;
diff --git a/librecrypt_decompose_chain1.c b/librecrypt_decompose_chain1.c
index 6eece8d..6fc8a63 100644
--- a/librecrypt_decompose_chain1.c
+++ b/librecrypt_decompose_chain1.c
@@ -13,11 +13,13 @@ extern inline size_t librecrypt_decompose_chain1(char *hash);
do {\
assert(sizeof(IN) <= sizeof(buf));\
assert(sizeof(IN) == sizeof(OUT));\
+ CANARY_FILL(buf);\
stpcpy(buf, (IN));\
n = librecrypt_decompose_chain1(buf);\
EXPECT(n == (N));\
EXPECT(n == librecrypt_chain_length(IN));\
EXPECT(!memcmp(buf, (OUT), sizeof(IN)));\
+ CANARY_CHECK(buf, sizeof(IN));\
} while (0)
diff --git a/librecrypt_encode.c b/librecrypt_encode.c
index 6c81b33..ec371cc 100644
--- a/librecrypt_encode.c
+++ b/librecrypt_encode.c
@@ -156,17 +156,16 @@ check(const char *binary, size_t binary_len, const char *ascii, size_t ascii_len
/* Check encoding requests, with and without truncation, without padding */
for (i = 0u; i <= ascii_len; i++) {
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_encode(buf, i + 1u, binary, binary_len, lut, '\0') == ascii_len);
EXPECT(!memcmp(buf, ascii, i));
EXPECT(buf[i] == '\0');
- for (j = i + 1u; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, i + 1u);
}
/* Check encoding requests, with and without truncation, with padding */
for (i = 0u; i <= padded_ascii_len; i++) {
- memset(buf, 99, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_encode(buf, i + 1u, binary, binary_len, lut, '=') == padded_ascii_len);
j = MIN(i, ascii_len);
n = MIN(i, padded_ascii_len);
@@ -174,8 +173,7 @@ check(const char *binary, size_t binary_len, const char *ascii, size_t ascii_len
for (; j < n; j++)
EXPECT(buf[j] == '=');
EXPECT(buf[j++] == '\0');
- for (; j < sizeof(buf); j++)
- EXPECT(buf[j] == 99);
+ CANARY_CHECK(buf, j);
}
}
diff --git a/librecrypt_fill_with_random_.c b/librecrypt_fill_with_random_.c
index 1361652..a1acc84 100644
--- a/librecrypt_fill_with_random_.c
+++ b/librecrypt_fill_with_random_.c
@@ -106,8 +106,17 @@ main(void)
EXPECT(librecrypt_fill_with_random_(buf2, sizeof(buf1), NULL, NULL) == 0);
EXPECT(memcmp(buf1, buf2, sizeof(buf1)));
+ /* Check that it is not writing too much */
+ CANARY_FILL(buf1);
+ CANARY_FILL(buf2);
+ EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1) / 2u, NULL, NULL) == 0);
+ EXPECT(librecrypt_fill_with_random_(buf2, sizeof(buf2) / 2u, NULL, NULL) == 0);
+ EXPECT(memcmp(buf1, buf2, sizeof(buf1) / 2u));
+ CANARY_CHECK(buf1, sizeof(buf1) / 2u);
+ CANARY_CHECK(buf2, sizeof(buf2) / 2u);
+
/* Check stateless all-at-once RNG */
- memset(buf1, 99, sizeof(buf1));
+ CANARY_FILL(buf1);
errno = 0;
EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), &zero, NULL) == 0);
EXPECT(errno == 0);
@@ -115,7 +124,7 @@ main(void)
EXPECT(!buf1[i]);
/* Check stateful chunked RNG (importantly, chunks are smaller than pattern) */
- memset(buf1, 99, sizeof(buf1));
+ CANARY_FILL(buf1);
s = 0u;
errno = 0;
EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), &seq, &s) == 0);
@@ -124,7 +133,7 @@ main(void)
EXPECT(buf1[i] == s);
/* Check stateful one-byte-per-call RNG */
- memset(buf1, 99, sizeof(buf1));
+ CANARY_FILL(buf1);
s = 0u;
errno = 0;
EXPECT(librecrypt_fill_with_random_(buf1, sizeof(buf1), &next, &s) == 0);
@@ -133,13 +142,12 @@ main(void)
EXPECT(buf1[i] == s);
/* Check failure in RNG */
- memset(buf1, 99, sizeof(buf1));
+ CANARY_FILL(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);
+ CANARY_CHECK(buf1, 0u);
/* Check function abort(3)s if RNG returns 0 */
EXPECT_ABORT(rv = librecrypt_fill_with_random_(buf1, sizeof(buf1), &zero_ret, NULL));
diff --git a/librecrypt_hash.c b/librecrypt_hash.c
index 66784d4..69b8dcf 100644
--- a/librecrypt_hash.c
+++ b/librecrypt_hash.c
@@ -14,7 +14,7 @@ librecrypt_hash(char *restrict out_buffer, size_t size, const char *phrase, size
static void
-check(const char *phrase, const char *settings, const char *chain, const char *hash)
+check(const char *phrase, const char *settings, const char *chain, const char *hash, size_t scratchsize)
{
size_t hashlen = strlen(hash);
size_t len = strlen(phrase);
@@ -26,29 +26,36 @@ check(const char *phrase, const char *settings, const char *chain, const char *h
assert(hashlen <= sizeof(buf));
assert(hashlen < sizeof(expected));
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash(buf, sizeof(buf), phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, hashlen + 1u));
+ CANARY_X_CHECK(buf, hashlen + 1u, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash(buf, hashlen + 1u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, hashlen + 1u));
+ CANARY_X_CHECK(buf, hashlen + 1u, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash(buf, hashlen, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, hashlen - 1u));
- EXPECT(!buf[hashlen]);
+ EXPECT(!buf[hashlen - 1]);
+ CANARY_X_CHECK(buf, hashlen, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash(buf, 2u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(hash, buf, 1u));
EXPECT(!buf[1u]);
+ CANARY_X_CHECK(buf, 2u, 2u);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash(buf, 1u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!buf[0u]);
+ CANARY_X_CHECK(buf, 1u, 1u);
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash(buf, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
+ CANARY_X_CHECK(buf, 0u, 0u);
EXPECT(librecrypt_hash(NULL, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
lut = librecrypt_get_encoding(settings, strlen(settings), &pad, &strict_pad, 1);
@@ -56,19 +63,24 @@ check(const char *phrase, const char *settings, const char *chain, const char *h
r = librecrypt_decode(expected, sizeof(expected), hash, strlen(hash), lut, pad, strict_pad);
assert(r > 0 && (size_t)r <= sizeof(expected));
+ CANARY_FILL(buf);
+ CANARY_FILL(buf2);
EXPECT(librecrypt_hash(buf, sizeof(buf), expected, (size_t)r, settings, NULL) == (ssize_t)hashlen);
errno = 0;
EXPECT(librecrypt_hash(buf2, sizeof(buf2), phrase, len, chain, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(buf, buf2, hashlen + 1u));
+ CANARY_X_CHECK(buf, hashlen + 2, scratchsize);
+ CANARY_X_CHECK(buf2, hashlen + 2, scratchsize);
}
#define CHECK(PHRASE, CONF, HASHLEN, IS_DEFAULT_HASHLEN, HASH)\
do {\
- check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH, HASH);\
- check(PHRASE, CONF "*" #HASHLEN, CONF "*" #HASHLEN ">" CONF "*" #HASHLEN, HASH);\
+ size_t scratchsize = GET_SCRATCH_SIZE(HASHLEN);\
+ check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH, HASH, scratchsize);\
+ check(PHRASE, CONF "*" #HASHLEN, CONF "*" #HASHLEN ">" CONF "*" #HASHLEN, HASH, scratchsize);\
if (IS_DEFAULT_HASHLEN)\
- check(PHRASE, CONF, CONF ">" CONF, HASH);\
+ check(PHRASE, CONF, CONF ">" CONF, HASH, scratchsize);\
} while (0)
@@ -110,6 +122,7 @@ main(void)
SET_UP_ALARM();
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, 1, "/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY");
CHECK("password", "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$", 32, 1, "iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8");
@@ -129,6 +142,7 @@ main(void)
"yLKZMg+DIOXVc9z1po9ZlZG8+Gp4g5brqfza3lvkR9vw");
CHECK_BAD("$argon2d$");
#endif
+#undef GET_SCRATCH_SIZE
STOP_RESOURCE_TEST();
return 0;
diff --git a/librecrypt_hash_.c b/librecrypt_hash_.c
index a09d921..7438a48 100644
--- a/librecrypt_hash_.c
+++ b/librecrypt_hash_.c
@@ -368,19 +368,26 @@ main(void)
# define ARGON2ID_PREFIX "$argon2id$v=19$m=8,t=1,p=1$"
# define ARGON2ID_STR ARGON2ID_PREFIX SALT"$*32"
+ CANARY_FILL(buf);
errno = 0;
EXPECT(librecrypt_hash_(buf, sizeof(buf), "hello", 5u, "!"ARGON2ID_STR, NULL, ASCII_CRYPT) == -1);
EXPECT(errno == ENOSYS);
+ CANARY_CHECK(buf, 0u);
+ CANARY_FILL(buf);
errno = 0;
EXPECT(librecrypt_hash_(buf, sizeof(buf), "hello", 5u, ARGON2ID_PREFIX"*"LARGE"$", NULL, ASCII_CRYPT) == -1);
EXPECT(errno == ENOMEM);
+ CANARY_CHECK(buf, sizeof(ARGON2ID_PREFIX"*"));
r = librecrypt_hash_(NULL, 0u, "hello", 5u, ARGON2ID_PREFIX"*1000$", NULL, ASCII_CRYPT);
EXPECT(r > 0);
EXPECT(librecrypt_hash_(NULL, 0u, NULL, 0u, ARGON2ID_PREFIX"*1000$", NULL, ASCII_CRYPT) == r);
- for (i = 0u; i <= sizeof(sbuf); i++)
+ for (i = 0u; i <= sizeof(sbuf); i++) {
+ CANARY_FILL(sbuf);
EXPECT(librecrypt_hash_(sbuf, i, NULL, 0u, ARGON2ID_PREFIX"*1000$", NULL, ASCII_CRYPT) == r);
+ CANARY_X_CHECK(sbuf, (size_t)r, MIN(i, 32u));
+ }
if (libtest_have_custom_malloc()) {
/* target if-statement in zero_generator, using alloc failure as guarding;
@@ -434,6 +441,7 @@ main(void)
}
+ CANARY_FILL(buf1);
memset(buf1, 99, sizeof(buf1));
r1 = librecrypt_hash_(buf1, sizeof(buf1), NULL, 0u, X2(ARGON2ID_STR), NULL, ASCII_CRYPT);
EXPECT(r1 > 0);
@@ -445,13 +453,13 @@ main(void)
EXPECT(r1c > 0);
EXPECT(r1c == r1 + 2 * (ssize_t)sizeof(ARGON2ID_STR));
- memset(buf2, 99, sizeof(buf2));
+ CANARY_FILL(buf2);
EXPECT((r2 = librecrypt_hash_(buf2, sizeof(buf2), NULL, 0u, X2(ARGON2ID_STR), NULL, ASCII_HASH)) > 0);
EXPECT(librecrypt_hash_(buf, sizeof(buf), NULL, 0u, X3(ARGON2ID_STR), NULL, ASCII_HASH) == r2);
- EXPECT(librecrypt_hash_(buf, sizeof(buf), NULL, 0u, X4(ARGON2ID_STR), NULL, ASCII_HASH == r2));
+ EXPECT(librecrypt_hash_(buf, sizeof(buf), NULL, 0u, X4(ARGON2ID_STR), NULL, ASCII_HASH) == r2);
EXPECT(r2 < r1);
- memset(buf3, 99, sizeof(buf3));
+ CANARY_FILL(buf3);
EXPECT((r3 = librecrypt_hash_(buf3, sizeof(buf3), NULL, 0u, X2(ARGON2ID_STR), NULL, BINARY_HASH)) > 0);
EXPECT(librecrypt_hash_(buf, sizeof(buf), NULL, 0u, X3(ARGON2ID_STR), NULL, BINARY_HASH) == r3);
EXPECT(librecrypt_hash_(buf, sizeof(buf), NULL, 0u, X4(ARGON2ID_STR), NULL, BINARY_HASH) == r3);
@@ -460,30 +468,37 @@ main(void)
assert((size_t)r1 < sizeof(buf) - 11u);
for (i = (size_t)r1 + 11u; i < SIZE_MAX; i--) {
if (i <= (size_t)r1 + 10u) {
- memset(buf, 88, sizeof(buf));
+ CANARY_C_FILL(88, buf);
EXPECT(librecrypt_hash_(buf, i, NULL, 0u, X2(ARGON2ID_STR), NULL, ASCII_CRYPT) == r1);
if (i) {
n = MIN(i - 1u, (size_t)r1);
EXPECT(!memcmp(buf, buf1, n));
EXPECT(buf[n] == '\0');
}
+ CANARY_X_CHECK(buf, (size_t)r1, MIN(i, 32u));
}
if (i <= (size_t)r2 + 10u) {
- memset(buf, 88, sizeof(buf));
+ CANARY_C_FILL(88, buf);
EXPECT(librecrypt_hash_(buf, i, NULL, 0u, X2(ARGON2ID_STR), NULL, ASCII_HASH) == r2);
if (i) {
n = MIN(i - 1u, (size_t)r2);
EXPECT(!memcmp(buf, buf2, n));
EXPECT(buf[n] == '\0');
}
+ CANARY_X_CHECK(buf, (size_t)r2, MIN(i, 32u));
}
if (i <= (size_t)r3 + 10u) {
- memset(buf, 88, sizeof(buf));
+ CANARY_C_FILL(88, buf);
EXPECT(librecrypt_hash_(buf, i, NULL, 0u, X2(ARGON2ID_STR), NULL, BINARY_HASH) == r3);
EXPECT(!memcmp(buf, buf3, MIN(i, (size_t)r3)));
+ CANARY_X_CHECK(buf, MIN(i, (size_t)r3), MIN(i, 32u));
}
}
+ CANARY_X_CHECK(buf1, (size_t)r1, 32u);
+ CANARY_X_CHECK(buf2, (size_t)r2, 32u);
+ CANARY_X_CHECK(buf3, (size_t)r3, 32u);
+
EXPECT(librecrypt_hash_(NULL, 0u, NULL, 0u, X2(ARGON2ID_STR), NULL, ASCII_CRYPT) == r1);
EXPECT(librecrypt_hash_(NULL, 0u, NULL, 0u, X3(ARGON2ID_STR), NULL, ASCII_CRYPT) == r1b);
EXPECT(librecrypt_hash_(NULL, 0u, NULL, 0u, X4(ARGON2ID_STR), NULL, ASCII_CRYPT) == r1c);
diff --git a/librecrypt_hash_binary.c b/librecrypt_hash_binary.c
index ee2b8ca..9987758 100644
--- a/librecrypt_hash_binary.c
+++ b/librecrypt_hash_binary.c
@@ -14,7 +14,7 @@ librecrypt_hash_binary(char *restrict out_buffer, size_t size, const char *phras
static void
-check(const char *phrase, const char *settings, const char *chain, const char *hash, size_t hashlen)
+check(const char *phrase, const char *settings, const char *chain, const char *hash, size_t hashlen, size_t scratchsize)
{
size_t len = strlen(phrase);
char buf[1024], buf2[sizeof(buf)], expected[256], pad;
@@ -31,34 +31,44 @@ check(const char *phrase, const char *settings, const char *chain, const char *h
r = librecrypt_decode(expected, sizeof(expected), hash, strlen(hash), lut, pad, strict_pad);
assert(r > 0 && (size_t)r == hashlen);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash_binary(buf, sizeof(buf), phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(buf, expected, hashlen));
+ CANARY_X_CHECK(buf, hashlen, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash_binary(buf, hashlen, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(buf, expected, hashlen));
+ CANARY_X_CHECK(buf, hashlen, scratchsize);
- memset(buf, 0, sizeof(buf));
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash_binary(buf, 1u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(buf, expected, 1u));
+ CANARY_X_CHECK(buf, 1u, 1u);
+ CANARY_FILL(buf);
EXPECT(librecrypt_hash_binary(buf, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
+ CANARY_X_CHECK(buf, 0u, 0u);
EXPECT(librecrypt_hash_binary(NULL, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
+ CANARY_FILL(buf);
+ CANARY_FILL(buf2);
EXPECT(librecrypt_hash_binary(buf, sizeof(buf), expected, hashlen, settings, NULL) == (ssize_t)hashlen);
errno = 0;
EXPECT(librecrypt_hash_binary(buf2, sizeof(buf2), phrase, len, chain, NULL) == (ssize_t)hashlen);
EXPECT(!memcmp(buf, buf2, hashlen));
+ CANARY_X_CHECK(buf, hashlen, scratchsize);
+ CANARY_X_CHECK(buf2, hashlen, scratchsize);
}
#define CHECK(PHRASE, CONF, HASHLEN, IS_DEFAULT_HASHLEN, HASH)\
do {\
- check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH, HASH, (size_t)HASHLEN);\
- check(PHRASE, CONF "*" #HASHLEN, CONF "*" #HASHLEN ">" CONF "*" #HASHLEN, HASH, (size_t)HASHLEN);\
+ size_t scratchsize = GET_SCRATCH_SIZE(HASHLEN);\
+ check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH, HASH, (size_t)HASHLEN, scratchsize);\
+ check(PHRASE, CONF "*" #HASHLEN, CONF "*" #HASHLEN ">" CONF "*" #HASHLEN, HASH, (size_t)HASHLEN, scratchsize);\
if (IS_DEFAULT_HASHLEN)\
- check(PHRASE, CONF, CONF ">" CONF, HASH, (size_t)HASHLEN);\
+ check(PHRASE, CONF, CONF ">" CONF, HASH, (size_t)HASHLEN, scratchsize);\
} while (0)
@@ -79,6 +89,7 @@ main(void)
SET_UP_ALARM();
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, 1, "/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY");
CHECK("password", "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ$", 32, 1, "iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8");
@@ -98,6 +109,7 @@ main(void)
"yLKZMg+DIOXVc9z1po9ZlZG8+Gp4g5brqfza3lvkR9vw");
CHECK_BAD("$argon2d$");
#endif
+#undef GET_SCRATCH_SIZE
STOP_RESOURCE_TEST();
return 0;
diff --git a/librecrypt_make_settings.c b/librecrypt_make_settings.c
index 7688061..5bdc6f5 100644
--- a/librecrypt_make_settings.c
+++ b/librecrypt_make_settings.c
@@ -97,40 +97,48 @@ main(void)
#if defined(SUPPORT_ARGON2I)
saltbyte = 0u;
+ CANARY_FILL(buf);
r = librecrypt_make_settings(buf, sizeof(buf), "$argon2i$", 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(!strcmp(buf, "$argon2i$v=19$m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32"));
+ CANARY_CHECK(buf, (size_t)r + 1u);
any_supported = 1;
any_salted = 1;
#endif
#if defined(SUPPORT_ARGON2D)
saltbyte = 0u;
+ CANARY_FILL(buf);
r = librecrypt_make_settings(buf, sizeof(buf), "$argon2d$", 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(!strcmp(buf, "$argon2d$v=19$m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32"));
+ CANARY_CHECK(buf, (size_t)r + 1u);
any_supported = 1;
any_salted = 1;
#endif
#if defined(SUPPORT_ARGON2ID)
saltbyte = 0u;
+ CANARY_FILL(buf);
r = librecrypt_make_settings(buf, sizeof(buf), "$argon2id$", 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(!strcmp(buf, "$argon2id$v=19$m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32"));
+ CANARY_CHECK(buf, (size_t)r + 1u);
any_supported = 1;
any_salted = 1;
#endif
#if defined(SUPPORT_ARGON2DS)
saltbyte = 0u;
+ CANARY_FILL(buf);
r = librecrypt_make_settings(buf, sizeof(buf), "$argon2ds$", 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(!strcmp(buf, "$argon2ds$v=19$m=8192,t=10,p=1$AAAAAAAAAAAAAAAAAAAAAA$*32"));
+ CANARY_CHECK(buf, (size_t)r + 1u);
any_supported = 1;
any_salted = 1;
#endif
@@ -147,26 +155,38 @@ main(void)
EXPECT(librecrypt_make_settings(buf, sizeof(buf), NULL, 0u, 0u, 1, &saltfail, NULL) > 0);
}
+ CANARY_FILL(buf);
+ CANARY_FILL(buf2);
r = librecrypt_make_settings(buf, sizeof(buf), NULL, 0u, 0u, 0, &saltfail, NULL);
EXPECT(r > 0 && (size_t)r < sizeof(buf));
EXPECT(!buf[r] && (size_t)r == strlen(buf));
EXPECT(librecrypt_make_settings(buf2, sizeof(buf2), NULL, 0u, 0u, 0, &saltfail, NULL) == r);
EXPECT(!buf2[r] && (size_t)r == strlen(buf2));
EXPECT(!strcmp(buf, buf2));
+ CANARY_CHECK(buf, (size_t)r + 1u);
+ CANARY_CHECK(buf2, (size_t)r + 1u);
+ CANARY_FILL(buf);
+ CANARY_FILL(buf2);
r = librecrypt_make_settings(buf, sizeof(buf), NULL, 0u, 0u, 0, NULL, NULL);
EXPECT(r > 0 && (size_t)r < sizeof(buf));
EXPECT(!buf[r] && (size_t)r == strlen(buf));
EXPECT(librecrypt_make_settings(buf2, sizeof(buf2), NULL, 0u, 0u, 0, NULL, NULL) == r);
EXPECT(!buf2[r] && (size_t)r == strlen(buf2));
EXPECT(!strcmp(buf, buf2));
+ CANARY_CHECK(buf, (size_t)r + 1u);
+ CANARY_CHECK(buf2, (size_t)r + 1u);
+ CANARY_FILL(buf);
+ CANARY_FILL(buf2);
r = librecrypt_make_settings(buf, sizeof(buf), NULL, 0u, 0u, 1, NULL, NULL);
EXPECT(r > 0 && (size_t)r < sizeof(buf));
EXPECT(!buf[r] && (size_t)r == strlen(buf));
EXPECT(librecrypt_make_settings(buf2, sizeof(buf2), NULL, 0u, 0u, 1, NULL, NULL) == r);
EXPECT(!buf2[r] && (size_t)r == strlen(buf2));
EXPECT(strcmp(buf, buf2));
+ CANARY_CHECK(buf, (size_t)r + 1u);
+ CANARY_CHECK(buf2, (size_t)r + 1u);
} else {
errno = 0;
EXPECT(librecrypt_make_settings(NULL, 0u, NULL, 0u, 0u, 0, NULL, NULL) == -1);
diff --git a/librecrypt_realise_salts.c b/librecrypt_realise_salts.c
index 195afaf..8a4b769 100644
--- a/librecrypt_realise_salts.c
+++ b/librecrypt_realise_salts.c
@@ -270,7 +270,9 @@ main(void)
EXPECT(librecrypt_realise_salts(NULL, 0u, ALGO"*"LARGE"$", &saltgen, &saltbyte) == -1);
EXPECT(errno == ERANGE);
+ CANARY_FILL(buf);
EXPECT(librecrypt_realise_salts(buf, sizeof(ALGO) - 1u, ALGO"*3$", &saltfail, NULL) == (ssize_t)sizeof(ALGO"$") - 1 + 4);
+ CANARY_CHECK(buf, sizeof(ALGO) - 1u);
errno = 0;
EXPECT(librecrypt_realise_salts(buf, sizeof(buf), ALGO"*3$", &saltfail, NULL) == -1);
EXPECT(errno == EDOM);
@@ -293,13 +295,15 @@ main(void)
EXPECT(librecrypt_realise_salts(NULL, 0u, conf, &saltgen, &saltbyte) == -1);
EXPECT(errno == ERANGE);
- memset(buf, 99, sizeof(buf));
- memset(buf2, 99, sizeof(buf2));
+ CANARY_FILL(buf);
+ CANARY_FILL(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));
+ CANARY_CHECK(buf, sizeof(ALGO"$") + 40u);
+ CANARY_CHECK(buf2, sizeof(ALGO"$") + 40u);
#endif
STOP_RESOURCE_TEST();
diff --git a/librecrypt_rng_.c b/librecrypt_rng_.c
index e620c6f..4c6d5dc 100644
--- a/librecrypt_rng_.c
+++ b/librecrypt_rng_.c
@@ -374,18 +374,24 @@ main(void)
#define CHECK1()\
do {\
+ CANARY_FILL(buf1);\
n1 = librecrypt_rng_(buf1, sizeof(buf1), NULL);\
EXPECT(n1 >= 128 && (size_t)n1 <= sizeof(buf1));\
EXPECT(memcmp(buf1, buf2, (size_t)MIN(n1, n2)));\
+ CANARY_CHECK(buf1, (size_t)n1);\
} while (0)
#define CHECK2()\
do {\
+ CANARY_FILL(buf1);\
+ CANARY_FILL(buf2);\
n1 = librecrypt_rng_(buf1, sizeof(buf1), NULL);\
n2 = librecrypt_rng_(buf2, sizeof(buf2), &user);\
EXPECT(n1 >= 128 && (size_t)n1 <= sizeof(buf1));\
EXPECT(n2 >= 128 && (size_t)n2 <= sizeof(buf2));\
EXPECT(memcmp(buf1, buf2, (size_t)MIN(n1, n2)));\
+ CANARY_CHECK(buf1, (size_t)n1);\
+ CANARY_CHECK(buf2, (size_t)n2);\
} while (0)
/* Test with output pattern (useful for other tests) */