Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds MBEDTLS_THREADING_C implementation for Windows using srwlock #7180

Open
wants to merge 9 commits into
base: development
Choose a base branch
from
7 changes: 7 additions & 0 deletions include/mbedtls/check_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,13 @@
#define MBEDTLS_THREADING_IMPL
#endif

#if defined(MBEDTLS_THREADING_SRWLOCK)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_SRWLOCK defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif

#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
Expand Down
13 changes: 12 additions & 1 deletion include/mbedtls/mbedtls_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -1940,6 +1940,17 @@
*/
//#define MBEDTLS_THREADING_PTHREAD

/**
* \def MBEDTLS_THREADING_SRWLOCK
*
* Enable the Windows SRW Locks wrapper layer for the threading layer.
*
* Requires: MBEDTLS_THREADING_C
*
* Uncomment this to enable SRW Lock mutexes.
*/
//#define MBEDTLS_THREADING_SRWLOCK

/**
* \def MBEDTLS_USE_PSA_CRYPTO
*
Expand Down Expand Up @@ -3307,7 +3318,7 @@
* provided).
*
* You will have to enable either MBEDTLS_THREADING_ALT or
* MBEDTLS_THREADING_PTHREAD.
* MBEDTLS_THREADING_PTHREAD or MBEDTLS_THREADING_SRWLOCK
*
* Enable this layer to allow use of mutexes within mbed TLS
*/
Expand Down
34 changes: 34 additions & 0 deletions include/mbedtls/threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,40 @@ typedef struct mbedtls_threading_mutex_t {
} mbedtls_threading_mutex_t;
#endif

#if defined(MBEDTLS_THREADING_SRWLOCK)

#if !defined(WIN32_LEAN_AND_MEAN)
/* Avoid exposing a temporary definition for files that includes threading.h */
#define MBEDTLS_LOCAL_HEADER_WIN32_LEAN_AND_MEAN
/* Needed to avoid redefinition errors from winsock.h */
#define WIN32_LEAN_AND_MEAN
#endif /* !WIN32_LEAN_AND_MEAN */

#if !defined(_WIN32_WINNT)
/* Avoid exposing a temporary definition for files that includes threading.h */
#define MBEDTLS_LOCAL_HEADER_WIN32_WINNT
/* Needed to enable srwlock api in synchapi.h */
#define _WIN32_WINNT 0x0600
#elif _WIN32_WINNT < 0x0600
#error "SRWLock api is supported from _WIN32_WINNT==0x0600 (Vista)"
#endif /* !_WIN32_WINNT */

#include <windows.h>
#include <synchapi.h>

#if defined(MBEDTLS_LOCAL_HEADER_WIN32_LEAN_AND_MEAN)
#undef WIN32_LEAN_AND_MEAN
#endif /* MBEDTLS_LOCAL_HEADER_WIN32_LEAN_AND_MEAN */

#if defined(MBEDTLS_LOCAL_HEADER_WIN32_WINNT)
#undef _WIN32_WINNT
#endif /* MBEDTLS_LOCAL_HEADER_WIN32_WINNT */

typedef struct mbedtls_threading_mutex_t {
SRWLOCK lock;
} mbedtls_threading_mutex_t;
#endif

#if defined(MBEDTLS_THREADING_ALT)
/* You should define the mbedtls_threading_mutex_t type in your header */
#include "threading_alt.h"
Expand Down
54 changes: 54 additions & 0 deletions library/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,60 @@ int (*mbedtls_mutex_unlock)(mbedtls_threading_mutex_t *) = threading_mutex_unloc

#endif /* MBEDTLS_THREADING_PTHREAD */

#if defined(MBEDTLS_THREADING_SRWLOCK)
static void threading_mutex_init_srwlock(mbedtls_threading_mutex_t *mutex)
{
if (mutex == NULL) {
return;
}

InitializeSRWLock(&mutex->lock);
}

static void threading_mutex_free_srwlock(mbedtls_threading_mutex_t *mutex)
{
if (mutex == NULL) {
return;
}
/*
* SRW locks do not need to be explicitly destroyed.
*/
}

static int threading_mutex_lock_srwlock(mbedtls_threading_mutex_t *mutex)
{
if (mutex == NULL) {
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
}

AcquireSRWLockExclusive(&mutex->lock);

return 0;
}

static int threading_mutex_unlock_srwlock(mbedtls_threading_mutex_t *mutex)
{
if (mutex == NULL) {
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
}

ReleaseSRWLockExclusive(&mutex->lock);

return 0;
}

void (*mbedtls_mutex_init)(mbedtls_threading_mutex_t *) = threading_mutex_init_srwlock;
void (*mbedtls_mutex_free)(mbedtls_threading_mutex_t *) = threading_mutex_free_srwlock;
int (*mbedtls_mutex_lock)(mbedtls_threading_mutex_t *) = threading_mutex_lock_srwlock;
int (*mbedtls_mutex_unlock)(mbedtls_threading_mutex_t *) = threading_mutex_unlock_srwlock;

/*
* With SRW Lock we can statically initialize mutexes
*/
#define MUTEX_INIT = SRWLOCK_INIT

#endif /* MBEDTLS_THREADING_SRWLOCK */

#if defined(MBEDTLS_THREADING_ALT)
static int threading_mutex_fail(mbedtls_threading_mutex_t *mutex)
{
Expand Down
1 change: 1 addition & 0 deletions scripts/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def realfull_adapter(_name, active, section):
'MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY', # interacts with *_USE_A64_CRYPTO_IF_PRESENT
'MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN', # build dependency (clang+memsan)
'MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND', # build dependency (valgrind headers)
'MBEDTLS_THREADING_SRWLOCK', # os dependency (windows)
'MBEDTLS_X509_REMOVE_INFO', # removes a feature
])

Expand Down
15 changes: 8 additions & 7 deletions tests/scripts/all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3634,16 +3634,17 @@ component_test_tls13_no_compatibility_mode () {
}

component_build_mingw () {
msg "build: Windows cross build - mingw64, make (Link Library)" # ~ 30s
msg "build: Windows cross build - mingw64, make (Static Library)" # ~ 30s
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 lib programs

# note Make tests only builds the tests, but doesn't run them
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror' WINDOWS_BUILD=1 tests
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 tests
make WINDOWS_BUILD=1 clean

msg "build: Windows cross build - mingw64, make (DLL)" # ~ 30s
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 lib programs
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 tests
msg "build: Windows cross build - mingw64, make (Shared Library)" # ~ 30s
scripts/config.py set MBEDTLS_THREADING_C
scripts/config.py set MBEDTLS_THREADING_SRWLOCK
# older versions of mingw defaults _WIN32_WINNT to 0x0502 so explicitly requesting _WIN32_WINNT=0x0600
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-D_WIN32_WINNT=0x0600 -Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 lib programs
make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar LD=i686-w64-minggw32-ld CFLAGS='-D_WIN32_WINNT=0x0600 -Werror -Wall -Wextra' WINDOWS_BUILD=1 SHARED=1 tests
make WINDOWS_BUILD=1 clean
}
support_build_mingw() {
Expand Down
8 changes: 7 additions & 1 deletion tests/scripts/check_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,13 @@ def parse_macros(self, include, exclude=None):
"""
macro_regex = re.compile(r"# *define +(?P<macro>\w+)")
exclusions = (
"asm", "inline", "EMIT", "_CRT_SECURE_NO_DEPRECATE", "MULADDC_"
"asm",
"inline",
"EMIT",
"_CRT_SECURE_NO_DEPRECATE",
"MULADDC_",
"_WIN32_WINNT",
"WIN32_LEAN_AND_MEAN"
)

files = self.get_included_files(include, exclude)
Expand Down