Description
System.Security.Cryptography.RandomNumberGenerator.Fill() throws PlatformNotSupportedException on WASI (wasi-wasm) targets. This affects both NativeAOT-LLVM and any future WASI runtime that uses the minipal crypto random path.
Root Cause
Two gaps prevent crypto random from working on WASI:
1. src/native/minipal/random.c has no WASI codepath
minipal_get_cryptographically_secure_random_bytes tries:
getrandom() → returns ENOSYS on WASI (not a Linux syscall)
/dev/urandom → returns ENOENT on WASI (no filesystem device nodes)
Both fail, so the function returns -1.
However, wasi-libc provides getentropy() which implements __wasi_random_get() — the WASI equivalent of /dev/urandom. This is already linked and working: the NativeAOT-LLVM C runtime startup uses arc4random_buf() → getentropy() → __wasi_random_get() for stack canary initialization. The import is present and the host provides it.
Proposed fix — add before the /dev/urandom fallback:
#elif defined(__wasi__)
// WASI provides getentropy() via wasi-libc, backed by __wasi_random_get()
// This is already linked for NativeAOT stack canary init
#include <unistd.h>
if (getentropy(buffer, (size_t)bufferLength) == 0)
return 0;
return -1;
2. System.Security.Cryptography.csproj excludes WASI entirely
The csproj's TargetFrameworks lists windows, unix, android, osx, ios, tvos, browser — but not wasi. When TargetPlatformIdentifier is empty (as it is for WASI), the entire assembly is replaced with a PlatformNotSupported stub via GeneratePlatformNotSupportedAssemblyMessage.
Even if minipal is fixed, the managed RandomNumberGenerator class would still throw because the real implementation is never compiled for WASI.
Impact
- Every .NET WASI app that calls
RandomNumberGenerator.Fill(), HashCode (uses random seed), or Directory.GetDirectories (uses HashCode internally) will fail
- Discovered while building a wasm interpreter (nesm) that runs .NET compiled to WASI — directory enumeration traps because
HashCode init can't get a random seed
- Workaround: P/Invoke
wasi_snapshot_preview1.random_get directly, catching PlatformNotSupportedException
Environment
- .NET 10 preview, NativeAOT-LLVM from dotnet/runtimelab
feature/NativeAOT-LLVM
- wasi-sdk 25.0
- wasi-libc provides
getentropy() → __wasi_random_get()
Description
System.Security.Cryptography.RandomNumberGenerator.Fill()throwsPlatformNotSupportedExceptionon WASI (wasi-wasm) targets. This affects both NativeAOT-LLVM and any future WASI runtime that uses the minipal crypto random path.Root Cause
Two gaps prevent crypto random from working on WASI:
1.
src/native/minipal/random.chas no WASI codepathminipal_get_cryptographically_secure_random_bytestries:getrandom()→ returnsENOSYSon WASI (not a Linux syscall)/dev/urandom→ returnsENOENTon WASI (no filesystem device nodes)Both fail, so the function returns -1.
However, wasi-libc provides
getentropy()which implements__wasi_random_get()— the WASI equivalent of/dev/urandom. This is already linked and working: the NativeAOT-LLVM C runtime startup usesarc4random_buf()→getentropy()→__wasi_random_get()for stack canary initialization. The import is present and the host provides it.Proposed fix — add before the
/dev/urandomfallback:2.
System.Security.Cryptography.csprojexcludes WASI entirelyThe csproj's
TargetFrameworkslistswindows,unix,android,osx,ios,tvos,browser— but notwasi. WhenTargetPlatformIdentifieris empty (as it is for WASI), the entire assembly is replaced with aPlatformNotSupportedstub viaGeneratePlatformNotSupportedAssemblyMessage.Even if minipal is fixed, the managed
RandomNumberGeneratorclass would still throw because the real implementation is never compiled for WASI.Impact
RandomNumberGenerator.Fill(),HashCode(uses random seed), orDirectory.GetDirectories(usesHashCodeinternally) will failHashCodeinit can't get a random seedwasi_snapshot_preview1.random_getdirectly, catchingPlatformNotSupportedExceptionEnvironment
feature/NativeAOT-LLVMgetentropy()→__wasi_random_get()