-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[wasm][crypto] RandomNumberGenerator mapped to Web Crypto getRandomValues #42728
[wasm][crypto] RandomNumberGenerator mapped to Web Crypto getRandomValues #42728
Conversation
…lues - Uses Web Crypto API [`getRandomValues`](https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues) if available. - Falls back to `/dev/urandom` as default if the crypto library is missing.
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @jeffhandley |
Doesn't |
Looks like it does: https://github.com/paulshapiro/emscripten/blob/master/src/library_fs.js#L1296 We can close this if we want to continue using the default implementation |
Is this even possible? Is there any wasm host which does not provide a subtle crypto implementation? And if there is, why not force the host to polyfill as in #42731? |
This is just about the best way to call https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues. It's the only API that isn't promised based and we can actually invoke. To be honest, this already works and unless I'm missing something, I would recommend we close the PR. |
Let me rephrase the requirement:
|
emscripten-core/emscripten#12240 landed recently which will expose getentropy as a very thin wrapper over subtle crypto which is what the existing wasm /dev/random uses. The code does fall back to requiring crypto.randomBytes on node and fails if that is not supported. I propose we stick with using /dev/random until we update emscripten then call getentropy from pal_random for wasm. Does this satisfy all the requirements? |
This just works because emscripten falls back to node's crypto.randomBytes for both /dev/random and /dev/urandom any code should handle the node case and not fall back to /dev/urandom |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has several issues, it should be implemented in terms of calling getentropy regardless of where the implementation lives.
…crypto-getRandomValues
- Javascript checks for crypto interface and uses `crypto.getRandomValues` - Add api bridge call when building for emscripten browser. - separate out into browser subdirectory - If we couldn't find a proper implementation, as Math.random() is not suitable we will abort. ``` ABORT: no cryptographic support found getRandomValues. Consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } }; ```
src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h
Outdated
Show resolved
Hide resolved
src/libraries/Native/Unix/System.Native/browser/pal_entropy_bridge.js
Outdated
Show resolved
Hide resolved
return 0; | ||
} else { | ||
// we couldn't find a proper implementation, as Math.random() is not suitable | ||
abort("no cryptographic support found for getRandomValues. Consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think we should be suggesting an unsecure polyfill in the error message.
I think we should leave it for the documentation to discuss the polyfill workarounds. The recommended workaround should be something that tries to be secure as much as possible, like the MSR library discussed in the other PR. If somebody wants to use insecure polyfill, I would leave it up to them to figure out how to do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to let normal managed exception to handle error.
WASM-ERR:
WASM-ERR: Unhandled Exception:
WASM-ERR: System.Security.Cryptography.CryptographicException: Error occurred during a cryptographic operation.
WASM-ERR: at Interop.GetCryptographicallySecureRandomBytes(Byte* buffer, Int32 length)
WASM-ERR: at System.Security.Cryptography.RandomNumberGeneratorImplementation.GetBytes(Byte* pbBuffer, Int32 count)
WASM-ERR: at System.Security.Cryptography.RandomNumberGeneratorImplementation.GetBytes(Span`1 data)
WASM-ERR: at System.Security.Cryptography.RandomNumberGeneratorImplementation.GetNonZeroBytes(Span`1 data)
WASM-ERR: at System.Security.Cryptography.RandomNumberGeneratorImplementation.GetNonZeroBytes(Byte[] data)
Does this work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo the things Jan mentioned. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address the open reviews and this looks good.
Co-authored-by: Ryan Lucia <ryan@luciaonline.net>
…crypto-getRandomValues
…allows the managed code exception flow to continue as normal.
Uses Web Crypto API
getRandomValues
if available.Add javascript bridge implementation library to Native source tree. …
crypto.getRandomValues
closes #42727
Part of #40074 and #40074 (comment)