diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-rawdylib-processprng.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-rawdylib-processprng.patch
new file mode 100644
index 0000000000000..6af11e54d88af
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-rawdylib-processprng.patch
@@ -0,0 +1,47 @@
+From 9f65e742ba3e41474e6126c6c4469c48eaa6ca7e Mon Sep 17 00:00:00 2001
+From: Chris Denton <chris@chrisdenton.dev>
+Date: Tue, 20 Feb 2024 16:01:40 -0300
+Subject: [PATCH] Don't use raw-dylib in std
+
+---
+ library/std/src/sys/pal/windows/c.rs    | 2 +-
+ library/std/src/sys/pal/windows/rand.rs | 3 +--
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
+index ad8e01bfa9b..9ca8e4c16ce 100644
+--- a/library/std/src/sys/pal/windows/c.rs
++++ b/library/std/src/sys/pal/windows/c.rs
+@@ -323,7 +323,7 @@ pub unsafe fn NtWriteFile(
+ 
+ // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
+ cfg_if::cfg_if! {
+-if #[cfg(not(target_vendor = "win7"))] {
++if #[cfg(any())] {
+     #[cfg(target_arch = "x86")]
+     #[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
+     extern "system" {
+diff --git a/library/std/src/sys/pal/windows/rand.rs b/library/std/src/sys/pal/windows/rand.rs
+index e427546222a..f2fe42a4d51 100644
+--- a/library/std/src/sys/pal/windows/rand.rs
++++ b/library/std/src/sys/pal/windows/rand.rs
+@@ -2,7 +2,7 @@
+ use core::mem;
+ use core::ptr;
+ 
+-#[cfg(not(target_vendor = "win7"))]
++#[cfg(any())]
+ #[inline]
+ pub fn hashmap_random_keys() -> (u64, u64) {
+     let mut v = (0, 0);
+@@ -13,7 +13,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
+     v
+ }
+ 
+-#[cfg(target_vendor = "win7")]
+ pub fn hashmap_random_keys() -> (u64, u64) {
+     use crate::ffi::c_void;
+     use crate::io;
+-- 
+2.42.0.windows.2
+
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 6b12d7db8b03a..ad8e01bfa9b03 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -321,6 +321,21 @@ pub unsafe fn NtWriteFile(
 }
 }
 
+// Use raw-dylib to import ProcessPrng as we can't rely on there being an import library.
+cfg_if::cfg_if! {
+if #[cfg(not(target_vendor = "win7"))] {
+    #[cfg(target_arch = "x86")]
+    #[link(name = "bcryptprimitives", kind = "raw-dylib", import_name_type = "undecorated")]
+    extern "system" {
+        pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
+    }
+    #[cfg(not(target_arch = "x86"))]
+    #[link(name = "bcryptprimitives", kind = "raw-dylib")]
+    extern "system" {
+        pub fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
+    }
+}}
+
 // Functions that aren't available on every version of Windows that we support,
 // but we still use them and just provide some form of a fallback implementation.
 compat_fn_with_fallback! {
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 726f1c3df8294..ab2a8caf5dfd9 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2180,10 +2180,6 @@ Windows.Win32.Networking.WinSock.WSATRY_AGAIN
 Windows.Win32.Networking.WinSock.WSATYPE_NOT_FOUND
 Windows.Win32.Networking.WinSock.WSAVERNOTSUPPORTED
 Windows.Win32.Security.Authentication.Identity.RtlGenRandom
-Windows.Win32.Security.Cryptography.BCRYPT_ALG_HANDLE
-Windows.Win32.Security.Cryptography.BCRYPT_USE_SYSTEM_PREFERRED_RNG
-Windows.Win32.Security.Cryptography.BCryptGenRandom
-Windows.Win32.Security.Cryptography.BCRYPTGENRANDOM_FLAGS
 Windows.Win32.Security.SECURITY_ATTRIBUTES
 Windows.Win32.Security.TOKEN_ACCESS_MASK
 Windows.Win32.Security.TOKEN_ACCESS_PSEUDO_HANDLE
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index c386b66a722df..8eb779373f7e4 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -15,15 +15,6 @@ extern "system" {
     pub fn RtlGenRandom(randombuffer: *mut ::core::ffi::c_void, randombufferlength: u32)
     -> BOOLEAN;
 }
-#[link(name = "bcrypt")]
-extern "system" {
-    pub fn BCryptGenRandom(
-        halgorithm: BCRYPT_ALG_HANDLE,
-        pbbuffer: *mut u8,
-        cbbuffer: u32,
-        dwflags: BCRYPTGENRANDOM_FLAGS,
-    ) -> NTSTATUS;
-}
 #[link(name = "kernel32")]
 extern "system" {
     pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> ();
@@ -889,9 +880,6 @@ impl ::core::clone::Clone for ARM64_NT_NEON128_0 {
         *self
     }
 }
-pub type BCRYPTGENRANDOM_FLAGS = u32;
-pub type BCRYPT_ALG_HANDLE = *mut ::core::ffi::c_void;
-pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: BCRYPTGENRANDOM_FLAGS = 2u32;
 pub const BELOW_NORMAL_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 16384u32;
 pub type BOOL = i32;
 pub type BOOLEAN = u8;
diff --git a/library/std/src/sys/pal/windows/rand.rs b/library/std/src/sys/pal/windows/rand.rs
index bd1ae6b06076e..e427546222aea 100644
--- a/library/std/src/sys/pal/windows/rand.rs
+++ b/library/std/src/sys/pal/windows/rand.rs
@@ -1,42 +1,27 @@
-use crate::mem;
-use crate::ptr;
 use crate::sys::c;
+use core::mem;
+use core::ptr;
 
+#[cfg(not(target_vendor = "win7"))]
+#[inline]
 pub fn hashmap_random_keys() -> (u64, u64) {
     let mut v = (0, 0);
-    let ret = unsafe {
-        c::BCryptGenRandom(
-            ptr::null_mut(),
-            core::ptr::addr_of_mut!(v) as *mut u8,
-            mem::size_of_val(&v) as c::ULONG,
-            c::BCRYPT_USE_SYSTEM_PREFERRED_RNG,
-        )
-    };
-    if c::nt_success(ret) { v } else { fallback_rng() }
+    let ret = unsafe { c::ProcessPrng(ptr::addr_of_mut!(v).cast::<u8>(), mem::size_of_val(&v)) };
+    // ProcessPrng is documented as always returning `TRUE`.
+    // https://learn.microsoft.com/en-us/windows/win32/seccng/processprng#return-value
+    debug_assert_eq!(ret, c::TRUE);
+    v
 }
 
-/// Generate random numbers using the fallback RNG function (RtlGenRandom)
-///
-/// This is necessary because of a failure to load the SysWOW64 variant of the
-/// bcryptprimitives.dll library from code that lives in bcrypt.dll
-/// See <https://bugzilla.mozilla.org/show_bug.cgi?id=1788004#c9>
-#[cfg(not(target_vendor = "uwp"))]
-#[inline(never)]
-fn fallback_rng() -> (u64, u64) {
+#[cfg(target_vendor = "win7")]
+pub fn hashmap_random_keys() -> (u64, u64) {
     use crate::ffi::c_void;
     use crate::io;
 
     let mut v = (0, 0);
     let ret = unsafe {
-        c::RtlGenRandom(core::ptr::addr_of_mut!(v) as *mut c_void, mem::size_of_val(&v) as c::ULONG)
+        c::RtlGenRandom(ptr::addr_of_mut!(v).cast::<c_void>(), mem::size_of_val(&v) as c::ULONG)
     };
 
-    if ret != 0 { v } else { panic!("fallback RNG broken: {}", io::Error::last_os_error()) }
-}
-
-/// We can't use RtlGenRandom with UWP, so there is no fallback
-#[cfg(target_vendor = "uwp")]
-#[inline(never)]
-fn fallback_rng() -> (u64, u64) {
-    panic!("fallback RNG broken: RtlGenRandom() not supported on UWP");
+    if ret != 0 { v } else { panic!("RNG broken: {}", io::Error::last_os_error()) }
 }
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index bddc30b8379b2..fdd7fc5fad4e8 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -427,6 +427,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 this.gen_random(ptr, len.into())?;
                 this.write_scalar(Scalar::from_bool(true), dest)?;
             }
+            "ProcessPrng" => {
+                let [ptr, len] =
+                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let ptr = this.read_pointer(ptr)?;
+                let len = this.read_target_usize(len)?;
+                this.gen_random(ptr, len.into())?;
+                this.write_scalar(Scalar::from_i32(1), dest)?;
+            }
             "BCryptGenRandom" => {
                 let [algorithm, ptr, len, flags] =
                     this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;