windows: Use BCryptGenRandom to implement os.urandom.

Fix urandom not working on windows (there's no /dev/urandom) by using
a proper cryptographic random function (same one as CPython >= 3.11).
This commit is contained in:
stijn 2022-06-07 11:24:42 +02:00 committed by Damien George
parent 5290bfaefe
commit 5bb2a85d74
3 changed files with 14 additions and 1 deletions

View File

@ -39,6 +39,11 @@
#endif #endif
#endif #endif
#if _WIN32
#include <windows.h>
#include <bcrypt.h>
#endif
STATIC mp_obj_t mp_uos_getenv(mp_obj_t var_in) { STATIC mp_obj_t mp_uos_getenv(mp_obj_t var_in) {
const char *s = getenv(mp_obj_str_get_str(var_in)); const char *s = getenv(mp_obj_str_get_str(var_in));
if (s == NULL) { if (s == NULL) {
@ -100,6 +105,12 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) {
mp_int_t n = mp_obj_get_int(num); mp_int_t n = mp_obj_get_int(num);
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, n); vstr_init_len(&vstr, n);
#if _WIN32
NTSTATUS result = BCryptGenRandom(NULL, (unsigned char *)vstr.buf, n, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (!BCRYPT_SUCCESS(result)) {
mp_raise_OSError(errno);
}
#else
#ifdef _HAVE_GETRANDOM #ifdef _HAVE_GETRANDOM
RAISE_ERRNO(getrandom(vstr.buf, n, 0), errno); RAISE_ERRNO(getrandom(vstr.buf, n, 0), errno);
#else #else
@ -108,6 +119,7 @@ STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) {
RAISE_ERRNO(read(fd, vstr.buf, n), errno); RAISE_ERRNO(read(fd, vstr.buf, n), errno);
close(fd); close(fd);
#endif #endif
#endif
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom);

View File

@ -33,7 +33,7 @@ INC += -I$(VARIANT_DIR)
# compiler settings # compiler settings
CFLAGS = $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Werror -std=gnu99 -DUNIX -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) CFLAGS = $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Werror -std=gnu99 -DUNIX -D__USE_MINGW_ANSI_STDIO=1 $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
LDFLAGS = $(LDFLAGS_MOD) -lm $(LDFLAGS_EXTRA) LDFLAGS = $(LDFLAGS_MOD) -lm -lbcrypt $(LDFLAGS_EXTRA)
# Debugging/Optimization # Debugging/Optimization
ifdef DEBUG ifdef DEBUG

View File

@ -32,6 +32,7 @@
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<AdditionalDependencies>Bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>