Add locks around sodium_init()
This commit is contained in:
parent
14211cd7ea
commit
f8ff8ebf66
@ -644,7 +644,7 @@ dnl Checks for functions and headers
|
|||||||
|
|
||||||
AS_IF([test "x$EMSCRIPTEN" = "x"],[
|
AS_IF([test "x$EMSCRIPTEN" = "x"],[
|
||||||
AC_CHECK_FUNCS([arc4random arc4random_buf])
|
AC_CHECK_FUNCS([arc4random arc4random_buf])
|
||||||
AC_CHECK_FUNCS([mmap mlock madvise mprotect explicit_bzero])
|
AC_CHECK_FUNCS([mmap mlock madvise mprotect explicit_bzero nanosleep])
|
||||||
])
|
])
|
||||||
AC_CHECK_FUNCS([posix_memalign getpid])
|
AC_CHECK_FUNCS([posix_memalign getpid])
|
||||||
|
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#ifdef HAVE_PTHREAD
|
||||||
|
# include <pthread.h>
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "crypto_generichash.h"
|
#include "crypto_generichash.h"
|
||||||
#include "crypto_onetimeauth.h"
|
#include "crypto_onetimeauth.h"
|
||||||
@ -18,12 +26,21 @@
|
|||||||
# warning Alternatively, use the "stable" branch in the git repository.
|
# warning Alternatively, use the "stable" branch in the git repository.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int initialized;
|
static int _sodium_crit_enter(void);
|
||||||
|
static int _sodium_crit_leave(void);
|
||||||
|
|
||||||
|
static volatile int initialized;
|
||||||
|
|
||||||
int
|
int
|
||||||
sodium_init(void)
|
sodium_init(void)
|
||||||
{
|
{
|
||||||
|
if (_sodium_crit_enter() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (initialized != 0) {
|
if (initialized != 0) {
|
||||||
|
if (_sodium_crit_leave() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
_sodium_runtime_get_cpu_features();
|
_sodium_runtime_get_cpu_features();
|
||||||
@ -35,6 +52,105 @@ sodium_init(void)
|
|||||||
_crypto_scalarmult_curve25519_pick_best_implementation();
|
_crypto_scalarmult_curve25519_pick_best_implementation();
|
||||||
_crypto_stream_chacha20_pick_best_implementation();
|
_crypto_stream_chacha20_pick_best_implementation();
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
|
if (_sodium_crit_leave() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PTHREAD
|
||||||
|
|
||||||
|
static pthread_mutex_t _sodium_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_enter(void)
|
||||||
|
{
|
||||||
|
return pthread_mutex_lock(&_sodium_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_leave(void)
|
||||||
|
{
|
||||||
|
return pthread_mutex_unlock(&_sodium_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
|
static CRITICAL_SECTION *_sodium_lock;
|
||||||
|
static volatile LONG _sodium_lock_initialized;
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_enter(void)
|
||||||
|
{
|
||||||
|
if (InterlockedCompareExchange(&_sodium_lock_initialized,
|
||||||
|
1L, 0L) != 0L) {
|
||||||
|
InitializeCriticalSection(_sodium_lock);
|
||||||
|
InterlockedIncrement(&_sodium_lock_initialized);
|
||||||
|
} else {
|
||||||
|
while (InterlockedCompareExchange(&_sodium_lock_initialized,
|
||||||
|
2L, 2L) != 2L) {
|
||||||
|
Sleep(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_leave(void)
|
||||||
|
{
|
||||||
|
if (_sodium_lock == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(_sodium_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(__GNUC__) && !defined(__EMSCRIPTEN__)
|
||||||
|
|
||||||
|
static volatile int _sodium_lock;
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_enter(void)
|
||||||
|
{
|
||||||
|
if (__sync_lock_test_and_set(&_sodium_lock, 1) != 0) {
|
||||||
|
for (;;) {
|
||||||
|
if (_sodium_lock == 0U &&
|
||||||
|
__sync_lock_test_and_set(&_sodium_lock, 1) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
# ifdef HAVE_NANOSLEEP
|
||||||
|
{
|
||||||
|
struct timespec q;
|
||||||
|
memset(&q, 0, sizeof q);
|
||||||
|
(void) nanosleep(&q, NULL);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_leave(void)
|
||||||
|
{
|
||||||
|
__sync_lock_release(&_sodium_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_enter(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sodium_crit_leave(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
# include <sys/mman.h>
|
# include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
#include "randombytes.h"
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <wincrypt.h>
|
# include <wincrypt.h>
|
||||||
@ -23,6 +21,9 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "randombytes.h"
|
||||||
|
|
||||||
#ifndef ENOSYS
|
#ifndef ENOSYS
|
||||||
# define ENOSYS ENXIO
|
# define ENOSYS ENXIO
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user