mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-12 20:51:21 +00:00
Use next generation crypto API on Windows (#2769)
CryptGenRandom is deprecated by Microsoft and may be removed in future releases. They recommend to use the next generation API instead. See https://learn.microsoft.com/en-us/windows/win32/seccng/cng-portal for more details. Also, refactor the random functions to return error codes rather than aborting the program if they fail.
This commit is contained in:
parent
2d0d4a0be9
commit
b39fd516d3
|
@ -614,14 +614,21 @@ fd_table_insert_existing(struct fd_table *ft, __wasi_fd_t in,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Picks an unused slot from the file descriptor table.
|
// Picks an unused slot from the file descriptor table.
|
||||||
static __wasi_fd_t
|
static __wasi_errno_t
|
||||||
fd_table_unused(struct fd_table *ft) REQUIRES_SHARED(ft->lock)
|
fd_table_unused(struct fd_table *ft, __wasi_fd_t *out) REQUIRES_SHARED(ft->lock)
|
||||||
{
|
{
|
||||||
assert(ft->size > ft->used && "File descriptor table has no free slots");
|
assert(ft->size > ft->used && "File descriptor table has no free slots");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
__wasi_fd_t fd = (__wasi_fd_t)random_uniform(ft->size);
|
uintmax_t random_fd = 0;
|
||||||
if (ft->entries[fd].object == NULL)
|
__wasi_errno_t error = random_uniform(ft->size, &random_fd);
|
||||||
return fd;
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (ft->entries[(__wasi_fd_t)random_fd].object == NULL) {
|
||||||
|
*out = (__wasi_fd_t)random_fd;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,10 +648,14 @@ fd_table_insert(wasm_exec_env_t exec_env, struct fd_table *ft,
|
||||||
return convert_errno(errno);
|
return convert_errno(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = fd_table_unused(ft);
|
__wasi_errno_t error = fd_table_unused(ft, out);
|
||||||
|
|
||||||
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
fd_table_attach(ft, *out, fo, rights_base, rights_inheriting);
|
fd_table_attach(ft, *out, fo, rights_base, rights_inheriting);
|
||||||
rwlock_unlock(&ft->lock);
|
rwlock_unlock(&ft->lock);
|
||||||
return 0;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inserts a numerical file descriptor into the file descriptor table.
|
// Inserts a numerical file descriptor into the file descriptor table.
|
||||||
|
@ -2282,8 +2293,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds,
|
||||||
__wasi_errno_t
|
__wasi_errno_t
|
||||||
wasmtime_ssp_random_get(void *buf, size_t nbyte)
|
wasmtime_ssp_random_get(void *buf, size_t nbyte)
|
||||||
{
|
{
|
||||||
random_buf(buf, nbyte);
|
return random_buf(buf, nbyte);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__wasi_errno_t
|
__wasi_errno_t
|
||||||
|
|
|
@ -13,14 +13,16 @@
|
||||||
|
|
||||||
#include "ssp_config.h"
|
#include "ssp_config.h"
|
||||||
#include "bh_platform.h"
|
#include "bh_platform.h"
|
||||||
|
#include "libc_errno.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
#if CONFIG_HAS_ARC4RANDOM_BUF
|
#if CONFIG_HAS_ARC4RANDOM_BUF
|
||||||
|
|
||||||
void
|
__wasi_errno_t
|
||||||
random_buf(void *buf, size_t len)
|
random_buf(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
arc4random_buf(buf, len);
|
arc4random_buf(buf, len);
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif CONFIG_HAS_GETRANDOM
|
#elif CONFIG_HAS_GETRANDOM
|
||||||
|
@ -29,7 +31,7 @@ random_buf(void *buf, size_t len)
|
||||||
#include <sys/random.h>
|
#include <sys/random.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
__wasi_errno_t
|
||||||
random_buf(void *buf, size_t len)
|
random_buf(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -37,57 +39,71 @@ random_buf(void *buf, size_t len)
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
os_printf("getrandom failed: %s", strerror(errno));
|
return convert_errno(errno);
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
if ((size_t)x == len)
|
if ((size_t)x == len)
|
||||||
return;
|
break;
|
||||||
buf = (void *)((unsigned char *)buf + x);
|
buf = (void *)((unsigned char *)buf + x);
|
||||||
len -= (size_t)x;
|
len -= (size_t)x;
|
||||||
}
|
}
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(BH_PLATFORM_WINDOWS)
|
#elif defined(BH_PLATFORM_WINDOWS)
|
||||||
|
|
||||||
#include <wincrypt.h>
|
#include <bcrypt.h>
|
||||||
|
#pragma comment(lib, "Bcrypt.lib")
|
||||||
|
|
||||||
void
|
__wasi_errno_t
|
||||||
random_buf(void *buf, size_t len)
|
random_buf(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
static int crypt_initialized = 0;
|
NTSTATUS ret =
|
||||||
static HCRYPTPROV provider;
|
BCryptGenRandom(NULL, buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||||
if (!crypt_initialized) {
|
|
||||||
CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
|
// Since we pass NULL for the algorithm handle, the only way BCryptGenRandom
|
||||||
CRYPT_VERIFYCONTEXT);
|
// can fail is if one of the parameters is invalid
|
||||||
crypt_initialized = 1;
|
// (STATUS_INVALID_PARAMETER).
|
||||||
}
|
return ret ? __WASI_EINVAL : __WASI_ESUCCESS;
|
||||||
CryptGenRandom(provider, len, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static int urandom;
|
static int urandom = -1;
|
||||||
|
static __wasi_errno_t urandom_error = __WASI_ESUCCESS;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
open_urandom(void)
|
open_urandom(void)
|
||||||
{
|
{
|
||||||
urandom = open("/dev/urandom", O_RDONLY);
|
urandom = open("/dev/urandom", O_RDONLY);
|
||||||
if (urandom < 0) {
|
if (urandom < 0)
|
||||||
os_printf("Failed to open /dev/urandom\n");
|
urandom_error = convert_errno(errno);
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
__wasi_errno_t
|
||||||
random_buf(void *buf, size_t len)
|
random_buf(void *buf, size_t len)
|
||||||
{
|
{
|
||||||
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
|
||||||
pthread_once(&open_once, open_urandom);
|
int pthread_ret = pthread_once(&open_once, open_urandom);
|
||||||
|
|
||||||
if ((size_t)read(urandom, buf, len) != len) {
|
if (pthread_ret != 0)
|
||||||
os_printf("Short read on /dev/urandom\n");
|
return convert_errno(pthread_ret);
|
||||||
abort();
|
|
||||||
|
if (urandom < 0)
|
||||||
|
return urandom_error;
|
||||||
|
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
|
||||||
|
while (bytes_read < len) {
|
||||||
|
ssize_t bytes_read_now =
|
||||||
|
read(urandom, buf + bytes_read, len - bytes_read);
|
||||||
|
|
||||||
|
if (bytes_read_now < 0)
|
||||||
|
return convert_errno(errno);
|
||||||
|
|
||||||
|
bytes_read += (size_t)bytes_read_now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return __WASI_ESUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -99,8 +115,8 @@ random_buf(void *buf, size_t len)
|
||||||
// arc4random() until it lies within the range [2^k % upper, 2^k). As
|
// arc4random() until it lies within the range [2^k % upper, 2^k). As
|
||||||
// this range has length k * upper, we can safely obtain a number
|
// this range has length k * upper, we can safely obtain a number
|
||||||
// without any modulo bias.
|
// without any modulo bias.
|
||||||
uintmax_t
|
__wasi_errno_t
|
||||||
random_uniform(uintmax_t upper)
|
random_uniform(uintmax_t upper, uintmax_t *out)
|
||||||
{
|
{
|
||||||
// Compute 2^k % upper
|
// Compute 2^k % upper
|
||||||
// == (2^k - upper) % upper
|
// == (2^k - upper) % upper
|
||||||
|
@ -108,8 +124,14 @@ random_uniform(uintmax_t upper)
|
||||||
uintmax_t lower = -upper % upper;
|
uintmax_t lower = -upper % upper;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
uintmax_t value;
|
uintmax_t value;
|
||||||
random_buf(&value, sizeof(value));
|
__wasi_errno_t error = random_buf(&value, sizeof(value));
|
||||||
if (value >= lower)
|
|
||||||
return value % upper;
|
if (error != __WASI_ESUCCESS)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (value >= lower) {
|
||||||
|
*out = value % upper;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,12 @@
|
||||||
#ifndef RANDOM_H
|
#ifndef RANDOM_H
|
||||||
#define RANDOM_H
|
#define RANDOM_H
|
||||||
|
|
||||||
void
|
#include "bh_platform.h"
|
||||||
|
|
||||||
|
__wasi_errno_t
|
||||||
random_buf(void *, size_t);
|
random_buf(void *, size_t);
|
||||||
uintmax_t random_uniform(uintmax_t);
|
|
||||||
|
__wasi_errno_t
|
||||||
|
random_uniform(uintmax_t upper, uintmax_t *out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user