]> git.proxmox.com Git - rustc.git/blame - vendor/getrandom/src/stdweb.rs
Merge tag 'debian/1.52.1+dfsg1-1_exp2' into proxmox/buster
[rustc.git] / vendor / getrandom / src / stdweb.rs
CommitLineData
f20569fa
XL
1// Copyright 2018 Developers of the Rand project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8use crate::Error;
9
10extern crate std;
11use std::thread_local;
12
13use stdweb::js;
14
15#[derive(Clone, Copy, PartialEq)]
16enum RngSource {
17 Browser,
18 Node,
19}
20
21thread_local!(
22 static RNG_SOURCE: Result<RngSource, Error> = getrandom_init();
23);
24
25pub(crate) fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
26 RNG_SOURCE.with(|&source| getrandom_fill(source?, dest))
27}
28
29fn getrandom_init() -> Result<RngSource, Error> {
30 if js! { return typeof self === "object"; } == true {
31 // We are in a Browser or WebWorker
32 let supported = js! { return typeof self.crypto === "object"; };
33 if supported == true {
34 Ok(RngSource::Browser)
35 } else {
36 Err(Error::WEB_CRYPTO)
37 }
38 } else {
39 // We are in Node.js
40 let supported = js! {
41 try {
42 require("crypto");
43 return true;
44 } catch(err) {
45 return false;
46 }
47 };
48 if supported == true {
49 Ok(RngSource::Node)
50 } else {
51 Err(Error::NODE_CRYPTO)
52 }
53 }
54}
55
56fn getrandom_fill(source: RngSource, dest: &mut [u8]) -> Result<(), Error> {
57 for chunk in dest.chunks_mut(65536) {
58 let len = chunk.len() as u32;
59 let ptr = chunk.as_mut_ptr() as i32;
60
61 let success = js! {
62 try {
63 let array = new Uint8Array(@{ len });
64
65 if @{ source == RngSource::Browser } {
66 self.crypto.getRandomValues(array);
67 } else {
68 require("crypto").randomFillSync(array);
69 }
70
71 HEAPU8.set(array, @{ ptr });
72 return true;
73 } catch(err) {
74 return false;
75 }
76 };
77
78 if success != true {
79 return match source {
80 RngSource::Browser => Err(Error::WEB_GET_RANDOM_VALUES),
81 RngSource::Node => Err(Error::NODE_RANDOM_FILL_SYNC),
82 };
83 }
84 }
85 Ok(())
86}