From: Wouter Wijngaards Date: Fri, 11 Jul 2014 14:46:46 +0000 (+0000) Subject: - arc4random, getentropy and explicit_bzero compat for Windows. X-Git-Tag: release-1.5.0rc1~88 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12137fe970ea53af8ffb601b3bb354ee6132a658;p=thirdparty%2Funbound.git - arc4random, getentropy and explicit_bzero compat for Windows. git-svn-id: file:///svn/unbound/trunk@3172 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/Makefile.in b/Makefile.in index 742b0fba1..63a67ec29 100644 --- a/Makefile.in +++ b/Makefile.in @@ -125,9 +125,9 @@ COMPAT_SRC=compat/ctime_r.c compat/fake-rfc2553.c compat/gmtime_r.c \ compat/inet_aton.c compat/inet_ntop.c compat/inet_pton.c compat/malloc.c \ compat/memcmp.c compat/memmove.c compat/snprintf.c compat/strlcat.c \ compat/strlcpy.c compat/strptime.c compat/getentropy_linux.c \ -compat/getentropy_osx.c compat/getentropy_solaris.c compat/explicit_bzero.c \ -compat/arc4random.c compat/arc4random_uniform.c compat/arc4_lock.c \ -compat/sha512.c +compat/getentropy_osx.c compat/getentropy_solaris.c compat/getentropy_win.c \ +compat/explicit_bzero.c compat/arc4random.c compat/arc4random_uniform.c \ +compat/arc4_lock.c compat/sha512.c COMPAT_OBJ=$(LIBOBJS:.o=.lo) COMPAT_OBJ_WITHOUT_CTIME=$(LIBOBJ_WITHOUT_CTIME:.o=.lo) COMPAT_OBJ_WITHOUT_CTIMEARC4=$(LIBOBJ_WITHOUT_CTIMEARC4:.o=.lo) @@ -1173,6 +1173,7 @@ strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c +getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c $(srcdir)/compat/chacha_private.h arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c $(srcdir)/compat/chacha_private.h diff --git a/compat/arc4random.c b/compat/arc4random.c index dd4e5cc00..50950e89d 100644 --- a/compat/arc4random.c +++ b/compat/arc4random.c @@ -33,12 +33,14 @@ #include #include #include +#ifndef UB_ON_WINDOWS #include +#endif #define KEYSTREAM_ONLY #include "chacha_private.h" -#define min(a, b) ((a) < (b) ? (a) : (b)) +#define arc4_min(a, b) ((a) < (b) ? (a) : (b)) #ifdef __GNUC__ #define inline __inline #else /* !__GNUC__ */ @@ -71,18 +73,30 @@ _rs_init(u_char *buf, size_t n) return; if (rs == NULL) { +#ifndef UB_ON_WINDOWS if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) abort(); #ifdef MAP_INHERIT_ZERO if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1) abort(); +#endif +#else /* WINDOWS */ + rs = malloc(sizeof(*rs)); + if(!rs) + abort(); #endif } if (rsx == NULL) { +#ifndef UB_ON_WINDOWS if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) abort(); +#else /* WINDOWS */ + rsx = malloc(sizeof(*rsx)); + if(!rsx) + abort(); +#endif } chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0); @@ -94,8 +108,13 @@ _rs_stir(void) { u_char rnd[KEYSZ + IVSZ]; - if (getentropy(rnd, sizeof rnd) == -1) + if (getentropy(rnd, sizeof rnd) == -1) { +#ifdef SIGKILL raise(SIGKILL); +#else + exit(9); /* windows */ +#endif + } if (!rs) _rs_init(rnd, sizeof(rnd)); @@ -145,7 +164,7 @@ _rs_rekey(u_char *dat, size_t datlen) if (dat) { size_t i, m; - m = min(datlen, KEYSZ + IVSZ); + m = arc4_min(datlen, KEYSZ + IVSZ); for (i = 0; i < m; i++) rsx->rs_buf[i] ^= dat[i]; } @@ -165,7 +184,7 @@ _rs_random_buf(void *_buf, size_t n) _rs_stir_if_needed(n); while (n > 0) { if (rs->rs_have > 0) { - m = min(n, rs->rs_have); + m = arc4_min(n, rs->rs_have); keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have; memcpy(buf, keystream, m); diff --git a/compat/explicit_bzero.c b/compat/explicit_bzero.c index c428dae7f..a3ba2798a 100644 --- a/compat/explicit_bzero.c +++ b/compat/explicit_bzero.c @@ -14,6 +14,9 @@ __explicit_bzero_hook(void *ATTR_UNUSED(buf), size_t ATTR_UNUSED(len)) void explicit_bzero(void *buf, size_t len) { +#ifdef UB_ON_WINDOWS + SecureZeroMemory(buf, len); +#endif memset(buf, 0, len); __explicit_bzero_hook(buf, len); } diff --git a/compat/getentropy_win.c b/compat/getentropy_win.c new file mode 100644 index 000000000..cad15d4aa --- /dev/null +++ b/compat/getentropy_win.c @@ -0,0 +1,65 @@ +/* getentropy_win.c - get entropy on Windows. +* + * Copyright (c) 2014, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" + +int +getentropy(void *buf, size_t len) +{ + HMODULE lib; + + if(len > 256) { + errno = EIO; + return -1; + } + + /* Get entropy with windows secure random number generator, + * for windows XP and later, it is in the ADVAPI32 dll */ + lib = LoadLibrary("ADVAPI32.DLL"); + if(lib) { + /* Load the RtlGenRandom function */ + BOOLEAN (APIENTRY* genrandom)(void*,ULONG) = + (BOOLEAN (APIENTRY*)(void*,ULONG)) + GetProcAddress(lib, "SystemFunction036"); + if(genrandom) { + if(genrandom(buf, len)) { + FreeLibrary(lib); + return 0; /* success */ + } + } + FreeLibrary(lib); + } + + errno = EIO; + return -1; +} diff --git a/configure b/configure index aa10bd2ec..007b89ee2 100755 --- a/configure +++ b/configure @@ -18167,23 +18167,31 @@ _ACEOF else - case `uname` in - Darwin) + if test "$USE_WINSOCK" = 1; then case " $LIBOBJS " in + *" getentropy_win.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS getentropy_win.$ac_objext" + ;; +esac + + else + case `uname` in + Darwin) + case " $LIBOBJS " in *" getentropy_osx.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getentropy_osx.$ac_objext" ;; esac - ;; - SunOS) - case " $LIBOBJS " in + ;; + SunOS) + case " $LIBOBJS " in *" getentropy_solaris.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getentropy_solaris.$ac_objext" ;; esac - for ac_header in sys/sha2.h + for ac_header in sys/sha2.h do : ac_fn_c_check_header_compile "$LINENO" "sys/sha2.h" "ac_cv_header_sys_sha2_h" "$ac_includes_default " @@ -18194,7 +18202,7 @@ _ACEOF else - for ac_func in SHA512_Update + for ac_func in SHA512_Update do : ac_fn_c_check_func "$LINENO" "SHA512_Update" "ac_cv_func_SHA512_Update" if test "x$ac_cv_func_SHA512_Update" = xyes; then : @@ -18204,7 +18212,7 @@ _ACEOF else - case " $LIBOBJS " in + case " $LIBOBJS " in *" sha512.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS sha512.$ac_objext" ;; @@ -18219,18 +18227,18 @@ fi done - if test "$ac_cv_header_sys_sha2_h" = "yes"; then - LIBS="$LIBS -lmd" - fi - ;; - Linux|*) - case " $LIBOBJS " in + if test "$ac_cv_header_sys_sha2_h" = "yes"; then + LIBS="$LIBS -lmd" + fi + ;; + Linux|*) + case " $LIBOBJS " in *" getentropy_linux.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getentropy_linux.$ac_objext" ;; esac - for ac_func in SHA512_Update + for ac_func in SHA512_Update do : ac_fn_c_check_func "$LINENO" "SHA512_Update" "ac_cv_func_SHA512_Update" if test "x$ac_cv_func_SHA512_Update" = xyes; then : @@ -18240,7 +18248,7 @@ _ACEOF else - case " $LIBOBJS " in + case " $LIBOBJS " in *" sha512.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS sha512.$ac_objext" ;; @@ -18250,7 +18258,7 @@ esac fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 $as_echo_n "checking for library containing clock_gettime... " >&6; } if ${ac_cv_search_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 @@ -18306,8 +18314,9 @@ if test "$ac_res" != no; then : fi - ;; - esac + ;; + esac + fi fi done diff --git a/configure.ac b/configure.ac index 066b5e9c0..29b8161a1 100644 --- a/configure.ac +++ b/configure.ac @@ -977,29 +977,33 @@ if test "$USE_NSS" = "no"; then AC_LIBOBJ(explicit_bzero) AC_LIBOBJ(arc4_lock) AC_CHECK_FUNCS([getentropy],,[ - case `uname` in - Darwin) - AC_LIBOBJ(getentropy_osx) - ;; - SunOS) - AC_LIBOBJ(getentropy_solaris) - AC_CHECK_HEADERS([sys/sha2.h],, [ + if test "$USE_WINSOCK" = 1; then + AC_LIBOBJ(getentropy_win) + else + case `uname` in + Darwin) + AC_LIBOBJ(getentropy_osx) + ;; + SunOS) + AC_LIBOBJ(getentropy_solaris) + AC_CHECK_HEADERS([sys/sha2.h],, [ + AC_CHECK_FUNCS([SHA512_Update],,[ + AC_LIBOBJ(sha512) + ]) + ], [AC_INCLUDES_DEFAULT]) + if test "$ac_cv_header_sys_sha2_h" = "yes"; then + LIBS="$LIBS -lmd" + fi + ;; + Linux|*) + AC_LIBOBJ(getentropy_linux) AC_CHECK_FUNCS([SHA512_Update],,[ AC_LIBOBJ(sha512) ]) - ], [AC_INCLUDES_DEFAULT]) - if test "$ac_cv_header_sys_sha2_h" = "yes"; then - LIBS="$LIBS -lmd" - fi - ;; - Linux|*) - AC_LIBOBJ(getentropy_linux) - AC_CHECK_FUNCS([SHA512_Update],,[ - AC_LIBOBJ(sha512) - ]) - AC_SEARCH_LIBS([clock_gettime], [rt]) - ;; - esac + AC_SEARCH_LIBS([clock_gettime], [rt]) + ;; + esac + fi ]) fi fi diff --git a/doc/Changelog b/doc/Changelog index 1fae6ace8..0b5db0765 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -4,6 +4,7 @@ This makes arc4random available on all platforms, except when compiled with LIBNSS (it uses libNSS crypto random). - fix strptime implicit declaration error on OpenBSD. + - arc4random, getentropy and explicit_bzero compat for Windows. 4 July 2014: Wouter - Fix #593: segfault or crash upon rotating logfile.