Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -119,11 +119,36 @@ fi dnl Random number generation mechanisms AC_CHECK_FUNCS(getrandom,, [ AC_CHECK_FUNCS(getentropy,, [ - AC_CHECK_FUNCS(CryptGenRandom) + AC_CACHE_CHECK([for CryptGenRandom], nanotcl_cv_func_CryptGenRandom, [ + save_LIBS="${LIBS}" + LIBS="${save_LIBS} -ladvapi32" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include + ]], [[ + HCRYPTPROV provider; + BOOL ret; + ret = CryptGenRandom(provider, 0, NULL); + if (ret) { + return(0); + } else { + return(1); + } + ]])], [ + nanotcl_cv_func_CryptGenRandom='yes' + ], [ + nanotcl_cv_func_CryptGenRandom='no' + ]) + LIBS="${save_LIBS}" + ]) + if test "x$nanotcl_cv_func_CryptGenRandom" = 'xyes'; then + LIBS="${LIBS} -ladvapi32" + AC_DEFINE(HAVE_CRYPTGENRANDOM, [1], [Define if we have CryptGenRandom]) + fi ]) ]) dnl Check for name resolution capabilities AC_CHECK_FUNCS(getaddrinfo, [ Index: randombytes.c ================================================================== --- randombytes.c +++ randombytes.c @@ -71,14 +71,31 @@ return(-1); } return(buflen); } -#elif defined(HAVE_CRYPTGENRANDOM) && 0 -#include +#elif defined(HAVE_CRYPTGENRANDOM) +# include +# include static long getrandom_impl(void *buf, unsigned int buflen) { - Tcl_Panic("Incomplete CryptGenRandom"); + HCRYPTPROV provider; + BOOL cac_ret, cgr_ret; + + cac_ret = CryptAcquireContextA(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT); + if (cac_ret == FALSE) { + return(-1); + } + + cgr_ret = CryptGenRandom(provider, buflen, (BYTE *) buf); + + CryptReleaseContext(provider, 0); + + if (cgr_ret == FALSE) { + return(-1); + } + + return(buflen); } #else # ifdef HAVE_SYS_TYPES_H # include # endif