mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-17 15:25:35 +00:00
d9863128b9
the ASM variant is not found it fix something is wrong with the external build hmm why is this critical section doing nothing fix multiple init debug init ok fixed
231 lines
3.8 KiB
C
231 lines
3.8 KiB
C
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#elif defined(HAVE_PTHREAD)
|
|
#include <pthread.h>
|
|
#endif
|
|
|
|
#include <sodium/core.h>
|
|
#include <sodium/crypto_generichash.h>
|
|
#include <sodium/crypto_scalarmult.h>
|
|
#include <sodium/crypto_stream_chacha20.h>
|
|
#include <sodium/crypto_stream_salsa20.h>
|
|
#include <sodium/randombytes.h>
|
|
#include <sodium/runtime.h>
|
|
#include <sodium/utils.h>
|
|
#include <sodium/private/implementations.h>
|
|
#include <sodium/private/mutex.h>
|
|
|
|
static volatile int initialized;
|
|
|
|
int
|
|
sodium_init(void)
|
|
{
|
|
if(sodium_crit_enter() != 0)
|
|
{
|
|
return -1; /* LCOV_EXCL_LINE */
|
|
}
|
|
if(initialized != 0)
|
|
{
|
|
if(sodium_crit_leave() != 0)
|
|
{
|
|
return -1; /* LCOV_EXCL_LINE */
|
|
}
|
|
/* if we're here, we already started properly */
|
|
return initialized ? 0: -1;
|
|
}
|
|
_sodium_runtime_get_cpu_features();
|
|
_crypto_generichash_blake2b_pick_best_implementation();
|
|
_crypto_scalarmult_curve25519_pick_best_implementation();
|
|
_crypto_stream_chacha20_pick_best_implementation();
|
|
_crypto_stream_salsa20_pick_best_implementation();
|
|
randombytes_stir();
|
|
initialized = 1;
|
|
if(sodium_crit_leave() != 0)
|
|
{
|
|
return -1; /* LCOV_EXCL_LINE */
|
|
}
|
|
return initialized ? 0 : -1;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
static CRITICAL_SECTION _sodium_lock;
|
|
static volatile LONG _sodium_lock_initialized;
|
|
static volatile int locked;
|
|
|
|
int
|
|
_sodium_crit_init(void)
|
|
{
|
|
LONG status = 0L;
|
|
|
|
while((status = InterlockedCompareExchange(&_sodium_lock_initialized, 1L, 0L))
|
|
== 1L)
|
|
{
|
|
Sleep(0);
|
|
}
|
|
|
|
switch(status)
|
|
{
|
|
case 0L:
|
|
InitializeCriticalSection(&_sodium_lock);
|
|
return InterlockedExchange(&_sodium_lock_initialized, 2L) == 1L ? 0 : -1;
|
|
case 2L:
|
|
return 0;
|
|
default: /* should never be reached */
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int
|
|
sodium_crit_enter(void)
|
|
{
|
|
if(_sodium_crit_init() != 0)
|
|
{
|
|
return -1; /* LCOV_EXCL_LINE */
|
|
}
|
|
EnterCriticalSection(&_sodium_lock);
|
|
assert(locked == 0);
|
|
locked = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
sodium_crit_leave(void)
|
|
{
|
|
if(locked == 0)
|
|
{
|
|
#ifdef EPERM
|
|
errno = EPERM;
|
|
#endif
|
|
return -1;
|
|
}
|
|
locked = 0;
|
|
LeaveCriticalSection(&_sodium_lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#elif defined(HAVE_PTHREAD) && !defined(__EMSCRIPTEN__)
|
|
|
|
static pthread_mutex_t _sodium_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
static volatile int locked;
|
|
|
|
int
|
|
sodium_crit_enter(void)
|
|
{
|
|
int ret;
|
|
|
|
if((ret = pthread_mutex_lock(&_sodium_lock)) == 0)
|
|
{
|
|
assert(locked == 0);
|
|
locked = 1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
sodium_crit_leave(void)
|
|
{
|
|
int ret;
|
|
|
|
if(locked == 0)
|
|
{
|
|
#ifdef EPERM
|
|
errno = EPERM;
|
|
#endif
|
|
return -1;
|
|
}
|
|
locked = 0;
|
|
|
|
return pthread_mutex_unlock(&_sodium_lock);
|
|
}
|
|
|
|
#elif defined(HAVE_ATOMIC_OPS) && !defined(__EMSCRIPTEN__) \
|
|
&& !defined(__native_client__)
|
|
|
|
static volatile int _sodium_lock;
|
|
|
|
int
|
|
sodium_crit_enter(void)
|
|
{
|
|
#ifdef HAVE_NANOSLEEP
|
|
struct timespec q;
|
|
memset(&q, 0, sizeof q);
|
|
#endif
|
|
while(__sync_lock_test_and_set(&_sodium_lock, 1) != 0)
|
|
{
|
|
#ifdef HAVE_NANOSLEEP
|
|
(void)nanosleep(&q, NULL);
|
|
#elif defined(__x86_64__) || defined(__i386__)
|
|
__asm__ __volatile__("pause");
|
|
#endif
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
sodium_crit_leave(void)
|
|
{
|
|
__sync_lock_release(&_sodium_lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
int
|
|
sodium_crit_enter(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
sodium_crit_leave(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
static void (*_misuse_handler)(void);
|
|
|
|
void
|
|
sodium_misuse(void)
|
|
{
|
|
void (*handler)(void);
|
|
|
|
(void)sodium_crit_leave();
|
|
if(sodium_crit_enter() == 0)
|
|
{
|
|
handler = _misuse_handler;
|
|
if(handler != NULL)
|
|
{
|
|
handler();
|
|
}
|
|
}
|
|
/* LCOV_EXCL_START */
|
|
abort();
|
|
}
|
|
/* LCOV_EXCL_STOP */
|
|
|
|
int
|
|
sodium_set_misuse_handler(void (*handler)(void))
|
|
{
|
|
if(sodium_crit_enter() != 0)
|
|
{
|
|
return -1; /* LCOV_EXCL_LINE */
|
|
}
|
|
_misuse_handler = handler;
|
|
if(sodium_crit_leave() != 0)
|
|
{
|
|
return -1; /* LCOV_EXCL_LINE */
|
|
}
|
|
return 0;
|
|
}
|