aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--librecrypt_crypt.c88
-rw-r--r--librecrypt_hash.c25
-rw-r--r--librecrypt_hash_.c18
-rw-r--r--librecrypt_hash_binary.c16
-rw-r--r--libtest/config.mk8
-rw-r--r--libtest/libtest.h20
-rw-r--r--libtest/random.c20
7 files changed, 147 insertions, 48 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 */
diff --git a/librecrypt_hash.c b/librecrypt_hash.c
index f793085..66784d4 100644
--- a/librecrypt_hash.c
+++ b/librecrypt_hash.c
@@ -14,13 +14,17 @@ librecrypt_hash(char *restrict out_buffer, size_t size, const char *phrase, size
static void
-check(const char *phrase, const char *settings, const char *hash)
+check(const char *phrase, const char *settings, const char *chain, const char *hash)
{
size_t hashlen = strlen(hash);
size_t len = strlen(phrase);
- char buf[1024];
+ char buf[1024], buf2[sizeof(buf)], expected[256], pad;
+ int strict_pad;
+ const void *lut;
+ ssize_t r;
assert(hashlen <= sizeof(buf));
+ assert(hashlen < sizeof(expected));
memset(buf, 0, sizeof(buf));
EXPECT(librecrypt_hash(buf, sizeof(buf), phrase, len, settings, NULL) == (ssize_t)hashlen);
@@ -46,15 +50,25 @@ check(const char *phrase, const char *settings, const char *hash)
EXPECT(librecrypt_hash(buf, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(librecrypt_hash(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, strlen(hash), lut, pad, strict_pad);
+ assert(r > 0 && (size_t)r <= sizeof(expected));
+
+ 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));
}
#define CHECK(PHRASE, CONF, HASHLEN, IS_DEFAULT_HASHLEN, HASH)\
do {\
- check(PHRASE, CONF HASH, HASH);\
- check(PHRASE, CONF "*" #HASHLEN, HASH);\
+ check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH, HASH);\
+ check(PHRASE, CONF "*" #HASHLEN, CONF "*" #HASHLEN ">" CONF "*" #HASHLEN, HASH);\
if (IS_DEFAULT_HASHLEN)\
- check(PHRASE, CONF, HASH);\
+ check(PHRASE, CONF, CONF ">" CONF, HASH);\
} while (0)
@@ -122,4 +136,3 @@ main(void)
#endif
-/* TODO test chaining */
diff --git a/librecrypt_hash_.c b/librecrypt_hash_.c
index d9da5e4..14c709b 100644
--- a/librecrypt_hash_.c
+++ b/librecrypt_hash_.c
@@ -14,7 +14,7 @@ zero_generator(void *out, size_t n, void *user)
}
-static int
+PURE static int
has_asterisk_encoded_salt(const char *settings)
{
int asterisk = 0;
@@ -87,14 +87,13 @@ librecrypt_hash_(char *restrict out_buffer, size_t size, const char *phrase, siz
return -1;
}
return -1;
- } else if ((size_t)r_len >= size) {
- settings_scratch = malloc((size_t)r_len + 1u);
- if (!settings_scratch)
- return -1;
- if (librecrypt_realise_salts(settings_scratch, (size_t)r_len + 1u, settings, rng, NULL) != r_len)
- abort(); /* $covered$ (impossible) */
- settings = settings_scratch;
}
+ settings_scratch = malloc((size_t)r_len + 1u);
+ if (!settings_scratch)
+ return -1;
+ if (librecrypt_realise_salts(settings_scratch, (size_t)r_len + 1u, settings, rng, NULL) != r_len)
+ abort(); /* $covered$ (impossible) */
+ settings = settings_scratch;
}
next:
@@ -389,7 +388,7 @@ main(void)
* librecrypt_hash_ coverts to ENOMEM */
libtest_set_alloc_failure_in(1u);
r = (ssize_t)snprintf(buf, sizeof(buf), "%s*%zu$", ARGON2ID_PREFIX, (size_t)SSIZE_MAX + 1u);
- assert(r > 0 && r < sizeof(buf));
+ assert(r > 0 && r < (ssize_t)sizeof(buf));
errno = 0;
EXPECT(librecrypt_hash_(NULL, 0u, NULL, 0u, buf, NULL, ASCII_CRYPT) == -1);
EXPECT(errno == ENOMEM);
@@ -501,6 +500,7 @@ main(void)
STOP_RESOURCE_TEST();
return 0;
}
+/* TODO test mixed algorithm chaining */
#endif
diff --git a/librecrypt_hash_binary.c b/librecrypt_hash_binary.c
index a56c61b..ee2b8ca 100644
--- a/librecrypt_hash_binary.c
+++ b/librecrypt_hash_binary.c
@@ -14,10 +14,10 @@ librecrypt_hash_binary(char *restrict out_buffer, size_t size, const char *phras
static void
-check(const char *phrase, const char *settings, const char *hash, size_t hashlen)
+check(const char *phrase, const char *settings, const char *chain, const char *hash, size_t hashlen)
{
size_t len = strlen(phrase);
- char buf[1024], expected[256], pad;
+ char buf[1024], buf2[sizeof(buf)], expected[256], pad;
int strict_pad;
const void *lut;
ssize_t r;
@@ -45,15 +45,20 @@ check(const char *phrase, const char *settings, const char *hash, size_t hashlen
EXPECT(librecrypt_hash_binary(buf, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
EXPECT(librecrypt_hash_binary(NULL, 0u, phrase, len, settings, NULL) == (ssize_t)hashlen);
+
+ 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));
}
#define CHECK(PHRASE, CONF, HASHLEN, IS_DEFAULT_HASHLEN, HASH)\
do {\
- check(PHRASE, CONF HASH, HASH, (size_t)HASHLEN);\
- check(PHRASE, CONF "*" #HASHLEN, HASH, (size_t)HASHLEN);\
+ check(PHRASE, CONF HASH, CONF "*" #HASHLEN ">" CONF HASH, HASH, (size_t)HASHLEN);\
+ check(PHRASE, CONF "*" #HASHLEN, CONF "*" #HASHLEN ">" CONF "*" #HASHLEN, HASH, (size_t)HASHLEN);\
if (IS_DEFAULT_HASHLEN)\
- check(PHRASE, CONF, HASH, (size_t)HASHLEN);\
+ check(PHRASE, CONF, CONF ">" CONF, HASH, (size_t)HASHLEN);\
} while (0)
@@ -100,4 +105,3 @@ main(void)
#endif
-/* TODO test chaining */
diff --git a/libtest/config.mk b/libtest/config.mk
index 6dff8a9..3b81c3f 100644
--- a/libtest/config.mk
+++ b/libtest/config.mk
@@ -3,3 +3,11 @@ IMPLEMENT_MMAP = true
TEST_CONFIGFILE = config_backtraces=$(WITH_BACKTRACE).mk
include $(TEST_INCLUDE_PREFIX)$(TEST_CONFIGFILE)
+
+# If IMPLEMENT_MMAP is false, it is assumed that libc provides __mmap,
+# __munmap, and __mremap as aliases for mmap, mumap, and mremap. If
+# this isn't the case for your libc, but it provides other aliases,
+# you can add e.g. "-D__mmap=_mmap -D__munmap=_munmap -D__mremap=_mremap"
+# to specify the alises libc provides (in this example _mmap, _munmap,
+# and _mremap). NB! "-D__mmap=mmap -D__munmap=munmap -D__mremap=mremap"
+# is not allowed as libtest overrides mmap(3), munmap(3), and mremap(3).
diff --git a/libtest/libtest.h b/libtest/libtest.h
index 9fa7e56..8f44114 100644
--- a/libtest/libtest.h
+++ b/libtest/libtest.h
@@ -424,18 +424,18 @@ size_t libtest_get_alloc_failure_in(void);
void libtest_set_alloc_failure_in(size_t n);
-extern unsigned char *libtest_random_pattern;
-extern size_t libtest_random_pattern_length;
-extern size_t libtest_random_pattern_offset;
+extern const unsigned char *volatile libtest_random_pattern;
+extern volatile size_t libtest_random_pattern_length;
+extern volatile size_t libtest_random_pattern_offset;
#if defined(__linux__)
-extern int libtest_getrandom_real;
-extern int libtest_getrandom_error;
-extern size_t libtest_getrandom_max_return;
+extern volatile int libtest_getrandom_real;
+extern volatile int libtest_getrandom_error;
+extern volatile size_t libtest_getrandom_max_return;
#endif
-extern int libtest_getentropy_real;
-extern int libtest_getentropy_error;
-extern size_t libtest_getentropy_calls;
-extern int libtest_getentropy_jmp_val;
+extern volatile int libtest_getentropy_real;
+extern volatile int libtest_getentropy_error;
+extern volatile size_t libtest_getentropy_calls;
+extern volatile int libtest_getentropy_jmp_val;
extern jmp_buf libtest_getentropy_jmp;
diff --git a/libtest/random.c b/libtest/random.c
index 2eb22e6..8f0b398 100644
--- a/libtest/random.c
+++ b/libtest/random.c
@@ -3,9 +3,9 @@
#ifndef TEST
-unsigned char *libtest_random_pattern = NULL;
-size_t libtest_random_pattern_length = 0u;
-size_t libtest_random_pattern_offset = 0u;
+const unsigned char *volatile libtest_random_pattern = NULL;
+volatile size_t libtest_random_pattern_length = 0u;
+volatile size_t libtest_random_pattern_offset = 0u;
static ssize_t
genpattern(void *buf, size_t size)
@@ -41,9 +41,9 @@ genpattern(void *buf, size_t size)
#if defined(__linux__)
-int libtest_getrandom_real = 1;
-int libtest_getrandom_error = 0;
-size_t libtest_getrandom_max_return = SIZE_MAX;
+volatile int libtest_getrandom_real = 1;
+volatile int libtest_getrandom_error = 0;
+volatile size_t libtest_getrandom_max_return = SIZE_MAX;
ssize_t
(getrandom)(void *buf, size_t size, unsigned int flags)
@@ -71,10 +71,10 @@ ssize_t
#endif
-int libtest_getentropy_real = 1;
-int libtest_getentropy_error = 0;
-size_t libtest_getentropy_calls = 0u;
-int libtest_getentropy_jmp_val = 0;
+volatile int libtest_getentropy_real = 1;
+volatile int libtest_getentropy_error = 0;
+volatile size_t libtest_getentropy_calls = 0u;
+volatile int libtest_getentropy_jmp_val = 0;
jmp_buf libtest_getentropy_jmp;
int