diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 477c265b3..1c7ed51d2 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -969,6 +969,7 @@ __ARCH_STRSTR_NO_REDIRECT __ARM_ARCH_7M__ __ARM_FEATURE_CRYPTO __ASSEMBLER__ +__ATOMIC_CONSUME __ATOMIC_RELAXED __AVR_ARCH__ __AVR__ diff --git a/src/ssl.c b/src/ssl.c index c201e30b3..cd9035de3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7559,7 +7559,7 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) * Return the private key of the WOLFSSL_CTX struct * @return WOLFSSL_EVP_PKEY* The caller doesn *NOT*` free the returned object. */ -WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx) +WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx) { WOLFSSL_EVP_PKEY* res; const unsigned char *key; @@ -7605,12 +7605,25 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx) #ifdef WOLFSSL_BLIND_PRIVATE_KEY wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); #endif - res = wolfSSL_d2i_PrivateKey(type, - (WOLFSSL_EVP_PKEY**)&ctx->privateKeyPKey, &key, + res = wolfSSL_d2i_PrivateKey(type, NULL, &key, (long)ctx->privateKey->length); #ifdef WOLFSSL_BLIND_PRIVATE_KEY wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask); #endif + if (res) { +#ifdef WOLFSSL_ATOMIC_OPS + WOLFSSL_EVP_PKEY *current_pkey = NULL; + if (! wolfSSL_Atomic_Ptr_CompareExchange( + (void **)&ctx->privateKeyPKey, + (void **)¤t_pkey, res)) + { + wolfSSL_EVP_PKEY_free(res); + res = current_pkey; + } +#else + ctx->privateKeyPKey = res; +#endif + } } return res; diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index df888c0d7..35a0f83d0 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1271,12 +1271,15 @@ char* wc_strdup_ex(const char *src, int memType) { } #endif -#if defined(WOLFSSL_ATOMIC_OPS) && !defined(SINGLE_THREADED) +#ifdef WOLFSSL_ATOMIC_OPS + +#if defined(WOLFSSL_USER_DEFINED_ATOMICS) + +#elif defined(SINGLE_THREADED) + +#elif defined(__GNUC__) && defined(__ATOMIC_RELAXED) +/* direct calls using gcc-style compiler built-ins */ -#ifdef HAVE_C___ATOMIC -/* Atomic ops using standard C lib */ -#ifdef __cplusplus -/* C++ using direct calls to compiler built-in functions */ void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i) { *c = i; @@ -1357,7 +1360,16 @@ int wolfSSL_Atomic_Uint_CompareExchange( c, expected_i, new_i, 0 /* weak */, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); } -#else +int wolfSSL_Atomic_Ptr_CompareExchange( + void **c, void **expected_ptr, void *new_ptr) +{ + return __atomic_compare_exchange_n( + c, expected_ptr, new_ptr, 0 /* weak */, + __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); +} + +#elif defined(HAVE_C___ATOMIC) && defined(WOLFSSL_HAVE_ATOMIC_H) && \ + !defined(__cplusplus) /* Default C Implementation */ void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i) @@ -1444,9 +1456,19 @@ int wolfSSL_Atomic_Uint_CompareExchange( c, expected_i, new_i, memory_order_seq_cst, memory_order_acquire); } -#endif /* __cplusplus */ +int wolfSSL_Atomic_Ptr_CompareExchange( + void **c, void **expected_ptr, void *new_ptr) +{ + /* use gcc-built-in __atomic_compare_exchange_n(), not + * atomic_compare_exchange_strong_explicit(), to sidestep _Atomic type + * requirements. + */ + return __atomic_compare_exchange_n( + c, expected_ptr, new_ptr, 0 /* weak */, + __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); +} -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && !defined(WOLFSSL_NOT_WINDOWS_API) void wolfSSL_Atomic_Int_Init(wolfSSL_Atomic_Int* c, int i) { @@ -1527,8 +1549,8 @@ unsigned int wolfSSL_Atomic_Uint_SubFetch(wolfSSL_Atomic_Uint* c, int wolfSSL_Atomic_Uint_CompareExchange( wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i) { - long actual_i = InterlockedCompareExchange - ((wolfSSL_Atomic_Int *)c, (long)new_i, (long)*expected_i); + long actual_i = InterlockedCompareExchange( + (wolfSSL_Atomic_Int *)c, (long)new_i, (long)*expected_i); if (actual_i == (long)*expected_i) { return 1; } @@ -1538,6 +1560,32 @@ int wolfSSL_Atomic_Uint_CompareExchange( } } +int wolfSSL_Atomic_Ptr_CompareExchange( + void ** c, void **expected_ptr, void *new_ptr) +{ +#ifdef _WIN64 + LONG64 actual_ptr = InterlockedCompareExchange64( + (LONG64 *)c, (LONG64)new_ptr, (LONG64)*expected_ptr); + if (actual_ptr == (LONG64)*expected_ptr) { + return 1; + } + else { + *expected_ptr = (void *)actual_ptr; + return 0; + } +#else /* !_WIN64 */ + LONG actual_ptr = InterlockedCompareExchange( + (LONG *)c, (LONG)new_ptr, (LONG)*expected_ptr); + if (actual_ptr == (LONG)*expected_ptr) { + return 1; + } + else { + *expected_ptr = (void *)actual_ptr; + return 0; + } +#endif /* !_WIN64 */ +} + #endif #endif /* WOLFSSL_ATOMIC_OPS */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index ca8f4f81d..3f3a98456 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3228,7 +3228,7 @@ WOLFSSL_API int wolfSSL_want_write(WOLFSSL* ssl); #ifdef OPENSSL_EXTRA WOLFSSL_API int wolfSSL_want(WOLFSSL* ssl); -WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx); +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx); #include /* var_arg */ WOLFSSL_API int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 91b5bc466..382f4f3ec 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -494,31 +494,26 @@ #define WOLFSSL_ATOMIC_LOAD(x) (x) #define WOLFSSL_ATOMIC_STORE(x, val) (x) = (val) #define WOLFSSL_ATOMIC_OPS - #elif defined(HAVE_C___ATOMIC) - #ifdef __cplusplus - #if defined(__GNUC__) && defined(__ATOMIC_RELAXED) - /* C++ using direct calls to compiler built-in functions */ - typedef volatile int wolfSSL_Atomic_Int; - typedef volatile unsigned int wolfSSL_Atomic_Uint; - #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) - #define WOLFSSL_ATOMIC_LOAD(x) __atomic_load_n(&(x), \ - __ATOMIC_CONSUME) - #define WOLFSSL_ATOMIC_STORE(x, val) __atomic_store_n(&(x), \ - val, __ATOMIC_RELEASE) - #define WOLFSSL_ATOMIC_OPS - #endif - #else - #ifdef WOLFSSL_HAVE_ATOMIC_H - /* Default C Implementation */ - #include - typedef atomic_int wolfSSL_Atomic_Int; - typedef atomic_uint wolfSSL_Atomic_Uint; - #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) - #define WOLFSSL_ATOMIC_LOAD(x) atomic_load(&(x)) - #define WOLFSSL_ATOMIC_STORE(x, val) atomic_store(&(x), val) - #define WOLFSSL_ATOMIC_OPS - #endif /* WOLFSSL_HAVE_ATOMIC_H */ - #endif + #elif defined(__GNUC__) && defined(__ATOMIC_CONSUME) + /* direct calls using gcc-style compiler built-ins */ + typedef volatile int wolfSSL_Atomic_Int; + typedef volatile unsigned int wolfSSL_Atomic_Uint; + #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) + #define WOLFSSL_ATOMIC_LOAD(x) __atomic_load_n(&(x), \ + __ATOMIC_CONSUME) + #define WOLFSSL_ATOMIC_STORE(x, val) __atomic_store_n(&(x), \ + val, __ATOMIC_RELEASE) + #define WOLFSSL_ATOMIC_OPS + #elif defined(HAVE_C___ATOMIC) && defined(WOLFSSL_HAVE_ATOMIC_H) && \ + !defined(__cplusplus) + /* Default C Implementation */ + #include + typedef atomic_int wolfSSL_Atomic_Int; + typedef atomic_uint wolfSSL_Atomic_Uint; + #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) + #define WOLFSSL_ATOMIC_LOAD(x) atomic_load(&(x)) + #define WOLFSSL_ATOMIC_STORE(x, val) atomic_store(&(x), val) + #define WOLFSSL_ATOMIC_OPS #elif defined(_MSC_VER) && !defined(WOLFSSL_NOT_WINDOWS_API) /* Use MSVC compiler intrinsics for atomic ops */ #ifdef _WIN32_WCE @@ -534,8 +529,8 @@ #define WOLFSSL_ATOMIC_OPS #endif - #ifndef WOLFSSL_ATOMIC_INITIALIZER - /* If we weren't able to implement atomics above, disable them here. */ + /* If we weren't able to implement atomics above, disable them here. */ + #ifndef WOLFSSL_ATOMIC_OPS #define WOLFSSL_NO_ATOMICS #endif #endif @@ -586,6 +581,8 @@ wolfSSL_Atomic_Uint* c, unsigned int i); WOLFSSL_API int wolfSSL_Atomic_Uint_CompareExchange( wolfSSL_Atomic_Uint* c, unsigned int *expected_i, unsigned int new_i); + WOLFSSL_API int wolfSSL_Atomic_Ptr_CompareExchange( + void** c, void **expected_ptr, void *new_ptr); #else /* Code using these fallback implementations in non-SINGLE_THREADED builds * needs to arrange its own explicit fallback to int for wolfSSL_Atomic_Int @@ -623,6 +620,18 @@ return 0; } } + static WC_INLINE int wolfSSL_Atomic_Ptr_CompareExchange( + void **c, void *expected_ptr, void *new_ptr) + { + if (*(char **)c == *(char **)expected_ptr) { + *(char **)c = (char *)new_ptr; + return 1; + } + else { + *(char **)expected_ptr = *(char **)c; + return 0; + } + } static WC_INLINE unsigned int wolfSSL_Atomic_Uint_FetchAdd( unsigned int *c, unsigned int i) {