On Mon, 26 Sep 2022, Alvin Wong wrote:

On 22/9/2022 0:01, Martin Storsjö wrote:
+static void __cdecl __attribute__((__constructor__)) init(void)
+{
+  HCRYPTPROV crypt = 0;
+  if (__stack_chk_guard != 0)
+    return;
+
+  if (CryptAcquireContext(&crypt, NULL, NULL, PROV_RSA_FULL, 
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+    if (CryptGenRandom(crypt, sizeof(__stack_chk_guard), (BYTE*) &__stack_chk_guard) 
&& __stack_chk_guard != 0) {
+      CryptReleaseContext(crypt, 0);
+      return;
+    }
+    CryptReleaseContext(crypt, 0);
+  }

I guess this is just following whatever libssp does, but I did just stumble across some talks about RNG functions elsewhere, mainly an old comment on Mozilla's bugzilla <https://bugzilla.mozilla.org/show_bug.cgi?id=504270#c5> recommending `RtlGenRandom` over `CryptGenRandom` and a discussion in rust-random <https://github.com/rust-random/getrandom/issues/65> advocating for `BCryptGenRandom` over `RtlGenRandom` and its references. Firefox, Chrome, Rust and Go all prefer to use `RtlGenRandom` instead of `CryptGenRandom`. The documentation of CryptGenRandom <https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom> says the API is deprecated and may be removed in the future (though I doubt they will really remove it) which may be a good reason to avoid using `CryptGenRandom`.

FWIW, CryptGenRandom is not available in UWP mode at all, which is why libwinstorecompat has got a reimplementation of it. It is reimplemented on top of the Windows.Security.Cryptography.CryptographicBuffer API. I'm CCing Hugo and Steve who have been involved in winstorecompat, in case they have anything to add about why they chose to implement it on top of that instead of on top of BCrypt.

Now whether to use `RtlGenRandom` or `BCryptGenRandom` as the replacement: For UWP, `BCryptGenRandom` is the only choice. For desktop, a comment in a BoringSSL issue <https://bugs.chromium.org/p/boringssl/issues/detail?id=307#c9> claims that they both use "the same internal RNG infrastructure".

It seems we'd be better off replacing this use of `CryptGenRandom` with `RtlGenRandom` for desktop and `BCryptGenRandom` for UWP. Do you think this make sense?

Hmm, this does sound reasonable - however it doesn't seem entirely easy.

Using separate codepaths for UWP is done by linking the libwinstorecompat static library (or libwindowsappcompat) before linking kernel32 or similar, so that unavailable functions are resolved from there instead of being imported.

Now for RtlGenRandom, this isn't available as one single function that can be linked from somewhere, but you're expected to use LoadLibrary and GetProcAddress to fetch it. (We could of course add it to our import libraries, but the docs for it says we shouldn't do it that way.) And we can't really replace the calls to LoadLibrary/GetProcAddress specifically for this case only.

We could use rand_s, which is a simple single function, and is kinda documented to be implemented on top of RtlGenRandom. That single function would be simple to handle in winstorecompat, but as far as I know, we wouldn't even need to, as it's part of the public bits of the CRT (which we should be free to use).

// Martin

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to