Merge pull request #10472 from douzzer/20260512-wc_init_state

20260512-wc_init_state
This commit is contained in:
David Garske
2026-06-08 13:44:17 -07:00
committed by GitHub
3 changed files with 511 additions and 189 deletions
+1
View File
@@ -662,6 +662,7 @@ WC_HASH_CUSTOM_MAX_BLOCK_SIZE
WC_HASH_CUSTOM_MAX_DIGEST_SIZE
WC_HASH_CUSTOM_MIN_DIGEST_SIZE
WC_LINUXKM_NO_USE_HEAP_WRAPPERS
WC_INIT_ERROR_WHEN_CONTENDED
WC_MLKEM_KERNEL_ASM
WC_NO_ASYNC_SLEEP
WC_NO_RNG_SIMPLE
+391 -144
View File
File diff suppressed because it is too large Load Diff
+119 -45
View File
@@ -516,6 +516,14 @@
typedef wolfSSL_Mutex wolfSSL_RwLock;
#endif
#ifdef WC_16BIT_CPU
#define WC_ATOMIC_INT_ARG long int
#define WC_ATOMIC_UINT_ARG long unsigned int
#else
#define WC_ATOMIC_INT_ARG int
#define WC_ATOMIC_UINT_ARG unsigned int
#endif
#ifndef WOLFSSL_NO_ATOMICS
#if defined(WOLFSSL_USER_DEFINED_ATOMICS)
/* user-supplied bindings for wolfSSL_Atomic_Int etc. */
@@ -527,8 +535,8 @@
#define WOLFSSL_ATOMIC_OPS
#endif
#elif defined(SINGLE_THREADED)
typedef int wolfSSL_Atomic_Int;
typedef unsigned int wolfSSL_Atomic_Uint;
typedef WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int;
typedef WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint;
#define WOLFSSL_ATOMIC_INITIALIZER(x) (x)
#define WOLFSSL_ATOMIC_LOAD(x) (x)
#define WOLFSSL_ATOMIC_STORE(x, val) (x) = (val)
@@ -593,10 +601,10 @@
* Allows a user-supplied override definition with type introspection.
*/
#ifndef WOLFSSL_ATOMIC_COERCE_INT
#define WOLFSSL_ATOMIC_COERCE_INT(x) ((int)(x))
#define WOLFSSL_ATOMIC_COERCE_INT(x) ((WC_ATOMIC_INT_ARG)(x))
#endif
#ifndef WOLFSSL_ATOMIC_COERCE_UINT
#define WOLFSSL_ATOMIC_COERCE_UINT(x) ((unsigned int)(x))
#define WOLFSSL_ATOMIC_COERCE_UINT(x) ((WC_ATOMIC_UINT_ARG)(x))
#endif
#ifdef WOLFSSL_USER_DEFINED_ATOMICS
@@ -604,32 +612,39 @@
* wolfSSL_Atomic_Int_FetchAdd(), etc.
*/
#elif defined(WOLFSSL_ATOMIC_OPS) && !defined(SINGLE_THREADED)
WOLFSSL_API void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i);
WOLFSSL_API void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c,
WC_ATOMIC_INT_ARG i);
WOLFSSL_API void wolfSSL_Atomic_Uint_Init(
wolfSSL_Atomic_Uint* c, unsigned int i);
wolfSSL_Atomic_Uint* c, WC_ATOMIC_UINT_ARG i);
/* FetchOp functions return the value of the counter immediately preceding
* the effects of the operation.
* OpFetch functions return the value of the counter immediately after
* the effects of the operation.
*/
WOLFSSL_API int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int* c, int i);
WOLFSSL_API int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int* c, int i);
WOLFSSL_API int wolfSSL_Atomic_Int_AddFetch(wolfSSL_Atomic_Int* c, int i);
WOLFSSL_API int wolfSSL_Atomic_Int_SubFetch(wolfSSL_Atomic_Int* c, int i);
WOLFSSL_API int wolfSSL_Atomic_Int_Exchange(
wolfSSL_Atomic_Int* c, int new_i);
WOLFSSL_API WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_FetchAdd(
wolfSSL_Atomic_Int* c, WC_ATOMIC_INT_ARG i);
WOLFSSL_API WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_FetchSub(
wolfSSL_Atomic_Int* c, WC_ATOMIC_INT_ARG i);
WOLFSSL_API WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_AddFetch(
wolfSSL_Atomic_Int* c, WC_ATOMIC_INT_ARG i);
WOLFSSL_API WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_SubFetch(
wolfSSL_Atomic_Int* c, WC_ATOMIC_INT_ARG i);
WOLFSSL_API WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_Exchange(
wolfSSL_Atomic_Int* c, WC_ATOMIC_INT_ARG new_i);
WOLFSSL_API int wolfSSL_Atomic_Int_CompareExchange(
wolfSSL_Atomic_Int* c, int *expected_i, int new_i);
WOLFSSL_API unsigned int wolfSSL_Atomic_Uint_FetchAdd(
wolfSSL_Atomic_Uint* c, unsigned int i);
WOLFSSL_API unsigned int wolfSSL_Atomic_Uint_FetchSub(
wolfSSL_Atomic_Uint* c, unsigned int i);
WOLFSSL_API unsigned int wolfSSL_Atomic_Uint_AddFetch(
wolfSSL_Atomic_Uint* c, unsigned int i);
WOLFSSL_API unsigned int wolfSSL_Atomic_Uint_SubFetch(
wolfSSL_Atomic_Uint* c, unsigned int i);
wolfSSL_Atomic_Int* c, WC_ATOMIC_INT_ARG *expected_i,
WC_ATOMIC_INT_ARG new_i);
WOLFSSL_API WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_FetchAdd(
wolfSSL_Atomic_Uint* c, WC_ATOMIC_UINT_ARG i);
WOLFSSL_API WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_FetchSub(
wolfSSL_Atomic_Uint* c, WC_ATOMIC_UINT_ARG i);
WOLFSSL_API WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_AddFetch(
wolfSSL_Atomic_Uint* c, WC_ATOMIC_UINT_ARG i);
WOLFSSL_API WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_SubFetch(
wolfSSL_Atomic_Uint* c, WC_ATOMIC_UINT_ARG i);
WOLFSSL_API int wolfSSL_Atomic_Uint_CompareExchange(
wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i);
wolfSSL_Atomic_Uint* c, WC_ATOMIC_UINT_ARG *expected_i,
WC_ATOMIC_UINT_ARG new_i);
WOLFSSL_API int wolfSSL_Atomic_Ptr_CompareExchange(
void* volatile * c, void **expected_ptr, void *new_ptr);
#else
@@ -639,35 +654,47 @@
* !defined(WOLFSSL_ATOMIC_OPS) && !defined(SINGLE_THREADED). This forces
* local awareness of thread-unsafe semantics.
*/
#define wolfSSL_Atomic_Int_Init(c, i) (*(c) = (i))
#define wolfSSL_Atomic_Uint_Init(c, i) (*(c) = (i))
static WC_INLINE int wolfSSL_Atomic_Int_FetchAdd(wolfSSL_Atomic_Int *c,
int i)
static WC_INLINE WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_FetchAdd(
WC_ATOMIC_INT_ARG *c,
WC_ATOMIC_INT_ARG i)
{
int ret = *c;
WC_ATOMIC_INT_ARG ret = *c;
*c += i;
return ret;
}
static WC_INLINE int wolfSSL_Atomic_Int_FetchSub(wolfSSL_Atomic_Int *c, int i) {
int ret = *c;
static WC_INLINE WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_FetchSub(
WC_ATOMIC_INT_ARG *c,
WC_ATOMIC_INT_ARG i)
{
WC_ATOMIC_INT_ARG ret = *c;
*c -= i;
return ret;
}
static WC_INLINE int wolfSSL_Atomic_Int_AddFetch(wolfSSL_Atomic_Int *c, int i) {
static WC_INLINE WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_AddFetch(
WC_ATOMIC_INT_ARG *c,
WC_ATOMIC_INT_ARG i)
{
return (*c += i);
}
static WC_INLINE int wolfSSL_Atomic_Int_SubFetch(wolfSSL_Atomic_Int *c, int i) {
static WC_INLINE WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_SubFetch(
WC_ATOMIC_INT_ARG *c,
WC_ATOMIC_INT_ARG i)
{
return (*c -= i);
}
static WC_INLINE int wolfSSL_Atomic_Int_Exchange(
wolfSSL_Atomic_Int *c, int new_i)
static WC_INLINE WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_Exchange(
WC_ATOMIC_INT_ARG *c, WC_ATOMIC_INT_ARG new_i)
{
int ret = *c;
WC_ATOMIC_INT_ARG ret = *c;
*c = new_i;
return ret;
}
static WC_INLINE int wolfSSL_Atomic_Int_CompareExchange(
wolfSSL_Atomic_Int *c, int *expected_i, int new_i)
static WC_INLINE WC_ATOMIC_INT_ARG wolfSSL_Atomic_Int_CompareExchange(
WC_ATOMIC_INT_ARG *c, WC_ATOMIC_INT_ARG *expected_i,
WC_ATOMIC_INT_ARG new_i)
{
if (*c == *expected_i) {
*c = new_i;
@@ -690,32 +717,33 @@
return 0;
}
}
static WC_INLINE unsigned int wolfSSL_Atomic_Uint_FetchAdd(
wolfSSL_Atomic_Uint *c, unsigned int i)
static WC_INLINE WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_FetchAdd(
WC_ATOMIC_UINT_ARG *c, WC_ATOMIC_UINT_ARG i)
{
unsigned int ret = *c;
WC_ATOMIC_UINT_ARG ret = *c;
*c += i;
return ret;
}
static WC_INLINE unsigned int wolfSSL_Atomic_Uint_FetchSub(
wolfSSL_Atomic_Uint *c, unsigned int i)
static WC_INLINE WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_FetchSub(
WC_ATOMIC_UINT_ARG *c, WC_ATOMIC_UINT_ARG i)
{
unsigned int ret = *c;
WC_ATOMIC_UINT_ARG ret = *c;
*c -= i;
return ret;
}
static WC_INLINE unsigned int wolfSSL_Atomic_Uint_AddFetch(
wolfSSL_Atomic_Uint *c, unsigned int i)
static WC_INLINE WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_AddFetch(
WC_ATOMIC_UINT_ARG *c, WC_ATOMIC_UINT_ARG i)
{
return (*c += i);
}
static WC_INLINE unsigned int wolfSSL_Atomic_Uint_SubFetch(
wolfSSL_Atomic_Uint *c, unsigned int i)
static WC_INLINE WC_ATOMIC_UINT_ARG wolfSSL_Atomic_Uint_SubFetch(
WC_ATOMIC_UINT_ARG *c, WC_ATOMIC_UINT_ARG i)
{
return (*c -= i);
}
static WC_INLINE int wolfSSL_Atomic_Uint_CompareExchange(
wolfSSL_Atomic_Uint *c, unsigned int *expected_i, unsigned int new_i)
WC_ATOMIC_UINT_ARG *c, WC_ATOMIC_UINT_ARG *expected_i,
WC_ATOMIC_UINT_ARG new_i)
{
if (*c == *expected_i) {
*c = new_i;
@@ -945,6 +973,52 @@ WOLFSSL_API int wc_SetMutexCb(mutex_cb* cb);
WOLFSSL_API mutex_cb* wc_GetMutexCb(void);
#endif
/* Internal APIs for counting initialization depth, with deallocation races
* fully mitigated. Used by wolfCrypt_Init() and wolfCrypt_Cleanup().
*/
#ifdef WOLFSSL_ATOMIC_OPS
typedef wolfSSL_Atomic_Uint wc_init_state_t;
#define WC_INIT_STATE_INITIALIZER WOLFSSL_ATOMIC_INITIALIZER(0)
#else
typedef WC_ATOMIC_UINT_ARG wc_init_state_t;
#define WC_INIT_STATE_INITIALIZER 0
#endif
#define WC_DECLARE_INIT_STATE(x) wc_init_state_t x = WC_INIT_STATE_INITIALIZER
#define WC_INIT_STATE_UNINITED 0U
#define WC_INIT_STATE_INITING 1U
#define WC_INIT_STATE_INITED 2U
#define WC_INIT_STATE_CLEANING_UP 3U
#define WC_INIT_STATE_BAD_STATE 4U
#define WC_INIT_STATE_STATE_BITS 3
#define WC_INIT_STATE_COUNT_BITS 29
union wc_init_state_bitfields {
WC_ATOMIC_UINT_ARG u;
struct {
WC_ATOMIC_UINT_ARG state:WC_INIT_STATE_STATE_BITS;
WC_ATOMIC_UINT_ARG count:WC_INIT_STATE_COUNT_BITS;
} c;
};
/* Modules with no provisions for cleanup after a partially successful init need
* to enter a degraded state, returning BAD_STATE_E to the caller, signaling
* that restart is needed. This macro should only be called while
* _STATE_INITING (after wc_local_InitUp() returns _STATE_INITING and before
* wc_local_InitUpDone()), to assure the store is uncontended.
*/
#define WC_INIT_STATE_RAISE_BAD_STATE(x) do { \
union wc_init_state_bitfields _x; \
_x.u = WOLFSSL_ATOMIC_LOAD(x); \
_x.c.state = WC_INIT_STATE_BAD_STATE; \
WOLFSSL_ATOMIC_STORE(x, _x.u); \
} while (0)
/* wc_local_InitUp() opens the critical span of an init sequence. */
WOLFSSL_LOCAL int wc_local_InitUp(wc_init_state_t *s);
/* wc_local_InitUpDone() closes the critical span of an init sequence. */
WOLFSSL_LOCAL int wc_local_InitUpDone(wc_init_state_t *s);
/* wc_local_InitDown() opens the critical span of a cleanup sequence. */
WOLFSSL_LOCAL int wc_local_InitDown(wc_init_state_t *s);
/* wc_local_InitDownDone() closes the critical span of a cleanup sequence. */
WOLFSSL_LOCAL int wc_local_InitDownDone(wc_init_state_t *s);
/* main crypto initialization function */
WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Init(void);
WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void);