Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/configs/os-check-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@
"--enable-experimental"]},
{"name": "wolfssl-extra", "minutes": 1.6, "configure": ["CPPFLAGS=-DWOLFSSL_EXTRA"]},
{"name": "coding-no", "minutes": 1.5, "configure": ["--enable-coding=no"]},
{"name": "rng-no-getpid", "minutes": 1.5,
"comment": "Default RNG fork handlers without the pid check, so the child handler alone must make the forked child reseed in the compat RAND fork test.",
"configure": ["--enable-opensslextra", "CPPFLAGS=-DWOLFSSL_NO_GETPID"]},
{"name": "rng-atfork-off-no-getpid", "minutes": 1.5,
"comment": "Neither the fork handlers nor the pid check: the compat RAND fork test must see the child repeat the parent.",
"configure": ["--disable-rng-atfork", "--enable-opensslextra", "CPPFLAGS=-DWOLFSSL_NO_GETPID"]},
{"name": "she-ext-cmac-cryptocb", "minutes": 1.3,
"configure": ["--enable-she=extended", "--enable-cmac", "--enable-cryptocb",
"--enable-cryptocbutils"]},
Expand Down Expand Up @@ -283,11 +289,23 @@
{"name": "no-tls-cryptocb-aesgcm-setkey-free", "minutes": 1.3,
"configure": ["--disable-tls", "--enable-cryptocb", "--enable-aesgcm",
"CPPFLAGS=-DWOLF_CRYPTO_CB_AES_SETKEY -DWOLF_CRYPTO_CB_FREE"]},
{"name": "rng-bank-lock", "minutes": 1.3,
"comment": "The RNG bank with the per-instance lock: bank builds still hand out plain instances.",
"configure": ["--enable-rng-bank", "--enable-opensslextra"]},
{"name": "she-std-cmac", "minutes": 1.2,
"configure": ["--enable-she=standard", "--enable-cmac"]},
{"name": "no-verify-oid-fpki", "minutes": 1.2,
"configure": ["CPPFLAGS=-DNO_VERIFY_OID -DWOLFSSL_FPKI"]},
{"name": "rng-single-threaded", "minutes": 1.2,
"comment": "SINGLE_THREADED: no RNG lock and no fork handlers may be built, and the compat RAND test still passes.",
"configure": ["--enable-singlethreaded", "--enable-opensslextra"]},
{"name": "rng-atfork-off", "minutes": 1.2,
"comment": "Opt out of the RNG fork handlers that are on by default, so the lock without them is built and tested.",
"configure": ["--disable-rng-atfork"]},
{"name": "no-verify-oid", "minutes": 1.1, "configure": ["CPPFLAGS=-DNO_VERIFY_OID"]},
{"name": "rng-lock-off", "minutes": 1.1,
"comment": "Opt out of the per-instance RNG lock, so the WC_RNG layout and generate path without it are built and tested.",
"configure": ["--disable-rng-lock"]},
{"name": "rng-seed-device", "minutes": 1.1,
"comment": "Seed the RNG from a nominated device. /dev/urandom stands in for a hardware RNG so the WC_RNG_SEED_DEVICE read path is actually exercised on a runner.",
"configure": ["--with-rng-seed-device=/dev/urandom"]},
Expand Down
4 changes: 4 additions & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ PKA_SR_OPERRF
PLATFORMIO
PLUTON_CRYPTO_ECC
PRINT_SESSION_STATS
PTHREAD_CANCEL_DISABLE
PTHREAD_STACK_MIN
QAT_ENABLE_HASH
QAT_ENABLE_RNG
Expand Down Expand Up @@ -606,6 +607,8 @@ RNG_CR_CONDRST
RNG_SR_BUSY
RTC_ALARMSUBSECONDMASK_ALL
RTE_CMSIS_RTOS_RTX
RTLD_NODELETE
RTLD_NOLOAD
RTOS_MODULE_NET_AVAIL
RTPLATFORM
SAES
Expand Down Expand Up @@ -1289,6 +1292,7 @@ __MICROBLAZE__
__MINGW32__
__MINGW64_VERSION_MAJOR
__MINGW64__
__MSYS__
__MWERKS__
__NT__
__OS2__
Expand Down
82 changes: 81 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,13 @@ check_function_exists("memset" HAVE_MEMSET)
check_function_exists("socket" HAVE_SOCKET)
check_function_exists("strftime" HAVE_STRFTIME)
check_function_exists("__atomic_fetch_add" HAVE_C___ATOMIC)
check_function_exists("getpid" HAVE_GETPID)

include(CheckSymbolExists)
check_symbol_exists(isascii "ctype.h" HAVE_ISASCII)
check_symbol_exists(getpid "unistd.h" HAVE_GETPID) # pid_t comes with it
if(HAVE_GETPID)
list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_GETPID") # as options.h says
endif()

include(CheckTypeSize)

Expand Down Expand Up @@ -3765,6 +3768,15 @@ if(WOLFSSL_RNG_BANK)
list(APPEND WOLFSSL_DEFINITIONS "-DWC_RNG_BANK_SUPPORT")
endif()

# RNG lock (share one WC_RNG between threads)
add_option("WOLFSSL_RNG_LOCK"
"Enable the lock that lets one WC_RNG be shared between threads (default: enabled where the build supports it)"
"yes" "yes;no")
# the header leaves the lock out where threads or the RNG are absent
if(NOT WOLFSSL_RNG_LOCK)
list(APPEND WOLFSSL_DEFINITIONS "-DWC_RNG_NO_LOCK")
endif()

# Valgrind (for unit tests)
add_option("WOLFSSL_VALGRIND"
"Enable valgrind for unit tests (default: disabled)"
Expand Down Expand Up @@ -3993,6 +4005,73 @@ if(NOT WOLFSSL_STATICMEMORY STREQUAL "no")
endif()
endif()

# RNG fork handlers (a forked child keeps using its WC_RNG); a build that
# cannot carry them drops them. After the static memory option: it reads it.
add_option("WOLFSSL_RNG_ATFORK"
"Enable pthread_atfork handlers so a forked child can keep using a WC_RNG (default: enabled where supported)"
"yes" "yes;no")
if(WOLFSSL_RNG_ATFORK)
set(RNG_ATFORK_NEEDS "")
if(WOLFSSL_USER_SETTINGS)
set(RNG_ATFORK_NEEDS "user_settings.h to define them")
elseif(WOLFSSL_SINGLE_THREADED OR WOLFSSL_LINUX_KM)
set(RNG_ATFORK_NEEDS "threads and no kernel module")
elseif(NOT WOLFSSL_RNG OR NOT WOLFSSL_RNG_LOCK OR NOT WOLFSSL_HASH_DRBG OR
WOLFSSL_RNG_BANK OR WOLFSSL_STATICMEMORY)
set(RNG_ATFORK_NEEDS "the RNG, its lock and the Hash DRBG, and no RNG bank or static memory")
else()
# real link tests: a toolchain whose try-compile only builds a static
# library reports every function as found
set(RNG_ATFORK_SAVED_LIBS "${CMAKE_REQUIRED_LIBRARIES}")
set(RNG_ATFORK_SAVED_TARGET "${CMAKE_TRY_COMPILE_TARGET_TYPE}")
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
check_function_exists("pthread_atfork" WOLFSSL_HAVE_PTHREAD_ATFORK)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
check_c_source_compiles("
#if defined(__linux__) || defined(__ANDROID__) || \
defined(__CYGWIN__) || defined(__MSYS__)
#define _GNU_SOURCE 1 /* as wc_port.c does */
#endif
#include <stddef.h>
#include <stdint.h>
#include <dlfcn.h>
#include <semaphore.h>
#include <pthread.h>
#ifdef __APPLE__
#error macOS has only named semaphores, which a forked child shares
#endif
int main(void) {
Dl_info info;
const char* name;
sem_t s;
int old;
if (sem_init(&s, 0, 1) == 0)
(void)sem_post(&s);
(void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
if (dladdr((void*)(uintptr_t)main, &info) != 0) {
name = info.dli_fname;
if (name != NULL && name[0] != 0)
(void)dlopen(name, RTLD_NOLOAD | RTLD_NODELETE | RTLD_LAZY);
}
return 0;
}" WOLFSSL_HAVE_DLADDR_PIN)
set(CMAKE_REQUIRED_LIBRARIES "${RNG_ATFORK_SAVED_LIBS}")
set(CMAKE_TRY_COMPILE_TARGET_TYPE "${RNG_ATFORK_SAVED_TARGET}")
if(NOT WOLFSSL_HAVE_PTHREAD_ATFORK)
set(RNG_ATFORK_NEEDS "pthread_atfork")
elseif(NOT WOLFSSL_HAVE_DLADDR_PIN)
set(RNG_ATFORK_NEEDS "dladdr, dlopen, unnamed semaphores and thread cancellation")
endif()
endif()
if(RNG_ATFORK_NEEDS)
message(STATUS "RNG fork handlers off: they need ${RNG_ATFORK_NEEDS}")
else()
list(APPEND WOLFSSL_DEFINITIONS "-DWC_RNG_ATFORK")
list(APPEND WOLFSSL_LINK_LIBS ${CMAKE_DL_LIBS})
endif()
endif()

# TLS (enabled by default; disable for wolfCrypt-only)
add_option("WOLFSSL_TLS" "Enable TLS (default: enabled)" "yes" "yes;no")
if(NOT WOLFSSL_TLS)
Expand Down Expand Up @@ -4162,6 +4241,7 @@ generate_build_flags()
if(WOLFSSL_USER_SETTINGS)
# Replace all options and just use WOLFSSL_USER_SETTINGS
set(WOLFSSL_DEFINITIONS "-DWOLFSSL_USER_SETTINGS")
set(HAVE_GETPID OFF) # user_settings.h decides; keeps options.h in step
endif()

if(WOLFSSL_USER_SETTINGS_ASM)
Expand Down
6 changes: 6 additions & 0 deletions cmake/options.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,12 @@ extern "C" {
#cmakedefine FP_ECC
#undef WC_RNG_BANK_SUPPORT
#cmakedefine WC_RNG_BANK_SUPPORT
#undef WC_RNG_NO_LOCK
#cmakedefine WC_RNG_NO_LOCK
#undef WC_RNG_ATFORK
#cmakedefine WC_RNG_ATFORK
#undef HAVE_GETPID
#cmakedefine HAVE_GETPID
#undef HAVE_VALGRIND
#cmakedefine HAVE_VALGRIND
#undef HAVE_CRL_MONITOR
Expand Down
168 changes: 168 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2754,6 +2754,48 @@ then
fi


# RNG lock (share one WC_RNG between threads)
AC_ARG_ENABLE([rng-lock],
[AS_HELP_STRING([--enable-rng-lock],[Enable the lock that lets one WC_RNG be shared between threads (default: enabled where the build supports it)])],
[ ENABLED_RNG_LOCK=$enableval ],
[ ENABLED_RNG_LOCK=yes ]
)

case "$ENABLED_RNG_LOCK" in
yes|no) ;;
*) AC_MSG_ERROR([--enable-rng-lock takes yes or no]) ;;
esac
# only an explicit ask is an error: the default is yes
if test "x$enable_rng_lock" = "xyes" && test "$ENABLED_RNG" = "no"
then
AC_MSG_ERROR([--enable-rng-lock requires --enable-rng])
fi
if test "$ENABLED_RNG_LOCK" = "no"
then
AM_CFLAGS="$AM_CFLAGS -DWC_RNG_NO_LOCK"
fi

# RNG fork handlers (a forked child keeps using its WC_RNG); decided below
AC_ARG_ENABLE([rng-atfork],
[AS_HELP_STRING([--enable-rng-atfork],[Enable pthread_atfork handlers so a forked child can keep using a WC_RNG (default: enabled where supported)])],
[ ENABLED_RNG_ATFORK=$enableval ],
[ ENABLED_RNG_ATFORK=yes ]
)

case "$ENABLED_RNG_ATFORK" in
yes|no) ;;
*) AC_MSG_ERROR([--enable-rng-atfork takes yes or no]) ;;
esac
if test "$ENABLED_RNG" = "no" || test "$ENABLED_RNG_LOCK" = "no"
then
if test "x$enable_rng_atfork" = "xyes"
then
AC_MSG_ERROR([--enable-rng-atfork requires --enable-rng and --enable-rng-lock])
fi
ENABLED_RNG_ATFORK=no
fi


# DTLS-SCTP
AC_ARG_ENABLE([sctp],
[AS_HELP_STRING([--enable-sctp],[Enable wolfSSL DTLS-SCTP support (default: disabled)])],
Expand Down Expand Up @@ -13250,6 +13292,130 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE___UINT128_T=1"
fi

# RNG lock and fork handlers need threads; the handlers need everything the
# WC_RNG_LOCK_ATFORK gate in random.h asks for
case "$AM_CFLAGS $CPPFLAGS $CFLAGS $EXTRA_CFLAGS" in
*-DSINGLE_THREADED*) ENABLED_RNG_LOCK_THREADS=no ;;
*) ENABLED_RNG_LOCK_THREADS=yes ;;
esac
if test "$ENABLED_SINGLETHREADED" = "yes"
then
ENABLED_RNG_LOCK_THREADS=no
fi
if test "x$enable_rng_lock" = "xyes" && test "$ENABLED_RNG_LOCK_THREADS" = "no"
then
AC_MSG_ERROR([--enable-rng-lock requires threads])
fi
case "$AM_CFLAGS $CPPFLAGS $CFLAGS $EXTRA_CFLAGS" in
*-DCUSTOM_RAND_GENERATE_BLOCK*) ENABLED_RNG_LOCK_CUSTOM=yes ;;
*) ENABLED_RNG_LOCK_CUSTOM=no ;;
esac
if test "$ENABLED_RNG_LOCK_THREADS" = "no" || test "$ENABLED_RNG" = "no" || \
test "$ENABLED_RNG_LOCK_CUSTOM" = "yes" || \
test "$ENABLED_SELFTEST" = "yes" || test "x$ENABLED_HASHDRBG" != "xyes" || \
test "$ENABLED_LINUXKM" = "yes" || test "$ENABLED_BSDKM" = "yes" || \
{ test "$ENABLED_FIPS" = "yes" && test "${HAVE_FIPS_VERSION_MAJOR:-0}" -lt 7; }
then
if test "x$enable_rng_lock" = "xyes"
then
AC_MSG_ERROR([--enable-rng-lock requires threads and the Hash DRBG, and none of selftest, FIPS before v7, a kernel module or a custom rand block])
fi
ENABLED_RNG_LOCK=no
fi
# a build that cannot carry the handlers drops them, unless asked explicitly
if test "$ENABLED_RNG_ATFORK" = "yes"
then
RNG_ATFORK_NEEDS=""
if test "$ENABLED_USERSETTINGS" = "yes"
then
# user_settings.h owns every define in that mode
RNG_ATFORK_NEEDS="user_settings.h to define WC_RNG_ATFORK"
fi
if test "$ENABLED_RNG_LOCK_THREADS" = "no" || \
test "$ENABLED_LINUXKM" = "yes" || test "$ENABLED_BSDKM" = "yes"
then
RNG_ATFORK_NEEDS="${RNG_ATFORK_NEEDS:+$RNG_ATFORK_NEEDS, and }threads and no kernel module"
fi
case "$AM_CFLAGS $CPPFLAGS $CFLAGS $EXTRA_CFLAGS" in
*-DWOLFSSL_STATIC_MEMORY*|*-DWOLFSSL_NO_MALLOC*|*-DCUSTOM_RAND_GENERATE_BLOCK*|*-DWOLFSSL_CHECK_MEM_ZERO*|*-DWOLFSSL_TRACK_MEMORY*|*-DWOLFSSL_MEM_FAIL_COUNT*|*-DWOLFSSL_USER_MUTEX*)
ENABLED_RNG_ATFORK_FLAGS=no ;;
*) ENABLED_RNG_ATFORK_FLAGS=yes ;;
esac
if test "$ENABLED_SELFTEST" = "yes" || test "x$ENABLED_HASHDRBG" != "xyes" || \
test "$ENABLED_ENTROPY_MEMUSE" != "no" || test "$ENABLED_RNG_BANK" = "yes" || \
test "$ENABLED_RNG_ATFORK_FLAGS" = "no" || test "$ENABLED_WNR" = "yes" || \
{ test "$ENABLED_FIPS" = "yes" && test "${HAVE_FIPS_VERSION_MAJOR:-0}" -lt 7; }
then
RNG_ATFORK_NEEDS="${RNG_ATFORK_NEEDS:+$RNG_ATFORK_NEEDS, and }the Hash DRBG with a heap and none of selftest, FIPS before v7, entropy-memuse, rng-bank, static memory, netRandom, memory zero checking or memory tracking"
fi
if test -z "$RNG_ATFORK_NEEDS"
then
saved_LIBS="$LIBS"
AC_SEARCH_LIBS([pthread_atfork], [pthread])
LIBS="$saved_LIBS" # detection only: AX_PTHREAD already added the library
if test "$ac_cv_search_pthread_atfork" = "no"
then
RNG_ATFORK_NEEDS="pthread_atfork"
fi
fi
if test -z "$RNG_ATFORK_NEEDS"
then
# link the real pin: a bare symbol probe passes where the header
# hides dladdr or lacks the RTLD flags
saved_LIBS="$LIBS"
AC_SEARCH_LIBS([dladdr], [dl])
AC_MSG_CHECKING([whether dladdr, dlopen, unnamed semaphores and thread cancellation are available])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#if defined(__linux__) || defined(__ANDROID__) || \
defined(__CYGWIN__) || defined(__MSYS__)
#define _GNU_SOURCE 1 /* as wc_port.c does */
#endif
#include <stddef.h>
#include <stdint.h>
#include <dlfcn.h>
#include <semaphore.h>
#include <pthread.h>
#ifdef __APPLE__
#error "macOS has only named semaphores, which a forked child shares"
#endif
]], [[
Dl_info info;
const char* name;
sem_t s;
int old;
if (sem_init(&s, 0, 1) == 0)
(void)sem_post(&s);
(void)pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
if (dladdr((void*)(uintptr_t)main, &info) != 0) {
name = info.dli_fname;
if (name != NULL && name[0] != '\0')
(void)dlopen(name, RTLD_NOLOAD | RTLD_NODELETE | RTLD_LAZY);
}
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
RNG_ATFORK_NEEDS="dladdr, dlopen, unnamed semaphores and thread cancellation"])
LIBS="$saved_LIBS"
fi
if test -n "$RNG_ATFORK_NEEDS"
then
if test "x$enable_rng_atfork" = "xyes"
then
AC_MSG_ERROR([--enable-rng-atfork requires $RNG_ATFORK_NEEDS])
fi
AC_MSG_NOTICE([RNG fork handlers off: they need $RNG_ATFORK_NEEDS])
ENABLED_RNG_ATFORK=no
fi
fi
if test "$ENABLED_RNG_ATFORK" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DWC_RNG_ATFORK"
case "$ac_cv_search_dladdr" in # -ldl where dladdr needed it
-l*) LIBS="$ac_cv_search_dladdr $LIBS"
PC_LIBS_PRIVATE="$PC_LIBS_PRIVATE $ac_cv_search_dladdr" ;;
esac
fi

# Add HAVE_GETPID to AM_CFLAGS for inclusion in options.h
if test "$ac_cv_func_getpid" = "yes"
then
Expand Down Expand Up @@ -14031,6 +14197,8 @@ echo " * XCHACHA: $ENABLED_XCHACHA"
echo " * Hash DRBG: $ENABLED_HASHDRBG"
echo " * SHA-256 Hash DRBG: $ENABLED_SHA256_DRBG"
echo " * SHA-512 Hash DRBG: $ENABLED_SHA512_DRBG"
echo " * RNG lock: $ENABLED_RNG_LOCK"
echo " * RNG fork handlers: $ENABLED_RNG_ATFORK"
echo " * MmemUse Entropy:"
echo " * (AKA: wolfEntropy): $ENABLED_ENTROPY_MEMUSE"
echo " * PWDBASED: $ENABLED_PWDBASED"
Expand Down
Loading
Loading