aboutsummaryrefslogtreecommitdiffstats
path: root/librecrypt_crypt.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-14 10:47:23 +0200
committerMattias Andrée <m@maandree.se>2026-05-14 10:47:23 +0200
commitb1d4927aa3d1d1b31034ede3eeb374efcdcfed0d (patch)
tree088d55cefd7673ce2e9741aaa5b20cb0fc5603bd /librecrypt_crypt.c
parentTests and fixes (diff)
downloadlibrecrypt-b1d4927aa3d1d1b31034ede3eeb374efcdcfed0d.tar.gz
librecrypt-b1d4927aa3d1d1b31034ede3eeb374efcdcfed0d.tar.bz2
librecrypt-b1d4927aa3d1d1b31034ede3eeb374efcdcfed0d.tar.xz
Tests and fixes
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'librecrypt_crypt.c')
-rw-r--r--librecrypt_crypt.c88
1 files changed, 81 insertions, 7 deletions
diff --git a/librecrypt_crypt.c b/librecrypt_crypt.c
index c41a9c4..ac35191 100644
--- a/librecrypt_crypt.c
+++ b/librecrypt_crypt.c
@@ -14,11 +14,14 @@ librecrypt_crypt(char *restrict out_buffer, size_t size, const char *phrase, siz
static void
-check(const char *phrase, const char *settings, const char *hash)
+check(const char *phrase, const char *settings, const char *chain, size_t chain_prefix, const char *hash, size_t hash_prefix)
{
size_t hashlen = strlen(hash);
size_t len = strlen(phrase);
- char buf[1024];
+ char buf[1024], buf2[sizeof(buf)], expected[sizeof(buf)], pad;
+ int strict_pad;
+ const void *lut;
+ ssize_t r;
assert(hashlen <= sizeof(buf));
@@ -46,15 +49,28 @@ check(const char *phrase, const char *settings, const char *hash)
EXPECT(librecrypt_crypt(buf, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(librecrypt_crypt(NULL, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
+
+ lut = librecrypt_get_encoding(settings, strlen(settings), &pad, &strict_pad, 1);
+ assert(lut);
+ r = librecrypt_decode(expected, sizeof(expected), &hash[hash_prefix], hashlen - hash_prefix, lut, pad, strict_pad);
+ assert(r > 0 && (size_t)r <= sizeof(expected));
+
+ 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));
}
#define CHECK(PHRASE, CONF, HASHLEN, IS_DEFAULT_HASHLEN, HASH)\
do {\
- check(PHRASE, CONF HASH, CONF HASH);\
- check(PHRASE, CONF "*" #HASHLEN, CONF HASH);\
+ check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH,\
+ sizeof(CONF "*" #HASHLEN ">" CONF) - 1u, CONF HASH, sizeof(CONF) - 1u);\
+ 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 HASH);\
+ check(PHRASE, CONF, CONF ">" CONF, sizeof(CONF ">" CONF) - 1u, CONF HASH, sizeof(CONF) - 1u);\
} while (0)
@@ -69,9 +85,17 @@ check(const char *phrase, const char *settings, const char *hash)
int
main(void)
{
+ char buf[1024], buf2[1024];
+ ssize_t r;
+
SET_UP_ALARM();
INIT_RESOURCE_TEST();
+#if defined(__linux__)
+ libtest_getrandom_real = 0;
+ libtest_getrandom_error = ENOSYS;
+#endif
+
#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");
@@ -92,11 +116,61 @@ main(void)
CHECK_BAD("$argon2d$");
#endif
+#if defined(SUPPORT_ARGON2ID)
+ assert(!libtest_getentropy_error);
+
+ libtest_getentropy_real = 0;
+ libtest_random_pattern = (const unsigned char *)"\x00\x01\x02\x03";
+ /* since librecrypt_realise_salts doesn't generate random data then base64-encode it,
+ * but rather just takes random characters from base64 alphabet (with restrictions
+ * one the list one if the count isn't a multiple of 4), this will map to a repeation
+ * of "ABCD", rather the become "AAECAwABAgMAAQIDAAECAwAB" */
+ libtest_random_pattern_length = 4u;
+ libtest_random_pattern_offset = 0u;
+ 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;
+ libtest_random_pattern_offset = 0u;
+ libtest_getentropy_real = 1;
+ EXPECT(r > 0);
+ 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]);
+ 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));
+
+ libtest_getentropy_real = 0;
+ libtest_random_pattern = (const unsigned char *)"\x00\x01\x02\03";
+ libtest_random_pattern_length = 4u;
+ libtest_random_pattern_offset = 0u;
+ 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;
+ libtest_random_pattern_length = 0u;
+ libtest_random_pattern_offset = 0u;
+ libtest_getentropy_real = 1;
+ EXPECT(r > 0);
+ 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]);
+ 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));
+#endif
+
+#if defined(__linux__)
+ libtest_getrandom_real = 1;
+ libtest_getrandom_error = 0;
+#endif
+
STOP_RESOURCE_TEST();
return 0;
}
#endif
-/* TODO test chaining */
-/* TODO test salt generation */