diff options
| author | Mattias Andrée <m@maandree.se> | 2026-05-16 02:11:29 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-05-16 02:11:29 +0200 |
| commit | 8e7bfadb3eb9f43eb0b670b908b479325722fee5 (patch) | |
| tree | e7f26f67cc4da2846e0ac3f8201e1e82de3c6112 | |
| parent | m (diff) | |
| download | librecrypt-8e7bfadb3eb9f43eb0b670b908b479325722fee5.tar.gz librecrypt-8e7bfadb3eb9f43eb0b670b908b479325722fee5.tar.bz2 librecrypt-8e7bfadb3eb9f43eb0b670b908b479325722fee5.tar.xz | |
Add WITH_LIBAR2SIMPLIFIED=false + work on fuzzing code
Signed-off-by: Mattias Andrée <m@maandree.se>
| -rw-r--r-- | DEPENDENCIES | 6 | ||||
| -rw-r--r-- | Makefile | 16 | ||||
| -rw-r--r-- | argon2/hash.c | 80 | ||||
| -rw-r--r-- | argon2/suffix.mk | 22 | ||||
| -rw-r--r-- | librecrypt_decode.c | 42 | ||||
| -rw-r--r-- | librecrypt_encode.c | 36 | ||||
| -rw-r--r-- | librecrypt_get_encoding.c | 24 | ||||
| -rw-r--r-- | librecrypt_realise_salts.c | 59 | ||||
| -rw-r--r-- | librecrypt_test_supported.c | 38 |
9 files changed, 308 insertions, 15 deletions
diff --git a/DEPENDENCIES b/DEPENDENCIES index 7915221..fb667f0 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -8,6 +8,12 @@ For Argon2 support (runtime, build, and check dependencies): libblake (indirect) pthread (indirect) + Running make(1) with WITH_LIBAR2SIMPLIFIED=false removes + dependency on libar2simplified and pthread (for Argon2), + however, it also disables multithreading for Argon2. It + is advisable to use WITH_LIBAR2SIMPLIFIED=false if you + are only going to use p=1 in the Argon2 parameters. + Build dependencies: libc make @@ -20,13 +20,18 @@ LIB_NAME = recrypt OBJ_PUBLIC_FUZZ =\ - librecrypt_settings_prefix.o + librecrypt_settings_prefix.o\ + librecrypt_test_supported.o\ + librecrypt_realise_salts.o OBJ_PUBLIC_DONT_FUZZ =\ librecrypt_chain_length.o\ librecrypt_decompose_chain.o\ librecrypt_decompose_chain1.o\ - librecrypt_next_algorithm.o + librecrypt_next_algorithm.o\ + librecrypt_encode.o\ + librecrypt_decode.o\ + librecrypt_get_encoding.o OBJ_PUBLIC_NO_FUZZ =\ librecrypt_wipe.o\ @@ -38,16 +43,11 @@ OBJ_PUBLIC =\ $(OBJ_PUBLIC_FUZZ)\ $(OBJ_PUBLIC_DONT_FUZZ)\ $(OBJ_PUBLIC_NO_FUZZ)\ - librecrypt_encode.o\ - librecrypt_decode.o\ - librecrypt_get_encoding.o\ - librecrypt_realise_salts.o\ librecrypt_make_settings.o\ librecrypt_hash_binary.o\ librecrypt_hash.o\ librecrypt_crypt.o\ - librecrypt_add_algorithm.o\ - librecrypt_test_supported.o + librecrypt_add_algorithm.o OBJ_PRIVATE =\ librecrypt_algorithms_.o\ diff --git a/argon2/hash.c b/argon2/hash.c index a40e54c..d06ec1e 100644 --- a/argon2/hash.c +++ b/argon2/hash.c @@ -3,7 +3,11 @@ #ifndef TEST #include <libar2.h> -#include <libar2simplified.h> +#ifndef NO_LIBAR2SIMPLIFIED +# include <libar2simplified.h> +#else +# define libar2simplified_init_context init_context +#endif #define RANGE(MIN, MAX) (uintmax_t)(MIN), (uintmax_t)(MAX) @@ -11,6 +15,80 @@ #define REMOVE_CONST(X) (*(void **)(void *)&(X)) +#ifdef NO_LIBAR2SIMPLIFIED + +static void * +allocate(size_t num, size_t size, size_t alignment, struct libar2_context *ctx) +{ + size_t extra, pad; + void *ptr; + unsigned char *p; + int err; + + (void) ctx; + + alignment = MAX(alignment, sizeof(void *)); + extra = 2u * sizeof(size_t); + pad = -extra & (alignment - 1u); + + err = ENOMEM; + if (num > (SIZE_MAX - extra - pad) / size || + (err = posix_memalign(&ptr, alignment, pad + extra + (size *= num)))) { + errno = err; + return NULL; + } + + p = ptr; + p += pad; + memcpy(p, &pad, sizeof(size_t)); + p += sizeof(size_t); + memcpy(p, &size, sizeof(size_t)); + p += sizeof(size_t); + return p; +} + + +static void +deallocate(void *ptr, struct libar2_context *ctx) +{ + size_t size, pad; + char *p = ptr; + + (void) ctx; + + p -= sizeof(size_t); + memcpy(&size, p, sizeof(size_t)); + p -= sizeof(size_t); + memcpy(&pad, p, sizeof(size_t)); + p -= pad; + + librecrypt_wipe(p, size + pad + 2u * sizeof(size_t)); + free(p); +} + + +static int +init_thread_pool(size_t desired, size_t *createdp, struct libar2_context *ctx) +{ + (void) desired; + (void) ctx; + *createdp = 0u; + return 0; +} + + +static void +init_context(struct libar2_context *ctxp) +{ + memset(ctxp, 0, sizeof(*ctxp)); + ctxp->allocate = &allocate; + ctxp->deallocate = &deallocate; + ctxp->init_thread_pool = &init_thread_pool; +} + +#endif + + int librecrypt__argon2__hash(char *restrict out_buffer, size_t size, const char *phrase, size_t len, const char *settings, size_t prefix, void *reserved) diff --git a/argon2/suffix.mk b/argon2/suffix.mk index 65617b1..5ca2ceb 100644 --- a/argon2/suffix.mk +++ b/argon2/suffix.mk @@ -1,5 +1,7 @@ SUPPORT_ANY_ARGON2 = ($(SUPPORT_ARGON2I) || $(SUPPORT_ARGON2D) || $(SUPPORT_ARGON2ID) || $(SUPPORT_ARGON2DS)) +WITH_LIBAR2SIMPLIFIED = true + HDR += argon2/argon2.h OBJ_ARGON2 !=\ @@ -29,19 +31,27 @@ CPPFLAGS_ARGON2 !=\ ;fi;\ if $(SUPPORT_ARGON2DS); then echo\ -DSUPPORT_ARGON2DS\ + ;fi;\ + if ! $(WITH_LIBAR2SIMPLIFIED); then echo\ + -DNO_LIBAR2SIMPLIFIED\ ;fi CFLAGS_ARGON2 !=\ - if $(SUPPORT_ANY_ARGON2); then echo\ + if $(SUPPORT_ANY_ARGON2) && $(WITH_LIBAR2SIMPLIFIED); then echo\ -pthread\ ;fi LDFLAGS_ARGON2 !=\ - if $(SUPPORT_ANY_ARGON2); then echo\ - -lar2simplified\ - -lar2\ - -lblake\ - -pthread\ + if $(SUPPORT_ANY_ARGON2); then\ + if $(WITH_LIBAR2SIMPLIFIED); then echo\ + -lar2simplified\ + -lar2\ + -lblake\ + -pthread\ + ;else echo\ + -lar2\ + -lblake\ + ;fi\ ;fi CPPFLAGS_MODULES += $(CPPFLAGS_ARGON2) diff --git a/librecrypt_decode.c b/librecrypt_decode.c index 5d09efa..b43373b 100644 --- a/librecrypt_decode.c +++ b/librecrypt_decode.c @@ -131,6 +131,9 @@ static const unsigned char lut[256u] = { }; +# ifndef FUZZ + + #define CHECK(BINARY, ASCII, PAD)\ check((BINARY), sizeof(BINARY) - 1u, (ASCII PAD), sizeof(ASCII) - 1u, sizeof(ASCII PAD) - 1u) @@ -334,4 +337,43 @@ main(void) } +# else + + +extern volatile ssize_t discarded_return_value; +volatile ssize_t discarded_return_value; + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + char *out_buffer; + size_t out_size; + const char *ascii; + char pad; + int strict_pad; + size_t r; + + if (size < 4u) + return 0; + + out_size = ((size_t)data[0u] << 8) | (size_t)data[1u]; + if (out_size) { + out_buffer = malloc(out_size); + assert(out_buffer != NULL); + } else { + out_buffer = NULL; + } + pad = data[2u]; + strict_pad = (int)data[3u] & 1; + ascii = (const void *)&data[4u]; + size -= 4u; + + discarded_return_value = librecrypt_decode(out_buffer, out_size, ascii, size, lut, pad, strict_pad); + + free(out_buffer); + return 0; +} + + +# endif #endif diff --git a/librecrypt_encode.c b/librecrypt_encode.c index df16895..42d77d6 100644 --- a/librecrypt_encode.c +++ b/librecrypt_encode.c @@ -126,6 +126,7 @@ librecrypt_encode(char *out_buffer, size_t size, const void *binary, size_t len, #else +# ifndef FUZZ NONSTRING static const char lut[256u] = MAKE_ENCODING_LUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); @@ -225,4 +226,39 @@ main(void) } +# else + + +extern volatile size_t discarded_return_value; +volatile size_t discarded_return_value; + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const static char lut[256]; + char *out_buffer; + size_t out_size; + char pad; + size_t r; + + if (size < 3u) + return 0; + + out_size = ((size_t)data[0u] << 8) | (size_t)data[1u]; + if (out_size) { + out_buffer = malloc(out_size); + assert(out_buffer != NULL); + } else { + out_buffer = NULL; + } + pad = data[2u]; + + discarded_return_value = librecrypt_encode(out_buffer, out_size, &data[3u], size - 3u, lut, pad); + + free(out_buffer); + return 0; +} + + +# endif #endif diff --git a/librecrypt_get_encoding.c b/librecrypt_get_encoding.c index f253e70..8dc1c0a 100644 --- a/librecrypt_get_encoding.c +++ b/librecrypt_get_encoding.c @@ -34,6 +34,7 @@ librecrypt_get_encoding(const char *settings, size_t len, char *pad_out, int *st #else +# ifndef FUZZ #define NSA "$~no~such~algorithm~$" @@ -137,4 +138,27 @@ main(void) } + +# else + + +extern const void *volatile discarded_return_value; +const void *volatile discarded_return_value; + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *settings; + int decoding; + if (size < 1u) + return 0; + decoding = (int)data[0u] & 1; + settings = (const void *)&data[1u]; + size -= 1u; + discarded_return_value = librecrypt_get_encoding(settings, size, &(char){0}, &(int){0}, decoding); + return 0; +} + + +# endif #endif diff --git a/librecrypt_realise_salts.c b/librecrypt_realise_salts.c index 8f6d4eb..c7b7071 100644 --- a/librecrypt_realise_salts.c +++ b/librecrypt_realise_salts.c @@ -164,6 +164,7 @@ erange: #else +# ifndef FUZZ # define LARGE "99999999999999999999999999999999999999999999999999999999999999" @@ -313,4 +314,62 @@ main(void) } +#else + + +int +LLVMFuzzerInitialize(int *argc, char ***argv) +{ + static unsigned char not_random = 5; + +#if defined(__linux__) + libtest_getrandom_real = 0; +#endif + libtest_getentropy_real = 0; + libtest_random_pattern = ¬_random; + libtest_random_pattern_length = 1u; + libtest_random_pattern_offset = 0u; + + (void) argc; + (void) argv; + return 0; +} + + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + char *out_buffer, *settings; + size_t out_size; + ssize_t r; + + if (size < 2u) + return 0; + + out_size = ((size_t)data[0u] << 8) | (size_t)data[1u]; + if (out_size) { + out_buffer = malloc(out_size); + assert(out_buffer != NULL); + } else { + out_buffer = NULL; + } + data = &data[2u]; + size -= 2u; + settings = malloc(size + 1u); + assert(settings != NULL); + memcpy(settings, data, size); + settings[size] = '\0'; + + r = librecrypt_realise_salts(out_buffer, out_size, settings, NULL, NULL); + if (out_size && r >= 0) { + assert(strlen(out_buffer) < out_size); + assert((size_t)r >= strlen(out_buffer)); + } + + free(out_buffer); + return 0; +} + + +# endif #endif diff --git a/librecrypt_test_supported.c b/librecrypt_test_supported.c index db9f302..66ee4fb 100644 --- a/librecrypt_test_supported.c +++ b/librecrypt_test_supported.c @@ -41,6 +41,7 @@ librecrypt_test_supported(const char *phrase, size_t len, int text, const char * #else +# ifndef FUZZ #define NSA "$~no~such~algorithm~$" @@ -77,4 +78,41 @@ main(void) } +# else + + +extern volatile int discarded_return_value; +volatile int discarded_return_value; + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const void *phrase; + size_t len; + int text; + char *settings; + + if (size < 4u) + return 0; + + text = (int)data[0u] & 1; + len = (size_t)data[1u]; + if (len > size - 2u) + return 0; + phrase = &data[2u]; + data = &data[2u + len]; + size -= 2u + len; + settings = malloc(size + 1u); + assert(settings); + memcpy(settings, data, size); + settings[size] = '\0'; + + discarded_return_value = librecrypt_test_supported(phrase, len, text, settings); + + free(settings); + return 0; +} + + +# endif #endif |
