diff options
Diffstat (limited to '')
| -rw-r--r-- | librecrypt_crypt.c | 88 | ||||
| -rw-r--r-- | librecrypt_hash.c | 25 | ||||
| -rw-r--r-- | librecrypt_hash_.c | 18 | ||||
| -rw-r--r-- | librecrypt_hash_binary.c | 16 | ||||
| -rw-r--r-- | libtest/config.mk | 8 | ||||
| -rw-r--r-- | libtest/libtest.h | 20 | ||||
| -rw-r--r-- | libtest/random.c | 20 |
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 |
