diff --git a/src/common/sha3/xkcp_sha3.c b/src/common/sha3/xkcp_sha3.c index ede4607343..16ee2ff5c0 100644 --- a/src/common/sha3/xkcp_sha3.c +++ b/src/common/sha3/xkcp_sha3.c @@ -17,24 +17,27 @@ #include #include #include +#ifndef __STDC_NO_THREADS__ +#include +#endif #define KECCAK_CTX_ALIGNMENT 32 #define _KECCAK_CTX_BYTES (200+sizeof(uint64_t)) #define KECCAK_CTX_BYTES (KECCAK_CTX_ALIGNMENT * \ ((_KECCAK_CTX_BYTES + KECCAK_CTX_ALIGNMENT - 1)/KECCAK_CTX_ALIGNMENT)) -/* The first call to Keccak_Initialize will be routed through dispatch, which - * updates all of the function pointers used below. - */ -static KeccakInitFn Keccak_Dispatch; -static KeccakInitFn *Keccak_Initialize_ptr = &Keccak_Dispatch; +#ifndef __STDC_NO_THREADS__ +static once_flag dispatch_once_flag = ONCE_FLAG_INIT; +#endif + +static KeccakInitFn *Keccak_Initialize_ptr = NULL; static KeccakAddByteFn *Keccak_AddByte_ptr = NULL; static KeccakAddBytesFn *Keccak_AddBytes_ptr = NULL; static KeccakPermuteFn *Keccak_Permute_ptr = NULL; static KeccakExtractBytesFn *Keccak_ExtractBytes_ptr = NULL; static KeccakFastLoopAbsorbFn *Keccak_FastLoopAbsorb_ptr = NULL; -static void Keccak_Dispatch(void *state) { +static void Keccak_Dispatch() { // TODO: Simplify this when we have a Windows-compatible AVX2 implementation of SHA3 #if defined(OQS_DIST_X86_64_BUILD) #if defined(OQS_ENABLE_SHA3_xkcp_low_avx2) @@ -69,8 +72,6 @@ static void Keccak_Dispatch(void *state) { Keccak_ExtractBytes_ptr = &KeccakP1600_ExtractBytes; Keccak_FastLoopAbsorb_ptr = &KeccakF1600_FastLoop_Absorb; #endif - - (*Keccak_Initialize_ptr)(state); } /************************************************* @@ -84,6 +85,13 @@ static void Keccak_Dispatch(void *state) { * that have not been permuted, or not-yet-squeezed bytes. **************************************************/ static void keccak_inc_reset(uint64_t *s) { +#ifndef __STDC_NO_THREADS__ + call_once(&dispatch_once_flag, Keccak_Dispatch); +#else + if (Keccak_Initialize_ptr == NULL) { + Keccak_Dispatch(); + } +#endif (*Keccak_Initialize_ptr)(s); s[25] = 0; } diff --git a/src/common/sha3/xkcp_sha3x4.c b/src/common/sha3/xkcp_sha3x4.c index ef95ac6f02..cc75875f25 100644 --- a/src/common/sha3/xkcp_sha3x4.c +++ b/src/common/sha3/xkcp_sha3x4.c @@ -12,23 +12,26 @@ #include #include #include +#ifndef __STDC_NO_THREADS__ +#include +#endif #define KECCAK_X4_CTX_ALIGNMENT 32 #define _KECCAK_X4_CTX_BYTES (800+sizeof(uint64_t)) #define KECCAK_X4_CTX_BYTES (KECCAK_X4_CTX_ALIGNMENT * \ ((_KECCAK_X4_CTX_BYTES + KECCAK_X4_CTX_ALIGNMENT - 1)/KECCAK_X4_CTX_ALIGNMENT)) -/* The first call to Keccak_Initialize will be routed through dispatch, which - * updates all of the function pointers used below. - */ -static KeccakX4InitFn Keccak_X4_Dispatch; -static KeccakX4InitFn *Keccak_X4_Initialize_ptr = &Keccak_X4_Dispatch; +#ifndef __STDC_NO_THREADS__ +static once_flag dispatch_once_flag = ONCE_FLAG_INIT; +#endif + +static KeccakX4InitFn *Keccak_X4_Initialize_ptr = NULL; static KeccakX4AddByteFn *Keccak_X4_AddByte_ptr = NULL; static KeccakX4AddBytesFn *Keccak_X4_AddBytes_ptr = NULL; static KeccakX4PermuteFn *Keccak_X4_Permute_ptr = NULL; static KeccakX4ExtractBytesFn *Keccak_X4_ExtractBytes_ptr = NULL; -static void Keccak_X4_Dispatch(void *state) { +static void Keccak_X4_Dispatch() { // TODO: Simplify this when we have a Windows-compatible AVX2 implementation of SHA3 #if defined(OQS_DIST_X86_64_BUILD) #if defined(OQS_ENABLE_SHA3_xkcp_low_avx2) @@ -59,11 +62,16 @@ static void Keccak_X4_Dispatch(void *state) { Keccak_X4_Permute_ptr = &KeccakP1600times4_PermuteAll_24rounds; Keccak_X4_ExtractBytes_ptr = &KeccakP1600times4_ExtractBytes; #endif - - (*Keccak_X4_Initialize_ptr)(state); } static void keccak_x4_inc_reset(uint64_t *s) { +#ifndef __STDC_NO_THREADS__ + call_once(&dispatch_once_flag, &Keccak_X4_Dispatch); +#else + if (Keccak_X4_Initialize_ptr == NULL) { + Keccak_X4_Dispatch(); + } +#endif (*Keccak_X4_Initialize_ptr)(s); s[100] = 0; } @@ -234,4 +242,3 @@ void OQS_SHA3_shake256_x4_inc_ctx_release(OQS_SHA3_shake256_x4_inc_ctx *state) { void OQS_SHA3_shake256_x4_inc_ctx_reset(OQS_SHA3_shake256_x4_inc_ctx *state) { keccak_x4_inc_reset((uint64_t *)state->ctx); } -