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

9
configure vendored
View file

@ -18167,6 +18167,14 @@ _ACEOF
else else
if test "$USE_WINSOCK" = 1; then
case " $LIBOBJS " in
*" getentropy_win.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS getentropy_win.$ac_objext"
;;
esac
else
case `uname` in case `uname` in
Darwin) Darwin)
case " $LIBOBJS " in case " $LIBOBJS " in
@ -18308,6 +18316,7 @@ fi
;; ;;
esac esac
fi
fi fi
done done

View file

@ -977,6 +977,9 @@ 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],,[
if test "$USE_WINSOCK" = 1; then
AC_LIBOBJ(getentropy_win)
else
case `uname` in case `uname` in
Darwin) Darwin)
AC_LIBOBJ(getentropy_osx) AC_LIBOBJ(getentropy_osx)
@ -1000,6 +1003,7 @@ if test "$USE_NSS" = "no"; then
AC_SEARCH_LIBS([clock_gettime], [rt]) AC_SEARCH_LIBS([clock_gettime], [rt])
;; ;;
esac esac
fi
]) ])
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.