diff options
Diffstat (limited to '')
| -rw-r--r-- | LICENSE | 2 | ||||
| -rw-r--r-- | README | 4 | ||||
| -rw-r--r-- | config.mk | 10 | ||||
| -rw-r--r-- | libar2simplified.7 | 14 | ||||
| -rw-r--r-- | libar2simplified_decode_r.c | 15 | ||||
| -rw-r--r-- | libar2simplified_init_context.3 | 6 | ||||
| -rw-r--r-- | libar2simplified_init_context.c | 72 |
7 files changed, 76 insertions, 47 deletions
@@ -1,6 +1,6 @@ ISC License -© 2022 Mattias Andrée <m@maandree.se> +© 2022, 2023, 2026 Mattias Andrée <m@maandree.se> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -2,8 +2,8 @@ NAME libar2simplified - Simplified interface for libar2 DESCRIPTION - libar2simplified is façade for the libar2 C library that - implements the family of Argon2 key derivation function, + libar2simplified is a façade for the libar2 C library that + implements the family of Argon2 key derivation functions, including Argon2d, Argon2i, and Argon2id, as well as Argon2ds which was not part of the submission to the Password Hashing Competition of 2013, which Argon2 won in @@ -3,6 +3,12 @@ MANPREFIX = $(PREFIX)/share/man CC = cc +COMMON_SANITIZE = -fsanitize=alignment,shift,signed-integer-overflow,object-size,null,undefined,bounds,address +CLANG_SANITIZE = -O1 $(COMMON_SANITIZE),cfi -flto -fvisibility=hidden -fno-sanitize-trap=cfi +GCC_SANITIZE = -O1 $(COMMON_SANITIZE) +#SANITIZE = $(CLANG_SANITIZE) +#SANITIZE = $(GCC_SANITIZE) + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -CFLAGS = -std=c11 -Wall -g -pthread -LDFLAGS = -lar2 -lblake -pthread +CFLAGS = $(SANITIZE) -std=c11 -Wall -g -pthread +LDFLAGS = $(SANITIZE) -lar2 -lblake -pthread diff --git a/libar2simplified.7 b/libar2simplified.7 index 809ba1e..0a156e1 100644 --- a/libar2simplified.7 +++ b/libar2simplified.7 @@ -1,21 +1,21 @@ -.TH LIBAR2SIMPLIFIED 7 LIBAR2 +.TH LIBAR2SIMPLIFIED 7 LIBAR2SIMPLIFIED .SH NAME libar2simplified - Simplified interface for libar2 .SH DESCRIPTION .B libar2simplified -is façade for the +is a façade for the .BR libar2 (7) C library that implements the family of Argon2 key -derivation function, including Argon2d, Argon2i, and +derivation functions, including Argon2d, Argon2i, and Argon2id, as well as Argon2ds which was not part of the submission to the Password Hashing Competition of 2013, which Argon2 won in 2015. As a key derivation function, Argon2 is well-suited for cryptographically -hashing (one-way encrypting) passwords. Where as the +hashing (one-way encrypting) passwords. Whereas the .BR libar2 (7) -library is suitable in any code-base, as long as it -some standard C functions are avaible, since it does +library is suitable for any code-base, as long as it has +some standard C functions available, since it does not interact with the operating system, .B libar2simplified can only be used in fully hosted environments, since @@ -40,7 +40,7 @@ output the password hash in binary without prepending the parameters. .SH SEE ALSO -.BR libar2simplified (7), +.BR libar2 (7), .BR libar2simplified_crypt (3), .BR libar2simplified_decode (3), .BR libar2simplified_decode_r (3), diff --git a/libar2simplified_decode_r.c b/libar2simplified_decode_r.c index 545ecde..fa37aac 100644 --- a/libar2simplified_decode_r.c +++ b/libar2simplified_decode_r.c @@ -47,7 +47,8 @@ random_salt(char *out, size_t n, int (*random_byte_generator)(char *out, size_t ssize_t r; # ifdef AT_RANDOM uintptr_t raddr_; - uint16_t *raddr; + const unsigned char *raddr; + size_t j; # endif #endif @@ -70,15 +71,9 @@ random_salt(char *out, size_t n, int (*random_byte_generator)(char *out, size_t #if defined(__linux__) && defined(AT_RANDOM) raddr_ = (uintptr_t)getauxval(AT_RANDOM); if (raddr_) { - raddr = (void *)raddr_; - seed ^= (unsigned)raddr[0]; - seed ^= (unsigned)raddr[1]; - seed ^= (unsigned)raddr[2]; - seed ^= (unsigned)raddr[3]; - seed ^= (unsigned)raddr[4]; - seed ^= (unsigned)raddr[5]; - seed ^= (unsigned)raddr[6]; - seed ^= (unsigned)raddr[7]; + raddr = (const void *)raddr_; + for (j = 0; j < 16; j++) + ((unsigned char *)&seed)[j % sizeof(seed)] ^= raddr[j]; } #endif srand(seed); diff --git a/libar2simplified_init_context.3 b/libar2simplified_init_context.3 index c190c86..de22fac 100644 --- a/libar2simplified_init_context.3 +++ b/libar2simplified_init_context.3 @@ -23,10 +23,10 @@ function, provided via the parameter, with all auto-erase options turned off. .PP -This function provides a dynamic memory +This function provides dynamic memory management functions that erase memory -before it is deallocated. It also also -provides a multi-threading support using +before it is deallocated. It also +provides multi-threading support using a thread pool. .PP This function is used internally by the diff --git a/libar2simplified_init_context.c b/libar2simplified_init_context.c index 9dcbfb0..814e182 100644 --- a/libar2simplified_init_context.c +++ b/libar2simplified_init_context.c @@ -2,6 +2,7 @@ #include "common.h" #include <pthread.h> #include <semaphore.h> +#include <stdatomic.h> struct user_data; @@ -11,7 +12,7 @@ struct thread_data { struct user_data *master; pthread_t thread; sem_t semaphore; - int error; + _Atomic int error; void (*function)(void *data); void *function_input; }; @@ -50,14 +51,15 @@ alignedalloc(size_t num, size_t size, size_t extra, size_t alignment) static void * allocate(size_t num, size_t size, size_t alignment, struct libar2_context *ctx) { - size_t pad = (alignment - ((2 * sizeof(size_t)) & (alignment - 1))) & (alignment - 1); - char *ptr = alignedalloc(num, size, pad + 2 * sizeof(size_t), alignment); + size_t extra = 2 * sizeof(size_t); + size_t pad = -extra & (alignment - 1); + char *ptr = alignedalloc(num, size, pad + extra, alignment); if (ptr) { - ptr = &ptr[pad]; - *(size_t *)ptr = pad; - ptr = &ptr[sizeof(size_t)]; - *(size_t *)ptr = num * size; - ptr = &ptr[sizeof(size_t)]; + ptr += pad; + memcpy(ptr, &pad, sizeof(size_t)); + ptr += sizeof(size_t); + memcpy(ptr, &(size_t){num * size}, sizeof(size_t)); + ptr += sizeof(size_t); } (void) ctx; return ptr; @@ -68,10 +70,13 @@ static void deallocate(void *ptr, struct libar2_context *ctx) { char *p = ptr; + size_t size, pad; p -= sizeof(size_t); - libar2_erase(ptr, *(size_t *)p); + memcpy(&size, p, sizeof(size_t)); p -= sizeof(size_t); - p -= *(size_t *)p; + memcpy(&pad, p, sizeof(size_t)); + p -= pad; + libar2_erase(p, size + pad + 2u * sizeof(size_t)); free(p); (void) ctx; } @@ -81,31 +86,44 @@ static void * thread_loop(void *data_) { struct thread_data *data = data_; + void (*function)(void *data); + void *function_input; int err; for (;;) { if (sem_wait(&data->semaphore)) { if (errno == EINTR) continue; - data->error = errno; + atomic_store(&data->error, errno); return NULL; } - if (!data->function) { - data->error = ENOTRECOVERABLE; + err = pthread_mutex_lock(&data->master->mutex); + if (err) { + atomic_store(&data->error, err); + return NULL; + } + function = data->function; + function_input = data->function_input; + if (!function) { + atomic_store(&data->error, ENOTRECOVERABLE); + pthread_mutex_unlock(&data->master->mutex); return NULL; } - data->function(data->function_input); + pthread_mutex_unlock(&data->master->mutex); + + function(function_input); err = pthread_mutex_lock(&data->master->mutex); if (err) { - data->error = err; + atomic_store(&data->error, err); return NULL; } data->master->resting[data->index / 64] |= (uint_least64_t)1 << (data->index % 64); + pthread_mutex_unlock(&data->master->mutex); if (sem_post(&data->master->semaphore)) { - data->error = errno; + atomic_store(&data->error, errno); return NULL; } } @@ -124,15 +142,17 @@ run_thread(size_t index, void (*function)(void *arg), void *arg, struct libar2_c return -1; } data->resting[index / 64] ^= (uint_least64_t)1 << (index % 64); - pthread_mutex_unlock(&data->mutex); - if (data->threads[index].error) { - errno = data->threads[index].error; + err = atomic_load(&data->threads[index].error); + if (err) { + pthread_mutex_unlock(&data->mutex); + errno = err; return -1; } data->threads[index].function = function; data->threads[index].function_input = arg; + pthread_mutex_unlock(&data->mutex); if (sem_post(&data->threads[index].semaphore)) return -1; @@ -145,15 +165,16 @@ destroy_thread_pool(struct libar2_context *ctx) { struct user_data *data = ctx->user_data; size_t i; - int ret = 0; + int err, ret = 0; for (i = data->nthreads; i--;) if (run_thread(i, pthread_exit, NULL, ctx)) return -1; for (i = data->nthreads; i--;) { pthread_join(data->threads[i].thread, NULL); sem_destroy(&data->threads[i].semaphore); - if (data->threads[i].error) - ret = data->threads[i].error; + err = atomic_load(&data->threads[i].error); + if (err) + ret = err; } sem_destroy(&data->semaphore); pthread_mutex_destroy(&data->mutex); @@ -244,6 +265,7 @@ init_thread_pool(size_t desired, size_t *createdp, struct libar2_context *ctx) for (i = 0; i < data->nthreads; i++) { memset(&data->threads[i], 0, sizeof(data->threads[i])); + atomic_init(&data->threads[i].error, 0); data->threads[i].master = data; data->threads[i].index = i; data->resting[i / 64] |= (uint_least64_t)1 << (i % 64); @@ -290,6 +312,11 @@ await_threads(size_t *indices, size_t n, size_t require, struct libar2_context * memset(data->joined, 0, (data->nthreads + 63) / 64 * sizeof(*data->joined)); + err = pthread_mutex_lock(&data->mutex); + if (err) { + errno = err; + return 0; + } for (i = 0; i < data->nthreads; i += 64) { for (;;) { one = data->resting[i / 64]; @@ -302,6 +329,7 @@ await_threads(size_t *indices, size_t n, size_t require, struct libar2_context * indices[ret - 1] = i + lb(one); } } + pthread_mutex_unlock(&data->mutex); for (;;) { if (ret < require) { |
