- arc4random, getentropy and explicit_bzero compat for Windows.

git-svn-id: file:///svn/unbound/trunk@3172 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2014-07-11 14:46:46 +00:00
parent 8786ae15b4
commit 12137fe970
7 changed files with 174 additions and 72 deletions

View file

@ -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/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/memcmp.c compat/memmove.c compat/snprintf.c compat/strlcat.c \
compat/strlcpy.c compat/strptime.c compat/getentropy_linux.c \ compat/strlcpy.c compat/strptime.c compat/getentropy_linux.c \
compat/getentropy_osx.c compat/getentropy_solaris.c compat/explicit_bzero.c \ compat/getentropy_osx.c compat/getentropy_solaris.c compat/getentropy_win.c \
compat/arc4random.c compat/arc4random_uniform.c compat/arc4_lock.c \ compat/explicit_bzero.c compat/arc4random.c compat/arc4random_uniform.c \
compat/sha512.c compat/arc4_lock.c compat/sha512.c
COMPAT_OBJ=$(LIBOBJS:.o=.lo) COMPAT_OBJ=$(LIBOBJS:.o=.lo)
COMPAT_OBJ_WITHOUT_CTIME=$(LIBOBJ_WITHOUT_CTIME:.o=.lo) COMPAT_OBJ_WITHOUT_CTIME=$(LIBOBJ_WITHOUT_CTIME:.o=.lo)
COMPAT_OBJ_WITHOUT_CTIMEARC4=$(LIBOBJ_WITHOUT_CTIMEARC4:.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_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.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 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.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 arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c $(srcdir)/compat/chacha_private.h

View file

@ -33,12 +33,14 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#ifndef UB_ON_WINDOWS
#include <sys/mman.h> #include <sys/mman.h>
#endif
#define KEYSTREAM_ONLY #define KEYSTREAM_ONLY
#include "chacha_private.h" #include "chacha_private.h"
#define min(a, b) ((a) < (b) ? (a) : (b)) #define arc4_min(a, b) ((a) < (b) ? (a) : (b))
#ifdef __GNUC__ #ifdef __GNUC__
#define inline __inline #define inline __inline
#else /* !__GNUC__ */ #else /* !__GNUC__ */
@ -71,18 +73,30 @@ _rs_init(u_char *buf, size_t n)
return; return;
if (rs == NULL) { if (rs == NULL) {
#ifndef UB_ON_WINDOWS
if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE, if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
abort(); abort();
#ifdef MAP_INHERIT_ZERO #ifdef MAP_INHERIT_ZERO
if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1) if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1)
abort(); abort();
#endif
#else /* WINDOWS */
rs = malloc(sizeof(*rs));
if(!rs)
abort();
#endif #endif
} }
if (rsx == NULL) { if (rsx == NULL) {
#ifndef UB_ON_WINDOWS
if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE, if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
abort(); abort();
#else /* WINDOWS */
rsx = malloc(sizeof(*rsx));
if(!rsx)
abort();
#endif
} }
chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0); chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
@ -94,8 +108,13 @@ _rs_stir(void)
{ {
u_char rnd[KEYSZ + IVSZ]; u_char rnd[KEYSZ + IVSZ];
if (getentropy(rnd, sizeof rnd) == -1) if (getentropy(rnd, sizeof rnd) == -1) {
#ifdef SIGKILL
raise(SIGKILL); raise(SIGKILL);
#else
exit(9); /* windows */
#endif
}
if (!rs) if (!rs)
_rs_init(rnd, sizeof(rnd)); _rs_init(rnd, sizeof(rnd));
@ -145,7 +164,7 @@ _rs_rekey(u_char *dat, size_t datlen)
if (dat) { if (dat) {
size_t i, m; size_t i, m;
m = min(datlen, KEYSZ + IVSZ); m = arc4_min(datlen, KEYSZ + IVSZ);
for (i = 0; i < m; i++) for (i = 0; i < m; i++)
rsx->rs_buf[i] ^= dat[i]; rsx->rs_buf[i] ^= dat[i];
} }
@ -165,7 +184,7 @@ _rs_random_buf(void *_buf, size_t n)
_rs_stir_if_needed(n); _rs_stir_if_needed(n);
while (n > 0) { while (n > 0) {
if (rs->rs_have > 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) keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
- rs->rs_have; - rs->rs_have;
memcpy(buf, keystream, m); memcpy(buf, keystream, m);

View file

@ -14,6 +14,9 @@ __explicit_bzero_hook(void *ATTR_UNUSED(buf), size_t ATTR_UNUSED(len))
void void
explicit_bzero(void *buf, size_t len) explicit_bzero(void *buf, size_t len)
{ {
#ifdef UB_ON_WINDOWS
SecureZeroMemory(buf, len);
#endif
memset(buf, 0, len); memset(buf, 0, len);
__explicit_bzero_hook(buf, len); __explicit_bzero_hook(buf, len);
} }

65
compat/getentropy_win.c Normal file
View file

@ -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;
}

99
configure vendored
View file

@ -18167,23 +18167,31 @@ _ACEOF
else else
case `uname` in if test "$USE_WINSOCK" = 1; then
Darwin)
case " $LIBOBJS " in 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 "* ) ;; *" getentropy_osx.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS getentropy_osx.$ac_objext" *) LIBOBJS="$LIBOBJS getentropy_osx.$ac_objext"
;; ;;
esac esac
;; ;;
SunOS) SunOS)
case " $LIBOBJS " in case " $LIBOBJS " in
*" getentropy_solaris.$ac_objext "* ) ;; *" getentropy_solaris.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS getentropy_solaris.$ac_objext" *) LIBOBJS="$LIBOBJS getentropy_solaris.$ac_objext"
;; ;;
esac esac
for ac_header in sys/sha2.h for ac_header in sys/sha2.h
do : do :
ac_fn_c_check_header_compile "$LINENO" "sys/sha2.h" "ac_cv_header_sys_sha2_h" "$ac_includes_default ac_fn_c_check_header_compile "$LINENO" "sys/sha2.h" "ac_cv_header_sys_sha2_h" "$ac_includes_default
" "
@ -18194,6 +18202,42 @@ _ACEOF
else else
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 :
cat >>confdefs.h <<_ACEOF
#define HAVE_SHA512_UPDATE 1
_ACEOF
else
case " $LIBOBJS " in
*" sha512.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS sha512.$ac_objext"
;;
esac
fi
done
fi
done
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 : do :
ac_fn_c_check_func "$LINENO" "SHA512_Update" "ac_cv_func_SHA512_Update" ac_fn_c_check_func "$LINENO" "SHA512_Update" "ac_cv_func_SHA512_Update"
@ -18214,43 +18258,7 @@ esac
fi fi
done done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
fi
done
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
do :
ac_fn_c_check_func "$LINENO" "SHA512_Update" "ac_cv_func_SHA512_Update"
if test "x$ac_cv_func_SHA512_Update" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_SHA512_UPDATE 1
_ACEOF
else
case " $LIBOBJS " in
*" sha512.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS sha512.$ac_objext"
;;
esac
fi
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
$as_echo_n "checking for library containing clock_gettime... " >&6; } $as_echo_n "checking for library containing clock_gettime... " >&6; }
if ${ac_cv_search_clock_gettime+:} false; then : if ${ac_cv_search_clock_gettime+:} false; then :
$as_echo_n "(cached) " >&6 $as_echo_n "(cached) " >&6
@ -18306,8 +18314,9 @@ if test "$ac_res" != no; then :
fi fi
;; ;;
esac esac
fi
fi fi
done done

View file

@ -977,29 +977,33 @@ if test "$USE_NSS" = "no"; then
AC_LIBOBJ(explicit_bzero) AC_LIBOBJ(explicit_bzero)
AC_LIBOBJ(arc4_lock) AC_LIBOBJ(arc4_lock)
AC_CHECK_FUNCS([getentropy],,[ AC_CHECK_FUNCS([getentropy],,[
case `uname` in if test "$USE_WINSOCK" = 1; then
Darwin) AC_LIBOBJ(getentropy_win)
AC_LIBOBJ(getentropy_osx) else
;; case `uname` in
SunOS) Darwin)
AC_LIBOBJ(getentropy_solaris) AC_LIBOBJ(getentropy_osx)
AC_CHECK_HEADERS([sys/sha2.h],, [ ;;
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_CHECK_FUNCS([SHA512_Update],,[
AC_LIBOBJ(sha512) AC_LIBOBJ(sha512)
]) ])
], [AC_INCLUDES_DEFAULT]) AC_SEARCH_LIBS([clock_gettime], [rt])
if test "$ac_cv_header_sys_sha2_h" = "yes"; then ;;
LIBS="$LIBS -lmd" esac
fi fi
;;
Linux|*)
AC_LIBOBJ(getentropy_linux)
AC_CHECK_FUNCS([SHA512_Update],,[
AC_LIBOBJ(sha512)
])
AC_SEARCH_LIBS([clock_gettime], [rt])
;;
esac
]) ])
fi fi
fi fi

View file

@ -4,6 +4,7 @@
This makes arc4random available on all platforms, except when This makes arc4random available on all platforms, except when
compiled with LIBNSS (it uses libNSS crypto random). compiled with LIBNSS (it uses libNSS crypto random).
- fix strptime implicit declaration error on OpenBSD. - fix strptime implicit declaration error on OpenBSD.
- arc4random, getentropy and explicit_bzero compat for Windows.
4 July 2014: Wouter 4 July 2014: Wouter
- Fix #593: segfault or crash upon rotating logfile. - Fix #593: segfault or crash upon rotating logfile.