[PATCH] D77553: [Support,Windows] Tolerate failure of CryptGenRandom

Simon Tatham via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 7 01:36:36 PDT 2020


This revision was automatically updated to reflect the committed changes.
Closed by commit rGaab9e9de4d99: [Support,Windows] Tolerate failure of CryptGenRandom (authored by simon_tatham).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77553/new/

https://reviews.llvm.org/D77553

Files:
  llvm/lib/Support/Windows/Process.inc


Index: llvm/lib/Support/Windows/Process.inc
===================================================================
--- llvm/lib/Support/Windows/Process.inc
+++ llvm/lib/Support/Windows/Process.inc
@@ -439,18 +439,38 @@
   return 0;
 }
 
+static unsigned GetRandomNumberSeed() {
+  // Generate a random number seed from the millisecond-resolution Windows
+  // system clock and the current process id.
+  FILETIME Time;
+  GetSystemTimeAsFileTime(&Time);
+  DWORD Pid = GetCurrentProcessId();
+  return hash_combine(Time.dwHighDateTime, Time.dwLowDateTime, Pid);
+}
+
+static unsigned GetPseudoRandomNumber() {
+  // Arrange to call srand once when this function is first used, and
+  // otherwise (if GetRandomNumber always succeeds in using
+  // CryptGenRandom) don't bother at all.
+  static int x = (static_cast<void>(::srand(GetRandomNumberSeed())), 0);
+  (void)x;
+  return ::rand();
+}
+
 unsigned Process::GetRandomNumber() {
+  // Try to use CryptGenRandom.
   HCRYPTPROV HCPC;
-  if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
-                              CRYPT_VERIFYCONTEXT))
-    ReportLastErrorFatal("Could not acquire a cryptographic context");
-
-  ScopedCryptContext CryptoProvider(HCPC);
-  unsigned Ret;
-  if (!::CryptGenRandom(CryptoProvider, sizeof(Ret),
-                        reinterpret_cast<BYTE *>(&Ret)))
-    ReportLastErrorFatal("Could not generate a random number");
-  return Ret;
+  if (::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
+                             CRYPT_VERIFYCONTEXT)) {
+    ScopedCryptContext CryptoProvider(HCPC);
+    unsigned Ret;
+    if (::CryptGenRandom(CryptoProvider, sizeof(Ret),
+                         reinterpret_cast<BYTE *>(&Ret)))
+      return Ret;
+  }
+
+  // If that fails, fall back to pseudo-random numbers.
+  return GetPseudoRandomNumber();
 }
 
 typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77553.255613.patch
Type: text/x-patch
Size: 1916 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200407/19b32399/attachment.bin>


More information about the llvm-commits mailing list