Hi,
On 2022-09-26 23:33, Martin Storsjö wrote:
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.
IIRC at the time BCrypt was probably not allowed in UWP (Win8+). Now
BCrypt would be a better choice.
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?
I would suggest the other way around. Use BCrypt everywhere except for
XP (if it's that the issue for having 2 different code path). If anyone
builds for Vista and above the code would only use BCrypt. And if one
day XP is dropped, it's easier to spot this code running only on XP.
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