Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
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
12 changes: 12 additions & 0 deletions .github/configs/os-check-linux.json
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,19 @@
"configure": ["--enable-she=standard", "--enable-cmac"]},
{"name": "no-verify-oid-fpki", "minutes": 1.2,
"configure": ["CPPFLAGS=-DNO_VERIFY_OID -DWOLFSSL_FPKI"]},
{"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": "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": "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
3 changes: 3 additions & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,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 +1291,7 @@ __MICROBLAZE__
__MINGW32__
__MINGW64_VERSION_MAJOR
__MINGW64__
__MSYS__
__MWERKS__
__NT__
__OS2__
Expand Down
67 changes: 67 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3765,6 +3765,16 @@ 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 lock defaults to yes, so a yes cannot be told from the default; the
# header leaves it 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 +4003,63 @@ if(NOT WOLFSSL_STATICMEMORY STREQUAL "no")
endif()
endif()

# RNG fork handlers (a forked child keeps using its WC_RNG). On by default;
# a build that cannot carry them drops them. Below the static memory option
# because 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)
# CMake sets no defines in that mode; user_settings.h defines
# WC_RNG_ATFORK and WC_RNG_ATFORK_PIN itself
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" HAVE_PTHREAD_ATFORK)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
check_c_source_compiles("
#define _GNU_SOURCE 1
#include <stddef.h>
#include <stdint.h>
#include <dlfcn.h>
int main(void) {
Dl_info info;
const char* name;
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;
}" HAVE_DLADDR)
set(CMAKE_REQUIRED_LIBRARIES "${RNG_ATFORK_SAVED_LIBS}")
set(CMAKE_TRY_COMPILE_TARGET_TYPE "${RNG_ATFORK_SAVED_TARGET}")
if(NOT HAVE_PTHREAD_ATFORK)
set(RNG_ATFORK_NEEDS "pthread_atfork")
elseif(NOT HAVE_DLADDR)
set(RNG_ATFORK_NEEDS "dladdr and dlopen to pin the library against dlclose")
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" "-DWC_RNG_ATFORK_PIN")
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
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 WC_RNG_ATFORK_PIN
#cmakedefine WC_RNG_ATFORK_PIN
#undef HAVE_VALGRIND
#cmakedefine HAVE_VALGRIND
#undef HAVE_CRL_MONITOR
Expand Down
147 changes: 147 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2754,6 +2754,50 @@ 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
# raw enable_rng_lock: the option defaults to yes, so only an explicit ask
# is an error here
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); on wherever the
# build supports them, decided in the late check with the other RNG checks
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 @@ -13248,6 +13292,108 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE___UINT128_T=1"
fi

# RNG lock and fork handlers need threads; the handlers need pthread_atfork
# and everything the WC_RNG_LOCK_ATFORK gate in random.h asks for
# (raw enable_rng_lock: only an explicit ask is an error, the default is yes)
case "$AM_CFLAGS $CPPFLAGS $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
# The handlers default to on; a build that cannot carry them drops them
# silently, unless they were asked for 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 and WC_RNG_ATFORK_PIN"
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" in
*-DWOLFSSL_STATIC_MEMORY*|*-DWOLFSSL_NO_MALLOC*|*-DCUSTOM_RAND_GENERATE_BLOCK*)
ENABLED_RNG_ATFORK_HEAP=no ;;
*) ENABLED_RNG_ATFORK_HEAP=yes ;;
esac
case "$AM_CFLAGS $CPPFLAGS $CFLAGS" in
*-DWOLFSSL_CHECK_MEM_ZERO*) ENABLED_RNG_ATFORK_MEMZERO=yes ;;
*) ENABLED_RNG_ATFORK_MEMZERO=no ;;
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_HEAP" = "no" || test "$ENABLED_WNR" = "yes" || \
test "$ENABLED_RNG_ATFORK_MEMZERO" = "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 or memory zero checking"
fi
if test -z "$RNG_ATFORK_NEEDS"
then
saved_LIBS="$LIBS"
AC_SEARCH_LIBS([pthread_atfork], [pthread])
LIBS="$saved_LIBS"
if test "$ac_cv_search_pthread_atfork" = "no"
then
RNG_ATFORK_NEEDS="pthread_atfork"
fi
fi
if test -z "$RNG_ATFORK_NEEDS"
then
# the handlers can never be removed, so the image holding them is
# pinned with dladdr and dlopen; without them the handlers stay out.
# Compile and link the real thing: 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 and dlopen can pin the library])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#define _GNU_SOURCE 1
#include <stddef.h>
#include <stdint.h>
#include <dlfcn.h>
]], [[
Dl_info info;
const char* name;
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 and dlopen to pin the library against dlclose"])
RNG_ATFORK_DL_LIBS="$LIBS"
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 -DWC_RNG_ATFORK_PIN"
LIBS="$RNG_ATFORK_DL_LIBS" # -ldl where dladdr needed it, only with the pin
fi

# Add HAVE_GETPID to AM_CFLAGS for inclusion in options.h
if test "$ac_cv_func_getpid" = "yes"
then
Expand Down Expand Up @@ -14029,6 +14175,7 @@ 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 fork handlers: $ENABLED_RNG_ATFORK"
echo " * MmemUse Entropy:"
echo " * (AKA: wolfEntropy): $ENABLED_ENTROPY_MEMUSE"
echo " * PWDBASED: $ENABLED_PWDBASED"
Expand Down
Loading
Loading