dict: Get random seed from system PRNG

This commit is contained in:
Nick Wellnhofer 2023-12-24 14:27:46 +01:00
parent c49572e57d
commit 2e9e758d1e
4 changed files with 67 additions and 10 deletions

View File

@ -137,6 +137,7 @@ if (NOT MSVC)
check_include_files(fcntl.h HAVE_FCNTL_H)
check_function_exists(fpclass HAVE_FPCLASS)
check_function_exists(ftime HAVE_FTIME)
check_function_exists(getentropy HAVE_GETENTROPY)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_include_files(inttypes.h HAVE_INTTYPES_H)
check_function_exists(isascii HAVE_ISASCII)
@ -151,6 +152,7 @@ if (NOT MSVC)
check_function_exists(stat HAVE_STAT)
check_include_files(stdint.h HAVE_STDINT_H)
check_include_files(sys/mman.h HAVE_SYS_MMAN_H)
check_include_files(sys/random.h HAVE_SYS_RANDOM_H)
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
@ -358,6 +360,8 @@ endif()
if(WIN32)
target_link_libraries(LibXml2 PRIVATE ws2_32)
set(WINSOCK_LIBS "-lws2_32")
target_link_libraries(LibXml2 PRIVATE bcrypt)
set(CRYPTO_LIBS "-lbcrypt")
endif()
if(LIBXML2_WITH_ICONV)
@ -641,7 +645,7 @@ if(LIBXML2_WITH_PYTHON)
configure_file(python/setup.py.in setup.py @ONLY)
endif()
set(NON_PC_LIBS "${THREAD_LIBS} ${ICONV_LIBS} ${LIBM} ${WINSOCK_LIBS}")
set(NON_PC_LIBS "${THREAD_LIBS} ${ICONV_LIBS} ${LIBM} ${WINSOCK_LIBS} ${CRYPTO_LIBS}")
list(APPEND XML_PC_LIBS "${NON_PC_LIBS}")
list(APPEND XML_PRIVATE_LIBS "${NON_PC_LIBS}")
list(REMOVE_DUPLICATES XML_PC_LIBS)

View File

@ -22,6 +22,9 @@
/* Define to 1 if you have the `ftime' function. */
#cmakedefine HAVE_FTIME 1
/* Define to 1 if you have the `getentropy' function. */
#cmakedefine HAVE_GETENTROPY 1
/* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine HAVE_GETTIMEOFDAY 1
@ -72,6 +75,9 @@
/* Define to 1 if you have the <sys/mman.h> header file. */
#cmakedefine HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/random.h> header file. */
#cmakedefine HAVE_SYS_RANDOM_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#cmakedefine HAVE_SYS_SELECT_H 1

View File

@ -300,6 +300,7 @@ AC_CHECK_HEADERS([sys/mman.h])
AC_CHECK_HEADERS([sys/socket.h netinet/in.h arpa/inet.h netdb.h])
AC_CHECK_HEADERS([sys/select.h poll.h])
AC_CHECK_HEADERS([sys/time.h sys/timeb.h])
AC_CHECK_HEADERS([sys/random.h])
AC_CHECK_HEADERS([dl.h dlfcn.h])
AC_CHECK_HEADERS([glob.h])
AM_CONDITIONAL(WITH_GLOB, test "$ac_cv_header_glob_h" = "yes")
@ -310,7 +311,7 @@ dnl
AC_TYPE_UINT32_T
dnl Checks for library functions.
AC_CHECK_FUNCS([gettimeofday ftime stat isascii mmap munmap])
AC_CHECK_FUNCS([getentropy gettimeofday ftime isascii stat mmap munmap])
AH_VERBATIM([HAVE_MUNMAP_AFTER],[/* mmap() is no good without munmap() */
#if defined(HAVE_MMAP) && !defined(HAVE_MUNMAP)
@ -1104,6 +1105,15 @@ else
fi
AC_SUBST(WITH_ICU)
dnl
dnl Crypto libraries
dnl
case "$host" in
*-*-mingw*)
CRYPTO_LIBS="-lbcrypt"
;;
esac
if test "$with_coverage" = "yes" && test "${GCC}" = "yes"
then
echo Enabling code coverage for GCC
@ -1115,7 +1125,7 @@ fi
XML_LIBS="-lxml2"
XML_LIBTOOLLIBS="libxml2.la"
NON_PC_LIBS="${THREAD_LIBS} ${ICONV_LIBS} ${LIBM} ${NET_LIBS}"
NON_PC_LIBS="${THREAD_LIBS} ${ICONV_LIBS} ${LIBM} ${NET_LIBS} ${CRYPTO_LIBS}"
XML_PC_LIBS="${XML_PC_LIBS} ${NON_PC_LIBS}"
XML_PRIVATE_LIBS="${XML_PRIVATE_LIBS} ${NON_PC_LIBS}"
XML_PRIVATE_CFLAGS="${XML_PRIVATE_CFLAGS} ${THREAD_CFLAGS} ${ICONV_CFLAGS}"

51
dict.c
View File

@ -19,9 +19,20 @@
#define IN_LIBXML
#include "libxml.h"
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_SYS_RANDOM_H
#include <sys/random.h>
#endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <bcrypt.h>
#endif
#include "private/dict.h"
#include "private/threads.h"
@ -916,16 +927,42 @@ static XML_THREAD_LOCAL unsigned localRngState[2];
ATTRIBUTE_NO_SANITIZE_INTEGER
void
xmlInitRandom(void) {
int var;
xmlInitMutex(&xmlRngMutex);
/* TODO: Get seed values from system PRNG */
{
#ifdef _WIN32
NTSTATUS status;
globalRngState[0] = (unsigned) time(NULL) ^
HASH_ROL((unsigned) ((size_t) &xmlInitRandom & 0xFFFFFFFF), 8);
globalRngState[1] = HASH_ROL((unsigned) ((size_t) &xmlRngMutex & 0xFFFFFFFF), 16) ^
HASH_ROL((unsigned) ((size_t) &var & 0xFFFFFFFF), 24);
status = BCryptGenRandom(NULL, (unsigned char *) globalRngState,
sizeof(globalRngState),
BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (!BCRYPT_SUCCESS(status)) {
fprintf(stderr, "libxml2: BCryptGenRandom failed with "
"error code %lu\n", GetLastError());
abort();
}
#elif defined(HAVE_GETENTROPY)
while (1) {
if (getentropy(globalRngState, sizeof(globalRngState)) == 0)
break;
if (errno != EINTR) {
fprintf(stderr, "libxml2: getentropy failed with "
"error code %d\n", errno);
abort();
}
}
#else
int var;
globalRngState[0] =
(unsigned) time(NULL) ^
HASH_ROL((unsigned) ((size_t) &xmlInitRandom & 0xFFFFFFFF), 8);
globalRngState[1] =
HASH_ROL((unsigned) ((size_t) &xmlRngMutex & 0xFFFFFFFF), 16) ^
HASH_ROL((unsigned) ((size_t) &var & 0xFFFFFFFF), 24);
#endif
}
}
void