[
  {
    "path": ".cargo/config.toml",
    "content": "# Allow normal use of \"cargo run\" and \"cargo test\" on these wasm32 platforms.\n[target.wasm32-unknown-unknown]\nrunner = 'wasm-bindgen-test-runner'\n[target.wasm32-wasip1]\nrunner = 'wasmtime'\n[target.wasm32-wasip2]\nrunner = 'wasmtime'\n[target.wasm32-wasip3]\nrunner = 'wasmtime'\n\n# Just run on node by default (that's where emscripten is tested)\n[target.'cfg(target_os = \"emscripten\")']\nrunner = 'node'\n\n[resolver]\nincompatible-rust-versions = \"allow\"\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n- package-ecosystem: cargo\n  directory: \"/\"\n  versioning-strategy: lockfile-only\n  allow:\n    - dependency-type: \"all\"\n  schedule:\n    interval: weekly\n  groups:\n    all-deps:\n      patterns:\n        - \"*\"\n- package-ecosystem: \"github-actions\"\n  directory: \"/\"\n  schedule:\n    interval: weekly\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\n\non:\n  push:\n    branches: master\n  pull_request:\n    branches: master\n  schedule:\n    - cron: \"0 12 * * 1\"\n\npermissions:\n  contents: read\n\nenv:\n  CARGO_INCREMENTAL: 0\n  RUSTFLAGS: \"-Dwarnings\"\n\njobs:\n  macos:\n    name: Apple Other\n    # visionOS requires Xcode 15.2+, which is only available on the arm64 runners.\n    runs-on: macos-14\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly\n        with:\n          targets: aarch64-apple-darwin, aarch64-apple-ios\n          components: rust-src\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo test --no-run --target=aarch64-apple-darwin --features=std\n      - run: cargo test --no-run --target=aarch64-apple-ios --features=std\n      - run: cargo test --no-run --target=aarch64-apple-tvos -Zbuild-std --features=std\n      - run: cargo test --no-run --target=aarch64-apple-watchos -Zbuild-std --features=std\n      # visionOS requires Xcode 15.2+, GitHub Actions defaults to an older version.\n      - run: sudo xcode-select -switch /Applications/Xcode_15.2.app\n      # std is broken on visionOS right now\n      #- run: cargo test --no-run --target=aarch64-apple-visionos -Zbuild-std --features=std\n\n  cross:\n    name: Cross\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [\n          # This target is currently broken:\n          # https://github.com/rust-random/getrandom/actions/runs/12949235456/job/36119544880\n          # sparcv9-sun-solaris,\n          x86_64-unknown-illumos,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - name: Install precompiled cross\n        run: |\n          VERSION=v0.2.5\n          URL=https://github.com/cross-rs/cross/releases/download/${VERSION}/cross-x86_64-unknown-linux-gnu.tar.gz\n          wget -O - $URL | tar -xz -C ~/.cargo/bin\n          cross --version\n      - name: Build Tests\n        run: cross test --no-run --target=${{ matrix.target }} --features=std\n\n  tier2:\n    name: Tier 2\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [\n          aarch64-linux-android,\n          x86_64-unknown-fuchsia,\n          x86_64-unknown-redox,\n          x86_64-fortanix-unknown-sgx,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          targets: ${{ matrix.target }}\n      - uses: Swatinem/rust-cache@v2\n      - name: Build\n        run: cargo build --target=${{ matrix.target }} --features=std\n\n  tier3:\n    name: Tier 3\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [\n          aarch64-kmc-solid_asp3,\n          aarch64-unknown-nto-qnx710,\n          armv6k-nintendo-3ds,\n          armv7-sony-vita-newlibeabihf,\n          i686-unknown-hurd-gnu,\n          riscv32imc-esp-espidf,\n          x86_64-unknown-hermit,\n          x86_64-wrs-vxworks,\n          x86_64-unknown-dragonfly,\n          x86_64-unknown-haiku,\n          x86_64-unknown-linux-none,\n          x86_64-pc-cygwin,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly # Required to build libcore\n        with:\n          components: rust-src\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo build -Z build-std=core --target=${{ matrix.target }}\n\n  # Ubuntu does not support running x32 binaries:\n  # https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1994516/comments/21\n  linux-x32:\n    name: Linux x32\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [x86_64-unknown-linux-gnux32]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          targets: ${{ matrix.target }}\n      - name: Install libc and libgcc\n        run: |\n          sudo apt-get update\n          sudo apt-get install --no-install-recommends libc6-dev-x32 libx32gcc-11-dev\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo build --target=${{ matrix.target }} --features=std\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_getrandom\"\n        run: cargo build --target=${{ matrix.target }} --features=std\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_test_linux_fallback\n        run: cargo build --features=std\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rdrand\"\n        run: cargo build --features=std\n\n  linux-raw:\n    name: Build Raw Linux\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [\n          arm-unknown-linux-gnueabihf,\n          aarch64-unknown-linux-gnu,\n          loongarch64-unknown-linux-gnu,\n          riscv32gc-unknown-linux-gnu,\n          riscv64gc-unknown-linux-gnu,\n          s390x-unknown-linux-gnu,\n          i686-unknown-linux-gnu,\n          x86_64-unknown-linux-gnu,\n          x86_64-unknown-linux-gnux32,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: nightly-2025-09-28\n          components: rust-src\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_raw\"\n        run: cargo build -Zbuild-std=core --target=${{ matrix.target }}\n\n  web:\n    name: ${{ matrix.target.description }} ${{ matrix.feature.description }} ${{ matrix.atomic.description }}\n    runs-on: ubuntu-24.04\n    strategy:\n      fail-fast: false\n      matrix:\n        target: [\n          { description: Web, target: wasm32-unknown-unknown },\n          { description: WasmV1, target: wasm32v1-none },\n        ]\n        feature: [\n          { description: no_std, feature: \"--features wasm_js\", build-std: \"core,alloc\", std: false },\n          { feature: \"--features wasm_js,std\", build-std: \"panic_abort,std\", std: true },\n        ]\n        atomic: [\n          { flags: \"\" },\n          { description: with Atomics, flags: \"-Ctarget-feature=+atomics,bulk-memory\" },\n        ]\n        exclude:\n          - target: { target: wasm32v1-none }\n            feature: { std: true }\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          targets: ${{ matrix.target.target }}\n          toolchain: nightly-2025-09-28\n          components: rust-src\n      - uses: Swatinem/rust-cache@v2\n      - name: Build\n        run: cargo build --target ${{ matrix.target.target }} ${{ matrix.feature.feature }} -Zbuild-std=${{ matrix.feature.build-std }}\n\n  efi-rng:\n    name: UEFI RNG Protocol\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [\n          aarch64-unknown-uefi,\n          x86_64-unknown-uefi,\n          i686-unknown-uefi,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly # Required to build libstd\n        with:\n          components: rust-src\n      - uses: Swatinem/rust-cache@v2\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"efi_rng\"\n        run: cargo build -Z build-std=std --target=${{ matrix.target }} --features std\n\n  rdrand-uefi:\n    name: RDRAND UEFI\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [\n          x86_64-unknown-uefi,\n          i686-unknown-uefi,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly # Required to build libcore\n        with:\n          components: rust-src\n      - uses: Swatinem/rust-cache@v2\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rdrand\"\n        run: cargo build -Z build-std=core --target=${{ matrix.target }}\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rdrand\"\n        run: cargo build -Z build-std=std --target=${{ matrix.target }} --features std\n\n  rndr:\n    name: RNDR\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          targets: aarch64-unknown-linux-gnu, aarch64-apple-darwin\n      - uses: Swatinem/rust-cache@v2\n      - name: RNDR enabled at compile time (Linux)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rndr\" -C target-feature=+rand\n        run: cargo build --target=aarch64-unknown-linux-gnu\n      - name: Runtime RNDR detection without std (Linux)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rndr\"\n        run: cargo build --target=aarch64-unknown-linux-gnu\n      - name: Runtime RNDR detection with std (macOS)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rndr\"\n        run: cargo build --target=aarch64-unknown-linux-gnu --features std\n\n  no-atomics:\n    name: No Atomics\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          targets: riscv32i-unknown-none-elf\n      - uses: Swatinem/rust-cache@v2\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"unsupported\"\n        run: cargo build --target riscv32i-unknown-none-elf\n\n  unsupported:\n    name: Runtime error\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          targets: wasm32-unknown-unknown\n      - uses: Swatinem/rust-cache@v2\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"unsupported\"\n        run: cargo build --target wasm32-unknown-unknown\n"
  },
  {
    "path": ".github/workflows/nopanic.yaml",
    "content": "# This CI config checks that  getrandom's backend implementation\n# do not contain potential panics.\n#\n# It is unclear how to implement a no-panic check for esp_idf, fuchsia,\n# vxworks, hermit, and solid backends, so we do not check them here,\n# but they still should be panic-free. We do not check wasm_js backend\n# since glue code generated by wasm-bindgen contains potential panics,\n# so resulting WASM files inevitably contain potential panics for any\n# code which non-trivially interacts with the JS enviroment.\nname: No panic\n\non:\n  push:\n    branches: master\n  pull_request:\n    branches: master\n\npermissions:\n  contents: read\n\ndefaults:\n  run:\n    working-directory: nopanic_check\n\nenv:\n  RUSTFLAGS: \"-Dwarnings\"\n\njobs:\n  linux:\n    name: Linux\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          targets: wasm32-wasip1, wasm32-wasip2\n      - uses: Swatinem/rust-cache@v2\n      \n      - name: Build (linux_android_with_fallback.rs)\n        run: cargo build --release\n      - name: Check (linux_android_with_fallback.rs)\n        run: (exit $( grep -c panic target/release/libgetrandom_wrapper.so ))\n\n      - name: Build (getrandom.rs)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_getrandom\"\n        run: cargo build --release\n      - name: Check (getrandom.rs)\n        run: (exit $( grep -c panic target/release/libgetrandom_wrapper.so ))\n\n      - name: Build (linux_raw.rs)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_raw\"\n        run: cargo build --release\n      - name: Check (linux_raw.rs)\n        run: (exit $( grep -c panic target/release/libgetrandom_wrapper.so ))\n\n      - name: Build (rdrand.rs)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rdrand\"\n        run: cargo build --release\n      - name: Check (rdrand.rs)\n        run: (exit $( grep -c panic target/release/libgetrandom_wrapper.so ))\n\n      - name: Build (custom.rs)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"custom\"\n        run: cargo build --release\n      - name: Check (custom.rs)\n        run: (exit $( grep -c panic target/release/libgetrandom_wrapper.so ))\n\n      - name: Build (wasi.rs, preview 1)\n        run: cargo build --release --target wasm32-wasip1\n      - name: Check (wasi.rs, preview 1)\n        run: (exit $( grep -c panic target/wasm32-wasip1/release/getrandom_wrapper.wasm ))\n\n      - name: Build (wasi.rs, preview 2)\n        run: cargo build --release --target wasm32-wasip2\n      - name: Check (wasi.rs, preview 2)\n        run: (exit $( grep -c panic target/wasm32-wasip2/release/getrandom_wrapper.wasm ))\n\n  cross:\n    name: Cross\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          components: rust-src\n          targets: aarch64-unknown-linux-gnu,x86_64-unknown-netbsd,x86_64-unknown-freebsd,x86_64-pc-solaris\n      - uses: Swatinem/rust-cache@v2\n      # TODO: use pre-compiled cross after a new (post-0.2.5) release\n      - name: Install cross\n        env:\n          # Allow compiler warnings during cross installation\n          RUSTFLAGS:\n        run: cargo install cross --force --git https://github.com/cross-rs/cross\n\n      - name: Build (rndr.rs)\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rndr\"\n        run: cross build --release --target=aarch64-unknown-linux-gnu\n      - name: Check (rndr.rs)\n        run: (exit $( grep -c panic target/aarch64-unknown-linux-gnu/release/libgetrandom_wrapper.so ))\n\n      - name: Build (netbsd.rs)\n        run: cross build --release --target=x86_64-unknown-netbsd\n      - name: Check (netbsd.rs)\n        run: (exit $( grep -c panic target/x86_64-unknown-netbsd/release/libgetrandom_wrapper.so ))\n\n      - name: Build (solaris.rs)\n        run: cross build --release --target=x86_64-pc-solaris\n      - name: Check (solaris.rs)\n        run: (exit $( grep -c panic target/x86_64-pc-solaris/release/libgetrandom_wrapper.so ))\n\n  macos:\n    name: macOS\n    runs-on: macos-14\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: stable\n          targets: aarch64-apple-ios\n      - uses: Swatinem/rust-cache@v2\n      \n      # We do not need the grep check since linker fails\n      # if `panic_nonexistent` can not be eliminated\n      - name: Build (getentropy.rs)\n        run: cargo build --release --target=aarch64-apple-darwin\n      - name: Build (apple-other.rs)\n        run: cargo build --release --target=aarch64-apple-ios\n\n  windows:\n    name: Windows\n    runs-on: windows-2022\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: nightly-2025-09-28\n          components: rust-src\n      - run: cargo build --release\n      - run: cargo build --release --target=x86_64-win7-windows-msvc -Zbuild-std=\"std,panic_abort\"\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Publish to crates.io\non:\n  push:\n    tags: ['v*']  # Triggers when pushing tags starting with 'v'\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    environment: release  # Optional: for enhanced security\n    permissions:\n      id-token: write     # Required for OIDC token exchange\n    steps:\n    - uses: actions/checkout@v6\n    - uses: rust-lang/crates-io-auth-action@v1\n      id: auth\n    - run: cargo publish\n      env:\n        CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "name: Test\n\non:\n  push:\n    branches: master\n  pull_request:\n    branches: master\n  schedule:\n    - cron: \"0 12 * * 1\"\n\npermissions:\n  contents: read\n\nenv:\n  CARGO_INCREMENTAL: 0\n  RUST_BACKTRACE: 1\n  RUSTFLAGS: \"-Dwarnings\"\n\njobs:\n  tier1:\n    name: Tier 1\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-24.04, windows-2022]\n        toolchain: [nightly, beta, stable, \"1.85\"]\n        # Only Test macOS on stable to reduce macOS CI jobs\n        include:\n          # aarch64-apple-darwin.\n          - os: macos-14\n            toolchain: stable\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ matrix.toolchain }}\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo test\n      # Make sure enabling the std feature doesn't break anything\n      - run: |\n          cargo test --features=std\n          cargo test --features=sys_rng\n          cargo test --features=std,sys_rng\n      - if: ${{ matrix.toolchain == 'nightly' }}\n        run: cargo test --benches\n\n  linux:\n    name: Linux\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [x86_64-unknown-linux-musl, i686-unknown-linux-musl]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          targets: ${{ matrix.target }}\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo test --target=${{ matrix.target }} --features=std,sys_rng\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_getrandom\"\n          RUSTDOCFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_getrandom\"\n        run: cargo test --target=${{ matrix.target }} --features=std,sys_rng\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_raw\"\n          RUSTDOCFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_raw\"\n        run: cargo test --target=${{ matrix.target }} --features=std,sys_rng\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_test_linux_fallback\n          RUSTDOCFLAGS: -Dwarnings --cfg getrandom_test_linux_fallback\n        run: cargo test --features=std,sys_rng\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_test_linux_without_fallback\n          RUSTDOCFLAGS: -Dwarnings --cfg getrandom_test_linux_without_fallback\n        run: cargo test --features=std,sys_rng\n      - env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rdrand\"\n          RUSTDOCFLAGS: -Dwarnings --cfg getrandom_backend=\"rdrand\"\n        run: cargo test --features=std,sys_rng\n\n  custom_impl:\n    name: Custom and External Implementations\n    runs-on: ubuntu-24.04\n    defaults:\n      run:\n        working-directory: custom_impl_test\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: nightly\n      - uses: Swatinem/rust-cache@v2\n      - name: Test getrandom_backend=\"custom\"\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"custom\"\n        run: cargo test\n      - name: Test getrandom_backend=\"extern_impl\"\n        env:\n          RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"extern_impl\"\n        run: cargo test\n\n  ios:\n    name: iOS Simulator\n    runs-on: macos-14\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: 1.88.0\n          targets: aarch64-apple-ios-sim\n      - name: Install precompiled cargo-dinghy\n        run: |\n          VERSION=0.8.1\n          URL=\"https://github.com/sonos/dinghy/releases/download/${VERSION}/cargo-dinghy-macos-${VERSION}.tgz\"\n          wget -O - $URL | tar -xz --strip-components=1 -C ~/.cargo/bin\n      - name: Check cargo-dinghy version.\n        run: cargo dinghy --version\n      - name: Setup Simulator\n        # Use the first installed iOS runtime and the first (i.e. oldest) supported iPhone device.\n        run: |\n          RUNTIME=$(xcrun simctl list runtimes --json | jq '.runtimes | map(select(.name | contains(\"iOS\"))) | .[0]')\n          RUNTIME_ID=$(echo $RUNTIME | jq -r '.identifier')\n          echo \"Using runtime:\" $RUNTIME_ID\n          DEVICE_ID=$(echo $RUNTIME | jq -r '.supportedDeviceTypes | map(select(.productFamily == \"iPhone\")) | .[0].identifier')\n          echo \"Using device:\" $DEVICE_ID\n          SIM_ID=$(xcrun simctl create Test-iPhone $DEVICE_ID $RUNTIME_ID)\n          echo \"Created simulator:\" $SIM_ID\n          xcrun simctl boot $SIM_ID\n          echo \"device=$SIM_ID\" >> $GITHUB_ENV\n      - uses: Swatinem/rust-cache@v2\n      - name: Run tests\n        run: cargo dinghy -p auto-ios-aarch64-sim -d ${{ env.device }} test\n\n  windows:\n    name: Windows\n    runs-on: windows-2022\n    strategy:\n      matrix:\n        toolchain: [\n          stable-x86_64-gnu,\n          stable-i686-gnu,\n          stable-i686-msvc,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ matrix.toolchain }}\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo test --features=std,sys_rng\n\n  windows7:\n    name: Windows 7 (on Windows 10)\n    runs-on: windows-2022\n    steps:\n      - uses: actions/checkout@v6\n      # Win7 targets are Tier3, so pin a nightly where libstd builds.\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: nightly-2025-09-28\n          components: rust-src\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo test --target=x86_64-win7-windows-msvc -Z build-std --features=std,sys_rng\n      - run: cargo test --target=i686-win7-windows-msvc -Z build-std --features=std,sys_rng\n\n  sanitizer-linux:\n    name: Sanitizer Linux\n    runs-on: ${{ matrix.runner }}\n    strategy:\n      matrix:\n        include:\n          # MemorySanitizer won't run in QEMU so we can't run it in cross:\n          # https://github.com/llvm/llvm-project/issues/65144\n          - arch: aarch64\n            runner: ubuntu-24.04-arm\n          - arch: x86_64\n            runner: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: nightly-2025-09-28\n          components: rust-src\n      # Use --all-targets to skip doctests, which don't work with the -Zsanitizer=memory flag.\n      # See: https://github.com/rust-lang/rust/issues/134172\n      - name: default configuration\n        env:\n          RUSTFLAGS: -Dwarnings -Zsanitizer=memory\n        run: cargo test --all-targets -Zbuild-std --target=${{ matrix.arch }}-unknown-linux-gnu\n      - name: --cfg getrandom_backend=\"linux_getrandom\"\n        env:\n          RUSTFLAGS: --cfg getrandom_backend=\"linux_getrandom\" -Dwarnings -Zsanitizer=memory\n        run: cargo test --all-targets -Zbuild-std --target=${{ matrix.arch }}-unknown-linux-gnu\n      - name: --cfg getrandom_backend=\"linux_raw\"\n        env:\n          RUSTFLAGS: --cfg getrandom_backend=\"linux_raw\" -Dwarnings -Zsanitizer=memory\n        run: cargo test --all-targets -Zbuild-std --target=${{ matrix.arch }}-unknown-linux-gnu\n      - name: --cfg getrandom_backend=\"linux_fallback\"\n        env:\n          RUSTFLAGS: --cfg getrandom_backend=\"linux_fallback\" -Dwarnings -Zsanitizer=memory\n        run: cargo test --all-targets -Zbuild-std --target=${{ matrix.arch }}-unknown-linux-gnu\n      - if: ${{ matrix.arch == 'x86_64' }}\n        name: --cfg getrandom_backend=\"rdrand\"\n        env:\n          RUSTFLAGS: --cfg getrandom_backend=\"rdrand\" -Dwarnings -Zsanitizer=memory\n        run: cargo test --all-targets -Zbuild-std --target=${{ matrix.arch }}-unknown-linux-gnu\n      - name: --cfg getrandom_test_linux_fallback\n        env:\n          RUSTFLAGS: --cfg getrandom_test_linux_fallback -Dwarnings -Zsanitizer=memory\n        run: cargo test --all-targets -Zbuild-std --target=${{ matrix.arch }}-unknown-linux-gnu\n      - name: --cfg getrandom_test_linux_without_fallback\n        env:\n          RUSTFLAGS: --cfg getrandom_test_linux_without_fallback -Dwarnings -Zsanitizer=memory\n        run: cargo test --all-targets -Zbuild-std --target=${{ matrix.arch }}-unknown-linux-gnu\n\n  cross:\n    name: Cross\n    runs-on: ubuntu-24.04\n    strategy:\n      matrix:\n        target: [\n          aarch64-unknown-linux-gnu,\n          # TODO: add Android tests back when the cross cuts a new release.\n          # See: https://github.com/cross-rs/cross/issues/1222\n          # aarch64-linux-android,\n          # This target is currently broken:\n          # https://github.com/rust-random/getrandom/actions/runs/15109500597/job/42465556156\n          #powerpc-unknown-linux-gnu,\n          riscv64gc-unknown-linux-gnu,\n          # This target is currently broken:\n          # https://github.com/rust-random/getrandom/actions/runs/12949235459/job/36119546920\n          #wasm32-unknown-emscripten,\n        ]\n    steps:\n      - uses: actions/checkout@v6\n      - name: Install precompiled cross\n        run: |\n          VERSION=v0.2.5\n          URL=https://github.com/cross-rs/cross/releases/download/${VERSION}/cross-x86_64-unknown-linux-gnu.tar.gz\n          wget -O - $URL | tar -xz -C ~/.cargo/bin\n          cross --version\n      - name: Test\n        run: cross test --no-fail-fast --target=${{ matrix.target }} --features=std,sys_rng\n\n  freebsd:\n    name: FreeBSD VM\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - name: Test in FreeBSD\n        uses: vmactions/freebsd-vm@v1\n        with:\n          envs: 'RUSTFLAGS'\n          usesh: true\n          prepare: |\n            pkg install -y rust\n          run: cargo test\n\n  openbsd:\n    name: OpenBSD VM\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - name: Test in OpenBSD\n        uses: vmactions/openbsd-vm@v1\n        with:\n          envs: 'RUSTFLAGS'\n          usesh: true\n          prepare: |\n            pkg_add rust\n          run: cargo test\n\n  netbsd:\n    name: NetBSD VM\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - name: Test in NetBSD\n        uses: vmactions/netbsd-vm@v1\n        with:\n          envs: 'RUSTFLAGS'\n          usesh: true\n          prepare: |\n            /usr/sbin/pkg_add rust\n          run: |\n            cargo test\n            RUSTFLAGS=\"--cfg getrandom_test_netbsd_fallback -D warnings\" cargo test\n\n  web:\n    name: ${{ matrix.rust.description }}\n    runs-on: ubuntu-24.04\n    strategy:\n      fail-fast: false\n      matrix:\n        rust:\n          - {\n              description: Web,\n              version: stable,\n              flags: '-Dwarnings',\n              args: '--features=std,sys_rng,wasm_js',\n            }\n          - {\n              description: Web with Atomics,\n              version: nightly,\n              components: rust-src,\n              flags: '-Dwarnings -Ctarget-feature=+atomics,+bulk-memory',\n              args: '--features=std,sys_rng,wasm_js -Zbuild-std=panic_abort,std',\n            }\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{ matrix.rust.version }}\n          components: ${{ matrix.rust.components }}\n      - name: Install precompiled wasm-pack\n        shell: bash\n        run: |\n          VERSION=v0.13.1\n          URL=https://github.com/rustwasm/wasm-pack/releases/download/${VERSION}/wasm-pack-${VERSION}-x86_64-unknown-linux-musl.tar.gz\n          wget -O - $URL | tar -xz --strip-components=1 -C ~/.cargo/bin\n          wasm-pack --version\n      - uses: Swatinem/rust-cache@v2\n      - name: Test (Node)\n        env:\n          RUSTFLAGS: ${{ matrix.rust.flags }}\n          RUSTDOCFLAGS: ${{ matrix.rust.flags }}\n        run: wasm-pack test --node -- ${{ matrix.rust.args }}\n      - name: Test (Firefox)\n        env:\n          WASM_BINDGEN_USE_BROWSER: 1\n          RUSTFLAGS: ${{ matrix.rust.flags }}\n          RUSTDOCFLAGS: ${{ matrix.rust.flags }}\n        run: wasm-pack test --headless --firefox -- ${{ matrix.rust.args }}\n      - name: Test (Chrome)\n        env:\n          WASM_BINDGEN_USE_BROWSER: 1\n          RUSTFLAGS: ${{ matrix.rust.flags }}\n          RUSTDOCFLAGS: ${{ matrix.rust.flags }}\n        run: wasm-pack test --headless --chrome -- ${{ matrix.rust.args }}\n      - name: Test (dedicated worker)\n        env:\n          WASM_BINDGEN_USE_DEDICATED_WORKER: 1\n          RUSTFLAGS: ${{ matrix.rust.flags }}\n          RUSTDOCFLAGS: ${{ matrix.rust.flags }}\n        run: wasm-pack test --headless --firefox -- ${{ matrix.rust.args }}\n      - name: Test (shared worker)\n        env:\n          WASM_BINDGEN_USE_SHARED_WORKER: 1\n          RUSTFLAGS: ${{ matrix.rust.flags }}\n          RUSTDOCFLAGS: ${{ matrix.rust.flags }}\n        run: wasm-pack test --headless --firefox -- ${{ matrix.rust.args }}\n      - name: Test (service worker)\n        env:\n          WASM_BINDGEN_USE_SERVICE_WORKER: 1\n          RUSTFLAGS: ${{ matrix.rust.flags }}\n          RUSTDOCFLAGS: ${{ matrix.rust.flags }}\n        # Firefox doesn't support module service workers and therefor can't import scripts\n        run: wasm-pack test --headless --chrome -- ${{ matrix.rust.args }}\n\n  wasi_p1:\n    name: WASIp1\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: 1.85\n          targets: wasm32-wasip1\n      - name: Install Wasmtime\n        run: |\n          VERSION=v40.0.0\n          URL=https://github.com/bytecodealliance/wasmtime/releases/download/${VERSION}/wasmtime-${VERSION}-x86_64-linux.tar.xz\n          wget -O - $URL | tar -xJ --strip-components=1 -C ~/.cargo/bin\n          wasmtime --version\n      - uses: Swatinem/rust-cache@v2\n      - run: cargo test --target wasm32-wasip1\n\n  wasi_p2:\n    name: WASIp2\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: 1.85\n          targets: wasm32-wasip2\n      - name: Install Wasmtime\n        run: |\n          VERSION=v40.0.0\n          URL=https://github.com/bytecodealliance/wasmtime/releases/download/${VERSION}/wasmtime-${VERSION}-x86_64-linux.tar.xz\n          wget -O - $URL | tar -xJ --strip-components=1 -C ~/.cargo/bin\n          wasmtime --version\n      - uses: Swatinem/rust-cache@v2\n      # TODO(MSRV-1.87): Remove this step.\n      - name: Generate MSRV-compatible Cargo.lock\n        env:\n          CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS: \"fallback\"\n        run: cargo update -p wasip2\n      - run: cargo test --target wasm32-wasip2\n\n  # TODO: enable after pre-built std will be provided by Rust \n  # wasi_p3:\n  #   name: WASIp3\n  #   runs-on: ubuntu-24.04\n  #   steps:\n  #     - uses: actions/checkout@v6\n  #     - uses: dtolnay/rust-toolchain@master\n  #       with:\n  #         toolchain: 1.90\n  #         targets: wasm32-wasip3\n  #     - name: Install Wasmtime\n  #       run: |\n  #         VERSION=v40.0.0\n  #         URL=https://github.com/bytecodealliance/wasmtime/releases/download/${VERSION}/wasmtime-${VERSION}-x86_64-linux.tar.xz\n  #         wget -O - $URL | tar -xJ --strip-components=1 -C ~/.cargo/bin\n  #         wasmtime --version\n  #     - uses: Swatinem/rust-cache@v2\n  #     - run: cargo test --target wasm32-wasip3\n"
  },
  {
    "path": ".github/workflows/workspace.yml",
    "content": "name: Workspace\n\non:\n  push:\n    branches: master\n  pull_request:\n    branches: master\n\npermissions:\n  contents: read\n\njobs:\n  clippy:\n    name: Clippy\n    runs-on: ubuntu-24.04\n    env:\n      RUSTFLAGS: \"-Dwarnings\"\n    steps:\n    - uses: actions/checkout@v6\n    - uses: dtolnay/rust-toolchain@master\n      with:\n        # We need Nightly for -Zbuild-std.\n        # Fixed Nigthly version is used to prevent\n        # CI failures which are not relevant to PR changes\n        # on introduction of new Clippy lints.\n        toolchain: nightly-2025-09-28\n        components: clippy,rust-src\n    - name: std feature\n      run: cargo clippy --features std\n    - name: custom backend\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"custom\"\n      run: cargo clippy -Zbuild-std=core --target riscv32i-unknown-none-elf\n    - name: iOS (apple-other.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-apple-ios\n    - name: ESP-IDF (espidf.rs)\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"esp_idf\"\n      run: cargo clippy -Zbuild-std=core --target riscv32imc-esp-espidf\n    - name: Fuchsia (fuchsia.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-unknown-fuchsia\n    - name: OpenBSD (getentropy.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-unknown-openbsd\n    - name: Hermit (hermit.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-unknown-hermit\n    - name: Web WASM (wasm_js.rs)\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"wasm_js\"\n      run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown --features wasm_js\n    - name: Web WASM with atomics (wasm_js.rs)\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"wasm_js\" -Ctarget-feature=+atomics,+bulk-memory\n      run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown --features wasm_js\n    - name: Linux (getrandom.rs)\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_getrandom\"\n      run: cargo clippy --target x86_64-unknown-linux-gnu\n    - name: Linux (linux_android_with_fallback.rs)\n      run: cargo clippy --target x86_64-unknown-linux-gnu\n    - name: Linux (linux_raw.rs)\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"linux_raw\"\n      run: cargo clippy --target x86_64-unknown-linux-gnu\n    - name: NetBSD (netbsd.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-unknown-netbsd\n    - name: Fortranix SGX (rdrand.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-fortanix-unknown-sgx\n    - name: RNDR (rndr.rs)\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"rndr\"\n      run: cargo clippy -Zbuild-std=core --target aarch64-unknown-linux-gnu\n    - name: EFI RNG (efi_rng.rs)\n      env:\n        RUSTFLAGS: -Dwarnings --cfg getrandom_backend=\"efi_rng\"\n      run: cargo clippy -Zbuild-std=std --target x86_64-unknown-uefi\n    - name: Solaris (solaris.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-pc-solaris\n    - name: SOLID (solid.rs)\n      run: cargo clippy -Zbuild-std=core --target aarch64-kmc-solid_asp3\n    - name: Redox (use_file.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-unknown-redox\n    - name: VxWorks (vxworks.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-wrs-vxworks\n    - name: WASI preview 1 (wasi.rs)\n      run: cargo clippy -Zbuild-std=core --target wasm32-wasip1\n    - name: WASI preview 2 (wasi.rs)\n      run: cargo clippy -Zbuild-std=core,alloc --target wasm32-wasip2\n    - name: Windows 7 (windows7.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-win7-windows-msvc\n    - name: Windows (windows.rs)\n      run: cargo clippy -Zbuild-std=core --target x86_64-pc-windows-msvc\n\n  fmt:\n    name: rustfmt\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          components: rustfmt\n      - uses: Swatinem/rust-cache@v2\n      - name: fmt\n        run: cargo fmt --all -- --check\n\n  doc:\n    name: rustdoc\n    runs-on: ubuntu-24.04\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          # We need Nightly for doc_cfg\n          toolchain: nightly-2026-01-25\n      - uses: Swatinem/rust-cache@v2\n      - name: Generate Docs\n        env:\n          RUSTDOCFLAGS: -Dwarnings --cfg docsrs --cfg getrandom_backend=\"extern_impl\"\n        run: cargo doc --no-deps --features std,sys_rng\n\n  typos:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: crate-ci/typos@v1\n\n  lockfile:\n    name: Check Cargo.lock\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n      - run: cargo check --workspace --locked\n"
  },
  {
    "path": ".gitignore",
    "content": "/target\n**/*.rs.bk\nnopanic_check/Cargo.lock\nnopanic_check/target/\ncustom_impl_test/Cargo.lock\ncustom_impl_test/target/\n"
  },
  {
    "path": ".typos.toml",
    "content": "[files]\nextend-exclude = [\n    \".git/\"\n]\n\n[default.extend-words]\n\"nto\" = \"nto\"\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [Unreleased]\n\n- Restore MSRV to 1.85 for wasm32-wasip3 targets. [#824]\n\n[Unreleased]: https://github.com/rust-random/getrandom/compare/v0.4.2...master\n[#824]: https://github.com/rust-random/getrandom/pull/824\n\n## [0.4.2] - 2026-03-03\n\n### Changed\n- Bump `r-efi` dependency to v6 [#814]\n\n### Fixed\n- Read `errno` only when it is set [#810]\n- Check the return value of `ProcessPrng` on Windows [#811]\n\n[0.4.2]: https://github.com/rust-random/getrandom/compare/v0.4.1...v0.4.2\n[#810]: https://github.com/rust-random/getrandom/pull/810\n[#811]: https://github.com/rust-random/getrandom/pull/811\n[#814]: https://github.com/rust-random/getrandom/pull/814\n\n## [0.4.1] - 2026-02-03\n\n### Fixed\n- Documentation build on docs.rs [#801]\n\n[0.4.1]: https://github.com/rust-random/getrandom/compare/v0.4.0...v0.4.1\n[#801]: https://github.com/rust-random/getrandom/pull/801\n\n## [0.4.0] - 2026-02-02\n\n### Added\n- `RawOsError` type alias [#739]\n- `SysRng` behind new feature `sys_rng` [#751]\n- WASIp3 support [#779]\n- `extern_impl` opt-in backend [#786] [#794]\n- Motor OS support [#797]\n\n### Changed\n- Use Edition 2024 and MSRV 1.85 [#749]\n\n[0.4.0]: https://github.com/rust-random/getrandom/compare/v0.3.4...v0.4.0\n[#739]: https://github.com/rust-random/getrandom/pull/739\n[#749]: https://github.com/rust-random/getrandom/pull/749\n[#751]: https://github.com/rust-random/getrandom/pull/751\n[#779]: https://github.com/rust-random/getrandom/pull/779\n[#786]: https://github.com/rust-random/getrandom/pull/786\n[#794]: https://github.com/rust-random/getrandom/pull/794\n[#797]: https://github.com/rust-random/getrandom/pull/797\n\n## [0.3.4] - 2025-10-14\n\n### Major change to `wasm_js` backend\n\nNow, when the `wasm_js` feature is enabled, the `wasm_js` backend will be used\nby default. Users of `wasm32-unknown-unknown` targeting JavaScript environments\nlike the Web and Node.js will no longer need to specify:\n```\n--cfg getrandom_backend=\"wasm_js\"\n```\nin `RUSTFLAGS` for the crate to compile. They can now simple enable a feature.\n\nNote: this should not affect non-JS users of the `wasm32-unknown-unknown`\ntarget. Using `--cfg getrandom_backend` will still override the source of\nrandomness _even if_ the `wasm_js` feature is enabled. This includes\n`--cfg getrandom_backend=custom` and `--cfg getrandom_backend=unsupported`.\n\nFor more information, see the discussions in [#671], [#675], and [#730].\n\n### Added\n- `unsupported` opt-in backend [#667]\n- `windows_legacy` opt-in backend [#724]\n\n### Changed\n- Implement Memory Sanitizer unpoisoning more precisely [#678]\n- Relax MSRV for the `linux_raw` opt-in backend on ARM targets [#688]\n- Use `getrandom` syscall on all RISC-V Linux targets [#699]\n- Replaced `wasi` dependency with `wasip2` [#721]\n- Enable `wasm_js` backend by default if the `wasm_js` feature is enabled [#730]\n\n### Removed\n- Unstable `rustc-dep-of-std` crate feature [#694]\n\n[0.3.4]: https://github.com/rust-random/getrandom/compare/v0.3.3...v0.3.4\n[#667]: https://github.com/rust-random/getrandom/pull/667\n[#671]: https://github.com/rust-random/getrandom/issues/671\n[#675]: https://github.com/rust-random/getrandom/pull/675\n[#678]: https://github.com/rust-random/getrandom/pull/678\n[#688]: https://github.com/rust-random/getrandom/pull/688\n[#694]: https://github.com/rust-random/getrandom/pull/694\n[#699]: https://github.com/rust-random/getrandom/pull/699\n[#721]: https://github.com/rust-random/getrandom/pull/721\n[#724]: https://github.com/rust-random/getrandom/pull/724\n[#730]: https://github.com/rust-random/getrandom/pull/730\n\n## [0.3.3] - 2025-05-09\n\n### Changed\n- Doc improvements [#632] [#634] [#635]\n- Add crate version to docs.rs links used in `compile_error!`s [#639]\n\n### Fixed\n- Error handling in WASI p1 [#661]\n\n[0.3.3]: https://github.com/rust-random/getrandom/compare/v0.3.2...v0.3.3\n[#632]: https://github.com/rust-random/getrandom/pull/632\n[#634]: https://github.com/rust-random/getrandom/pull/634\n[#635]: https://github.com/rust-random/getrandom/pull/635\n[#639]: https://github.com/rust-random/getrandom/pull/639\n[#661]: https://github.com/rust-random/getrandom/pull/661\n\n## [0.3.2] - 2025-03-17\n\n### Added\n- `efi_rng` opt-in backend [#570]\n- `linux_raw` opt-in backend [#572]\n- `.cargo/config.toml` example in the crate-level docs [#591]\n- `getrandom_test_linux_without_fallback` configuration flag to test that file fallback\n  is not triggered in the `linux_android_with_fallback` backend [#605]\n- Built-in support for `*-linux-none` targets [#618]\n- Cygwin support [#626]\n\n### Changed\n- Update `wasi` dependency to v0.14 [#594]\n- Add `#[inline]` attribute to the inner functions [#596]\n- Update WASI and Emscripten links in the crate-level docs [#597]\n- Do not use `dlsym` on MUSL targets in the `linux_android_with_fallback` backend [#602]\n- Remove `linux_android.rs` and use `getrandom.rs` instead [#603]\n- Always use `RtlGenRandom` on Windows targets when compiling with pre-1.78 Rust [#610]\n- Internal representation of the `Error` type [#614]\n- Remove `windows-targets` dependency and use [`raw-dylib`] directly [#627]\n\n### Removed\n- `Error::INTERNAL_START` and `Error::CUSTOM_START` associated constants [#614]\n\n[0.3.2]: https://github.com/rust-random/getrandom/compare/v0.3.1...v0.3.2\n[#570]: https://github.com/rust-random/getrandom/pull/570\n[#572]: https://github.com/rust-random/getrandom/pull/572\n[#591]: https://github.com/rust-random/getrandom/pull/591\n[#594]: https://github.com/rust-random/getrandom/pull/594\n[#596]: https://github.com/rust-random/getrandom/pull/596\n[#597]: https://github.com/rust-random/getrandom/pull/597\n[#602]: https://github.com/rust-random/getrandom/pull/602\n[#603]: https://github.com/rust-random/getrandom/pull/603\n[#605]: https://github.com/rust-random/getrandom/pull/605\n[#610]: https://github.com/rust-random/getrandom/pull/610\n[#614]: https://github.com/rust-random/getrandom/pull/614\n[#618]: https://github.com/rust-random/getrandom/pull/618\n[#626]: https://github.com/rust-random/getrandom/pull/626\n[#627]: https://github.com/rust-random/getrandom/pull/627\n[`raw-dylib`]: https://doc.rust-lang.org/reference/items/external-blocks.html?highlight=link#dylib-versus-raw-dylib\n\n## [0.3.1] - 2025-01-28\n\n### Fixed\n- Build error on Android [#588]\n\n[0.3.1]: https://github.com/rust-random/getrandom/compare/v0.3.0...v0.3.1\n[#588]: https://github.com/rust-random/getrandom/pull/588\n\n## [0.3.0] - 2025-01-25\n\n### Breaking Changes\n\n#### Changed\n- Bump MSRV to 1.63 [#542]\n- Rename `getrandom` and `getrandom_uninit` functions to `fill` and `fill_uninit` respectively [#532]\n\n#### Removed\n- `wasm32-wasi` target support (use `wasm32-wasip1` or `wasm32-wasip2` instead) [#499]\n- `linux_disable_fallback`, `rdrand`, `js`, `test-in-browser`, and `custom` crate features\n  in favor of configuration flags [#504]\n- `register_custom_getrandom!` macro [#504]\n- Implementation of `From<NonZeroU32>` for `Error` and `Error::code` method [#507]\n- Internet Explorer 11 support [#554]\n- Target-specific associated `Error` constants [#562]\n\n### Changed\n- Use `ProcessPrng` on Windows 10 and up, and use `RtlGenRandom` on older Windows versions [#415]\n- Do not use locale-specific `strerror_r` for retrieving error code descriptions [#440]\n- Avoid assuming `usize` is the native word size in the `rdrand` backend [#442]\n- Do not read from `errno` when `libc` did not indicate error on Solaris [#448]\n- Switch from `libpthread`'s mutex to `futex` on Linux and to `nanosleep`-based wait loop\n  on other targets in the `use_file` backend [#490]\n- Do not retry on `EAGAIN` while polling `/dev/random` on Linux [#522]\n- Remove separate codepath for Node.js in the `wasm_js` backend\n  (bumps minimum supported Node.js version to v19) [#557]\n- Use `js_namespace` in the `wasm_js` backend [#559]\n \n### Added\n- `wasm32-wasip1` and `wasm32-wasip2` support [#499]\n- `getrandom_backend` configuration flag for selection of opt-in backends [#504]\n- `Error::new_custom` method [#507]\n- `rndr` opt-in backend [#512]\n- Automatic MemorySanitizer support [#521] [#571]\n- `u32` and `u64` functions for generating random values of the respective type [#544]\n- `wasm32v1-none` support in the `wasm_js` backend [#560]\n- `wasm_js` crate feature which allows users to enable the `wasm_js` opt-in backend [#574]\n\n### Fixed\n- NetBSD fallback code based on `KERN_ARND` [#555]\n\n[0.3.0]: https://github.com/rust-random/getrandom/compare/v0.2.15...v0.3.0\n[#415]: https://github.com/rust-random/getrandom/pull/415\n[#440]: https://github.com/rust-random/getrandom/pull/440\n[#442]: https://github.com/rust-random/getrandom/pull/442\n[#448]: https://github.com/rust-random/getrandom/pull/448\n[#490]: https://github.com/rust-random/getrandom/pull/490\n[#499]: https://github.com/rust-random/getrandom/pull/499\n[#504]: https://github.com/rust-random/getrandom/pull/504\n[#507]: https://github.com/rust-random/getrandom/pull/507\n[#512]: https://github.com/rust-random/getrandom/pull/512\n[#521]: https://github.com/rust-random/getrandom/pull/521\n[#522]: https://github.com/rust-random/getrandom/pull/522\n[#532]: https://github.com/rust-random/getrandom/pull/532\n[#542]: https://github.com/rust-random/getrandom/pull/542\n[#544]: https://github.com/rust-random/getrandom/pull/544\n[#554]: https://github.com/rust-random/getrandom/pull/554\n[#555]: https://github.com/rust-random/getrandom/pull/555\n[#557]: https://github.com/rust-random/getrandom/pull/557\n[#559]: https://github.com/rust-random/getrandom/pull/559\n[#560]: https://github.com/rust-random/getrandom/pull/560\n[#562]: https://github.com/rust-random/getrandom/pull/562\n[#571]: https://github.com/rust-random/getrandom/pull/571\n[#574]: https://github.com/rust-random/getrandom/pull/574\n\n## [0.2.17] - 2026-01-12\n### Fixed\n- Use `doc_cfg` instead of `doc_auto_cfg` (partial backport of [#732]) [#768]\n- `BCryptGenRandom` signature [#778]\n\n[0.2.17]: https://github.com/rust-random/getrandom/compare/v0.2.16...v0.2.17\n[#732]: https://github.com/rust-random/getrandom/pull/732\n[#768]: https://github.com/rust-random/getrandom/pull/768\n[#778]: https://github.com/rust-random/getrandom/pull/778\n\n## [0.2.16] - 2025-04-22\n### Added\n- Cygwin support (backport of [#626]) [#654]\n\n[0.2.16]: https://github.com/rust-random/getrandom/compare/v0.2.15...v0.2.16\n[#654]: https://github.com/rust-random/getrandom/pull/654\n\n## [0.2.15] - 2024-05-06\n### Added\n- Apple visionOS support [#410]\n\n### Changed\n- Use `libc::getrandom` on DragonflyBSD, FreeBSD, illumos, and Solaris [#411] [#416] [#417] [#420]\n- Unify `libc::getentropy`-based implementations [#418]\n\n[0.2.15]: https://github.com/rust-random/getrandom/compare/v0.2.14...v0.2.15\n[#410]: https://github.com/rust-random/getrandom/pull/410\n[#411]: https://github.com/rust-random/getrandom/pull/411\n[#416]: https://github.com/rust-random/getrandom/pull/416\n[#417]: https://github.com/rust-random/getrandom/pull/417\n[#418]: https://github.com/rust-random/getrandom/pull/418\n[#420]: https://github.com/rust-random/getrandom/pull/420\n\n## [0.2.14] - 2024-04-08\n### Fixed\n- Enable `/dev/urandom` fallback for MUSL-based Linux targets [#408]\n\n[0.2.14]: https://github.com/rust-random/getrandom/compare/v0.2.13...v0.2.14\n[#408]: https://github.com/rust-random/getrandom/pull/408\n\n## [0.2.13] - 2024-04-06\n### Added\n- `linux_disable_fallback` crate feature to disable `/dev/urandom`-based fallback on Linux and\n  Android targets. Enabling this feature bumps minimum supported Linux kernel version to 3.17 and\n  Android API level to 23 (Marshmallow). [#396]\n\n### Changed\n- Disable `/dev/urandom` fallback for Linux targets outside of the following `target_arch`es:\n  `aarch64`, `arm`, `powerpc`, `powerpc64`, `s390x`, `x86`, `x86_64` [#396]\n- Do not catch `EPERM` error code on Android while checking availability of\n  the `getrandom` syscall [#396]\n\n[0.2.13]: https://github.com/rust-random/getrandom/compare/v0.2.12...v0.2.13\n[#396]: https://github.com/rust-random/getrandom/pull/396\n\n## [0.2.12] - 2024-01-09\n### Fixed\n- Custom backend for targets without atomics [#385]\n\n### Changed\n- Improve robustness of the Hermit backend and `sys_fill_exact` [#386]\n- Raise minimum supported Apple OS versions to macOS 10.12 and iOS 10 [#388]\n\n### Added\n- Document platform support policy [#387]\n\n[0.2.12]: https://github.com/rust-random/getrandom/compare/v0.2.11...v0.2.12\n[#385]: https://github.com/rust-random/getrandom/pull/385\n[#386]: https://github.com/rust-random/getrandom/pull/386\n[#387]: https://github.com/rust-random/getrandom/pull/387\n[#388]: https://github.com/rust-random/getrandom/pull/388\n\n## [0.2.11] - 2023-11-08\n### Added\n- GNU/Hurd support [#370]\n\n### Changed\n- Renamed `__getrandom_internal` to `__GETRANDOM_INTERNAL`  [#369]\n- Updated link to Hermit docs [#374]\n\n[0.2.11]: https://github.com/rust-random/getrandom/compare/v0.2.10...v0.2.11\n[#369]: https://github.com/rust-random/getrandom/pull/369\n[#370]: https://github.com/rust-random/getrandom/pull/370\n[#374]: https://github.com/rust-random/getrandom/pull/374\n\n## [0.2.10] - 2023-06-06\n### Added\n- Support for PS Vita (`armv7-sony-vita-newlibeabihf`) [#359]\n\n### Changed\n- Use getentropy from libc on Emscripten targets [#362]\n\n[0.2.10]: https://github.com/rust-random/getrandom/compare/v0.2.9...v0.2.10\n[#359]: https://github.com/rust-random/getrandom/pull/359\n[#362]: https://github.com/rust-random/getrandom/pull/362\n\n## [0.2.9] - 2023-04-06\n### Added\n- AIX support [#282]\n- `getrandom_uninit` function [#291]\n- `wasm64-unknown-unknown` support [#303]\n- tvOS and watchOS support [#317]\n- QNX/nto support [#325]\n- Support for `getrandom` syscall on NetBSD ≥ 10.0 [#331]\n- `RtlGenRandom` fallback for non-UWP Windows [#337]\n\n### Breaking Changes\n- Update MSRV to 1.36 [#291]\n\n### Fixed\n- Solaris/OpenBSD/Dragonfly build [#301]\n\n### Changed\n- Update MSRV to 1.36 [#291]\n- Use getentropy on Emscripten [#307]\n- Solaris: consistently use `/dev/random` source [#310]\n- Move 3ds selection above rdrand/js/custom fallback [#312]\n- Remove buffer zeroing from Node.js implementation [#315]\n- Use `open` instead of `open64` [#326]\n- Remove #cfg from bsd_arandom.rs [#332]\n- Hermit: use `sys_read_entropy` syscall [#333]\n- Eliminate potential panic in sys_fill_exact [#334]\n- rdrand: Remove checking for 0 and !0 and instead check CPU family and do a self-test [#335]\n- Move `__getrandom_custom` definition into a const block [#344]\n- Switch the custom backend to Rust ABI [#347]\n\n[0.2.9]: https://github.com/rust-random/getrandom/compare/v0.2.8...v0.2.9\n[#282]: https://github.com/rust-random/getrandom/pull/282\n[#291]: https://github.com/rust-random/getrandom/pull/291\n[#301]: https://github.com/rust-random/getrandom/pull/301\n[#303]: https://github.com/rust-random/getrandom/pull/303\n[#307]: https://github.com/rust-random/getrandom/pull/307\n[#310]: https://github.com/rust-random/getrandom/pull/310\n[#312]: https://github.com/rust-random/getrandom/pull/312\n[#315]: https://github.com/rust-random/getrandom/pull/315\n[#317]: https://github.com/rust-random/getrandom/pull/317\n[#325]: https://github.com/rust-random/getrandom/pull/325\n[#326]: https://github.com/rust-random/getrandom/pull/326\n[#331]: https://github.com/rust-random/getrandom/pull/331\n[#332]: https://github.com/rust-random/getrandom/pull/332\n[#333]: https://github.com/rust-random/getrandom/pull/333\n[#334]: https://github.com/rust-random/getrandom/pull/334\n[#335]: https://github.com/rust-random/getrandom/pull/335\n[#337]: https://github.com/rust-random/getrandom/pull/337\n[#344]: https://github.com/rust-random/getrandom/pull/344\n[#347]: https://github.com/rust-random/getrandom/pull/347\n\n## [0.2.8] - 2022-10-20\n### Changed\n- The [Web Cryptography API] will now be preferred on `wasm32-unknown-unknown`\n  when using the `\"js\"` feature, even on Node.js [#284] [#295]\n\n### Added\n- Added benchmarks to track buffer initialization cost [#272]\n\n### Fixed\n- Use `$crate` in `register_custom_getrandom!` [#270]\n\n### Documentation\n- Add information about enabling `\"js\"` feature [#280]\n- Fix link to `wasm-bindgen` [#278]\n- Document the varied implementations for underlying randomness sources [#276]\n\n[0.2.8]: https://github.com/rust-random/getrandom/compare/v0.2.7...v0.2.8\n[#284]: https://github.com/rust-random/getrandom/pull/284\n[#295]: https://github.com/rust-random/getrandom/pull/295\n[#272]: https://github.com/rust-random/getrandom/pull/272\n[#270]: https://github.com/rust-random/getrandom/pull/270\n[#280]: https://github.com/rust-random/getrandom/pull/280\n[#278]: https://github.com/rust-random/getrandom/pull/278\n[#276]: https://github.com/rust-random/getrandom/pull/276\n[Web Cryptography API]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API\n\n## [0.2.7] - 2022-06-14\n### Changed\n- Update `wasi` dependency to `0.11` [#253]\n\n### Fixed\n- Use `AtomicPtr` instead of `AtomicUsize` for Strict Provenance compatibility. [#263]\n\n### Documentation\n- Add comments explaining use of fallback mechanisms [#257] [#260]\n\n[0.2.7]: https://github.com/rust-random/getrandom/compare/v0.2.6...v0.2.7\n[#263]: https://github.com/rust-random/getrandom/pull/263\n[#260]: https://github.com/rust-random/getrandom/pull/260\n[#253]: https://github.com/rust-random/getrandom/pull/253\n[#257]: https://github.com/rust-random/getrandom/pull/257\n\n## [0.2.6] - 2022-03-28\n### Added\n- Nintendo 3DS (`armv6k-nintendo-3ds`) support [#248]\n\n### Changed\n- Retry `open` when interrupted [#252]\n\n[0.2.6]: https://github.com/rust-random/getrandom/compare/v0.2.5...v0.2.6\n[#248]: https://github.com/rust-random/getrandom/pull/248\n[#252]: https://github.com/rust-random/getrandom/pull/252\n\n## [0.2.5] - 2022-02-22\n### Added\n- ESP-IDF targets (`*‑espidf`) support [#245]\n\n### Fixed\n- Webpack warning caused by dynamic require [#234]\n- Error checking on iOS for `SecRandomCopyBytes` [#244]\n\n[0.2.5]: https://github.com/rust-random/getrandom/compare/v0.2.4...v0.2.5\n[#234]: https://github.com/rust-random/getrandom/pull/234\n[#244]: https://github.com/rust-random/getrandom/pull/244\n[#245]: https://github.com/rust-random/getrandom/pull/245\n\n## [0.2.4] - 2021-12-13\n### Changed\n- Use explicit imports in the `js` backend [#220]\n- Use `/dev/urandom` on Redox instead of `rand:` [#222]\n- Use `NonZeroU32::new_unchecked` to convert wasi error [#233]\n\n### Added\n- SOLID targets (`*-kmc-solid_*`) support [#235]\n- Limited Hermit (`x86_64-unknown-hermit`) support [#236]\n\n[0.2.4]: https://github.com/rust-random/getrandom/compare/v0.2.3...v0.2.4\n[#220]: https://github.com/rust-random/getrandom/pull/220\n[#222]: https://github.com/rust-random/getrandom/pull/222\n[#233]: https://github.com/rust-random/getrandom/pull/233\n[#235]: https://github.com/rust-random/getrandom/pull/235\n[#236]: https://github.com/rust-random/getrandom/pull/236\n\n## [0.2.3] - 2021-04-10\n### Changed\n- Replace build.rs with link attributes. [#205]\n- Add support for getrandom syscall on DragonFly BSD. [#210]\n- Improve Node.js detection. [#215]\n\n[0.2.3]: https://github.com/rust-random/getrandom/compare/v0.2.2...v0.2.3\n[#205]: https://github.com/rust-random/getrandom/pull/205\n[#210]: https://github.com/rust-random/getrandom/pull/210\n[#215]: https://github.com/rust-random/getrandom/pull/215\n\n## [0.2.2] - 2021-01-19\n### Changed\n- Forward `rustc-dep-of-std` to dependencies. [#198]\n- Highlight feature-dependent functionality in documentation using the `doc_cfg` feature. [#200]\n\n[0.2.2]: https://github.com/rust-random/getrandom/compare/v0.2.1...v0.2.2\n[#198]: https://github.com/rust-random/getrandom/pull/198\n[#200]: https://github.com/rust-random/getrandom/pull/200\n\n## [0.2.1] - 2021-01-03\n### Changed\n- Update `cfg-if` to v1.0. [#166]\n- Update `wasi` to v0.10. [#167]\n\n### Fixed\n- Multithreaded WASM support. [#165]\n\n### Removed\n- Windows XP support. [#177]\n- Direct `stdweb` support. [#178]\n- CloudABI support. [#184]\n\n[0.2.1]: https://github.com/rust-random/getrandom/compare/v0.2.0...v0.2.1\n[#165]: https://github.com/rust-random/getrandom/pull/165\n[#166]: https://github.com/rust-random/getrandom/pull/166\n[#167]: https://github.com/rust-random/getrandom/pull/167\n[#177]: https://github.com/rust-random/getrandom/pull/177\n[#178]: https://github.com/rust-random/getrandom/pull/178\n[#184]: https://github.com/rust-random/getrandom/pull/184\n\n## [0.2.0] - 2020-09-10\n### Features for using getrandom on unsupported targets\n\nThe following (off by default) Cargo features have been added:\n- `\"rdrand\"` - use the RDRAND instruction on `no_std` `x86`/`x86_64` targets [#133]\n- `\"js\"` - use JavaScript calls on `wasm32-unknown-unknown` [#149]\n  - Replaces the `stdweb` and `wasm-bindgen` features (which are removed)\n- `\"custom\"` - allows a user to specify a custom implementation [#109]\n\n### Breaking Changes\n- Unsupported targets no longer compile [#107]\n- Change/Add `Error` constants [#120]\n- Only impl `std` traits when the `\"std\"` Cargo feature is specified [#106]\n- Remove official support for Hermit, L4Re, and UEFI [#133]\n- Remove optional `\"log\"` dependency [#131]\n- Update minimum supported Linux kernel to 2.6.32 [#153]\n- Update MSRV to 1.34 [#159]\n\n[0.2.0]: https://github.com/rust-random/getrandom/compare/v0.1.16...v0.2.0\n[#106]: https://github.com/rust-random/getrandom/pull/106\n[#107]: https://github.com/rust-random/getrandom/pull/107\n[#109]: https://github.com/rust-random/getrandom/pull/109\n[#120]: https://github.com/rust-random/getrandom/pull/120\n[#131]: https://github.com/rust-random/getrandom/pull/131\n[#133]: https://github.com/rust-random/getrandom/pull/133\n[#149]: https://github.com/rust-random/getrandom/pull/149\n[#153]: https://github.com/rust-random/getrandom/pull/153\n[#159]: https://github.com/rust-random/getrandom/pull/159\n\n## [0.1.16] - 2020-12-31\n### Changed\n- Update `cfg-if` to v1.0. [#173]\n- Implement `std::error::Error` for the `Error` type on additional targets. [#169]\n\n### Fixed\n- Multithreaded WASM support. [#171]\n\n[0.1.16]: https://github.com/rust-random/getrandom/compare/v0.1.15...v0.1.16\n[#173]: https://github.com/rust-random/getrandom/pull/173\n[#171]: https://github.com/rust-random/getrandom/pull/171\n[#169]: https://github.com/rust-random/getrandom/pull/169\n\n## [0.1.15] - 2020-09-10\n### Changed\n- Added support for Internet Explorer 11 [#139]\n- Fix Webpack require warning with `wasm-bindgen` [#137]\n\n[0.1.15]: https://github.com/rust-random/getrandom/compare/v0.1.14...v0.1.15\n[#137]: https://github.com/rust-random/getrandom/pull/137\n[#139]: https://github.com/rust-random/getrandom/pull/139\n\n## [0.1.14] - 2020-01-07\n### Changed\n- Remove use of spin-locks in the `use_file` module. [#125]\n- Update `wasi` to v0.9. [#126]\n- Do not read errno value on DragonFlyBSD to fix compilation failure. [#129]\n\n[0.1.14]: https://github.com/rust-random/getrandom/compare/v0.1.13...v0.1.14\n[#125]: https://github.com/rust-random/getrandom/pull/125\n[#126]: https://github.com/rust-random/getrandom/pull/126\n[#129]: https://github.com/rust-random/getrandom/pull/129\n\n## [0.1.13] - 2019-08-25\n### Added\n- VxWorks targets support. [#86]\n\n### Changed\n- If zero-length slice is passed to the `getrandom` function, always return\n`Ok(())` immediately without doing any calls to the underlying operating\nsystem. [#104]\n- Use the `kern.arandom` sysctl on NetBSD. [#115]\n\n### Fixed\n- Bump `cfg-if` minimum version from 0.1.0 to 0.1.2. [#112]\n- Typos and bad doc links. [#117]\n\n[0.1.13]: https://github.com/rust-random/getrandom/compare/v0.1.12...v0.1.13\n[#86]: https://github.com/rust-random/getrandom/pull/86\n[#104]: https://github.com/rust-random/getrandom/pull/104\n[#112]: https://github.com/rust-random/getrandom/pull/112\n[#115]: https://github.com/rust-random/getrandom/pull/115\n[#117]: https://github.com/rust-random/getrandom/pull/117\n\n## [0.1.12] - 2019-08-18\n### Changed\n- Update wasi dependency from v0.5 to v0.7. [#100]\n\n[0.1.12]: https://github.com/rust-random/getrandom/compare/v0.1.11...v0.1.12\n[#100]: https://github.com/rust-random/getrandom/pull/100\n\n## [0.1.11] - 2019-08-25\n### Fixed\n- Implement `std`-dependent traits for selected targets even if `std`\nfeature is disabled. (backward compatibility with v0.1.8) [#96]\n\n[0.1.11]: https://github.com/rust-random/getrandom/compare/v0.1.10...v0.1.11\n[#96]: https://github.com/rust-random/getrandom/pull/96\n\n## [0.1.10] - 2019-08-18 [YANKED]\n### Changed\n- Use the dummy implementation on `wasm32-unknown-unknown` even with the\ndisabled `dummy` feature. [#90]\n\n### Fixed\n- Fix CSP error for `wasm-bindgen`. [#92]\n\n[0.1.10]: https://github.com/rust-random/getrandom/compare/v0.1.9...v0.1.10\n[#90]: https://github.com/rust-random/getrandom/pull/90\n[#92]: https://github.com/rust-random/getrandom/pull/92\n\n## [0.1.9] - 2019-08-14 [YANKED]\n### Changed\n- Remove `std` dependency for opening and reading files. [#58]\n- Use `wasi` instead of `libc` on WASI target. [#64]\n- By default emit a compile-time error when built for an unsupported target.\nThis behaviour can be disabled by using the `dummy` feature. [#71]\n\n### Added\n- Add support for UWP targets. [#69]\n- Add unstable `rustc-dep-of-std` feature. [#78]\n\n[0.1.9]: https://github.com/rust-random/getrandom/compare/v0.1.8...v0.1.9\n[#58]: https://github.com/rust-random/getrandom/pull/58\n[#64]: https://github.com/rust-random/getrandom/pull/64\n[#69]: https://github.com/rust-random/getrandom/pull/69\n[#71]: https://github.com/rust-random/getrandom/pull/71\n[#78]: https://github.com/rust-random/getrandom/pull/78\n\n## [0.1.8] - 2019-07-29\n### Changed\n- Explicitly specify types to arguments of 'libc::syscall'. [#74]\n\n[0.1.8]: https://github.com/rust-random/getrandom/compare/v0.1.7...v0.1.8\n[#74]: https://github.com/rust-random/getrandom/pull/74\n\n## [0.1.7] - 2019-07-29\n### Added\n- Support for hermit and l4re. [#61]\n- `Error::raw_os_error` method, `Error::INTERNAL_START` and\n`Error::CUSTOM_START` constants. Use `libc` for retrieving OS error descriptions. [#54]\n\n### Changed\n- Remove `lazy_static` dependency and use custom structures for lock-free\ninitialization. [#51] [#52]\n- Try `getrandom()` first on FreeBSD. [#57]\n\n### Removed\n-  Bitrig support. [#56]\n\n### Deprecated\n- `Error::UNKNOWN`, `Error::UNAVAILABLE`. [#54]\n\n[0.1.7]: https://github.com/rust-random/getrandom/compare/v0.1.6...v0.1.7\n[#51]: https://github.com/rust-random/getrandom/pull/51\n[#52]: https://github.com/rust-random/getrandom/pull/52\n[#54]: https://github.com/rust-random/getrandom/pull/54\n[#56]: https://github.com/rust-random/getrandom/pull/56\n[#57]: https://github.com/rust-random/getrandom/pull/57\n[#61]: https://github.com/rust-random/getrandom/pull/61\n\n## [0.1.6] - 2019-06-30\n### Changed\n- Minor change of RDRAND AMD bug handling. [#48]\n\n[0.1.6]: https://github.com/rust-random/getrandom/compare/v0.1.5...v0.1.6\n[#48]: https://github.com/rust-random/getrandom/pull/48\n\n## [0.1.5] - 2019-06-29\n### Fixed\n- Use shared `File` instead of shared file descriptor. [#44]\n- Workaround for RDRAND hardware bug present on some AMD CPUs. [#43]\n\n### Changed\n- Try `getentropy` and then fallback to `/dev/random` on macOS. [#38]\n\n[0.1.5]: https://github.com/rust-random/getrandom/compare/v0.1.4...v0.1.5\n[#38]: https://github.com/rust-random/getrandom/issues/38\n[#43]: https://github.com/rust-random/getrandom/pull/43\n[#44]: https://github.com/rust-random/getrandom/issues/44\n\n## [0.1.4] - 2019-06-28\n### Added\n- Add support for `x86_64-unknown-uefi` target by using RDRAND with CPUID\nfeature detection. [#30]\n\n### Fixed\n- Fix long buffer issues on Windows and Linux. [#31] [#32]\n- Check `EPERM` in addition to `ENOSYS` on Linux. [#37]\n\n### Changed\n- Improve efficiency by sharing file descriptor across threads. [#13]\n- Remove `cloudabi`, `winapi`, and `fuchsia-cprng` dependencies. [#40]\n- Improve RDRAND implementation. [#24]\n- Don't block during syscall detection on Linux. [#26]\n- Increase consistency with libc implementation on FreeBSD. [#36]\n- Apply `rustfmt`. [#39]\n\n[0.1.4]: https://github.com/rust-random/getrandom/compare/v0.1.3...v0.1.4\n[#30]: https://github.com/rust-random/getrandom/pull/30\n[#13]: https://github.com/rust-random/getrandom/issues/13\n[#40]: https://github.com/rust-random/getrandom/pull/40\n[#26]: https://github.com/rust-random/getrandom/pull/26\n[#24]: https://github.com/rust-random/getrandom/pull/24\n[#39]: https://github.com/rust-random/getrandom/pull/39\n[#36]: https://github.com/rust-random/getrandom/pull/36\n[#31]: https://github.com/rust-random/getrandom/issues/31\n[#32]: https://github.com/rust-random/getrandom/issues/32\n[#37]: https://github.com/rust-random/getrandom/issues/37\n\n## [0.1.3] - 2019-05-15\n- Update for `wasm32-unknown-wasi` being renamed to `wasm32-wasi`, and for\n  WASI being categorized as an OS.\n\n[0.1.3]: https://github.com/rust-random/getrandom/compare/v0.1.2...v0.1.3\n\n## [0.1.2] - 2019-04-06\n- Add support for `wasm32-unknown-wasi` target.\n\n[0.1.2]: https://github.com/rust-random/getrandom/compare/v0.1.1...v0.1.2\n\n## [0.1.1] - 2019-04-05\n- Enable std functionality for CloudABI by default.\n\n[0.1.1]: https://github.com/rust-random/getrandom/compare/v0.1.0...v0.1.1\n\n## [0.1.0] - 2019-03-23\nPublish initial implementation.\n\n[0.1.0]: https://github.com/rust-random/getrandom/compare/v0.0.0...v0.1.0\n\n## [0.0.0] - 2019-01-19\nPublish an empty template library.\n\n[0.0.0]: https://github.com/rust-random/getrandom/releases/tag/v0.0.0\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"getrandom\"\nversion = \"0.4.2\"\nedition = \"2024\"\nrust-version = \"1.85\" # Sync tests.yml and README.md.\nauthors = [\"The Rand Project Developers\"]\nlicense = \"MIT OR Apache-2.0\"\ndescription = \"A small cross-platform library for retrieving random data from system source\"\ndocumentation = \"https://docs.rs/getrandom\"\nrepository = \"https://github.com/rust-random/getrandom\"\ncategories = [\"os\", \"no-std\"]\nexclude = [\".*\"]\n\n[package.metadata.docs.rs]\nfeatures = [\"std\", \"sys_rng\"]\nrustdoc-args = [\"--cfg\", \"getrandom_backend=\\\"extern_impl\\\"\"]\n\n[features]\n# Implement From<getrandom::Error> for std::io::Error and\n# use std to retrieve OS error descriptions\nstd = []\n\n# Optional backend: wasm_js\n#\n# This flag enables the wasm_js backend and uses it by default on wasm32 where\n# the target_os is unknown. The getrandom_backend cfg may override this.\n#\n# WARNING: We strongly recommend against enabling this feature in libraries (except for tests)\n# since it is known to break non-Web WASM builds and further since the usage of `wasm-bindgen`\n# causes significant bloat to `Cargo.lock` (on all targets).\n#\n# The only exception to this rule: if your crate already unconditionally depends on `wasm-bindgen`\n# or `js-sys` on \"unknown\" WASM targets then it's acceptable to enable this feature unconditionally.\nwasm_js = [\"dep:wasm-bindgen\", \"dep:js-sys\"]\n\n# Provide SysRng over rand_core\nsys_rng = [\"dep:rand_core\"]\n\n[dependencies]\ncfg-if = \"1\"\nrand_core = { version = \"0.10.0\", optional = true }\n\n# getrandom / linux_android_with_fallback\n[target.'cfg(all(any(target_os = \"linux\", target_os = \"android\"), not(any(all(target_os = \"linux\", target_env = \"\"), getrandom_backend = \"custom\", getrandom_backend = \"linux_raw\", getrandom_backend = \"rdrand\", getrandom_backend = \"rndr\"))))'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# apple-other\n[target.'cfg(any(target_os = \"ios\", target_os = \"visionos\", target_os = \"watchos\", target_os = \"tvos\"))'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# efi_rng\n[target.'cfg(all(target_os = \"uefi\", getrandom_backend = \"efi_rng\"))'.dependencies]\nr-efi = { version = \"6\", default-features = false }\n\n# getentropy\n[target.'cfg(any(target_os = \"macos\", target_os = \"openbsd\", target_os = \"vita\", target_os = \"emscripten\"))'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# getrandom\n[target.'cfg(any(target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"hurd\", target_os = \"illumos\", target_os = \"cygwin\", all(target_os = \"horizon\", target_arch = \"arm\")))'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# netbsd\n[target.'cfg(target_os = \"netbsd\")'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# solaris\n[target.'cfg(target_os = \"solaris\")'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# use_file\n[target.'cfg(any(target_os = \"haiku\", target_os = \"redox\", target_os = \"nto\", target_os = \"aix\"))'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# vxworks\n[target.'cfg(target_os = \"vxworks\")'.dependencies]\nlibc = { version = \"0.2.154\", default-features = false }\n\n# wasi_p2_3\n[target.'cfg(all(target_arch = \"wasm32\", target_os = \"wasi\", target_env = \"p2\"))'.dependencies]\nwasip2 = { version = \"1\", default-features = false }\n\n# wasi_p2_3\n[target.'cfg(all(target_arch = \"wasm32\", target_os = \"wasi\", target_env = \"p3\"))'.dependencies]\n# TODO: remove 0.3 after MSRV bumped to 1.87+.\nwasip3 = \">=0.3, <=0.4\"\n\n# wasm_js\n[target.'cfg(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\")))'.dependencies]\nwasm-bindgen = { version = \"0.2.98\", default-features = false, optional = true }\n[target.'cfg(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\"), target_feature = \"atomics\"))'.dependencies]\njs-sys = { version = \"0.3.77\", default-features = false, optional = true }\n[target.'cfg(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\")))'.dev-dependencies]\nwasm-bindgen-test = \"0.3\"\n\n[lints.rust.unexpected_cfgs]\nlevel = \"warn\"\ncheck-cfg = [\n  'cfg(getrandom_backend, values(\"custom\", \"efi_rng\", \"rdrand\", \"rndr\", \"linux_getrandom\", \"linux_raw\", \"windows_legacy\", \"unsupported\", \"extern_impl\"))',\n  'cfg(getrandom_msan)',\n  'cfg(getrandom_test_linux_fallback)',\n  'cfg(getrandom_test_linux_without_fallback)',\n  'cfg(getrandom_test_netbsd_fallback)',\n  'cfg(target_os, values(\"cygwin\"))', # TODO(MSRV 1.86): Remove this.\n  'cfg(target_os, values(\"motor\"))',\n]\n\n[lints.rust]\nunused_lifetimes = \"warn\"\nmissing_docs = \"warn\"\n\n[lints.clippy]\ncast_lossless = \"warn\"\ncast_possible_truncation = \"warn\"\ncast_possible_wrap = \"warn\"\ncast_precision_loss = \"warn\"\ncast_ptr_alignment = \"warn\"\ncast_sign_loss = \"warn\"\nchar_lit_as_u8 = \"warn\"\nchecked_conversions = \"warn\"\nfn_to_numeric_cast = \"warn\"\nfn_to_numeric_cast_with_truncation = \"warn\"\nptr_as_ptr = \"warn\"\nunnecessary_cast = \"warn\"\nuseless_conversion = \"warn\"\n\n# workaround for https://github.com/cross-rs/cross/issues/1345\n[package.metadata.cross.target.x86_64-unknown-netbsd]\npre-build = [\n  \"mkdir -p /tmp/netbsd\",\n  \"curl -fO https://cdn.netbsd.org/pub/NetBSD/NetBSD-9.3/amd64/binary/sets/base.tar.xz\",\n  \"tar -C /tmp/netbsd -xJf base.tar.xz\",\n  \"cp /tmp/netbsd/usr/lib/libexecinfo.so /usr/local/x86_64-unknown-netbsd/lib\",\n  \"rm base.tar.xz\",\n  \"rm -rf /tmp/netbsd\",\n]\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "                              Apache License\n                        Version 2.0, January 2004\n                     https://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n   \"License\" shall mean the terms and conditions for use, reproduction,\n   and distribution as defined by Sections 1 through 9 of this document.\n\n   \"Licensor\" shall mean the copyright owner or entity authorized by\n   the copyright owner that is granting the License.\n\n   \"Legal Entity\" shall mean the union of the acting entity and all\n   other entities that control, are controlled by, or are under common\n   control with that entity. For the purposes of this definition,\n   \"control\" means (i) the power, direct or indirect, to cause the\n   direction or management of such entity, whether by contract or\n   otherwise, or (ii) ownership of fifty percent (50%) or more of the\n   outstanding shares, or (iii) beneficial ownership of such entity.\n\n   \"You\" (or \"Your\") shall mean an individual or Legal Entity\n   exercising permissions granted by this License.\n\n   \"Source\" form shall mean the preferred form for making modifications,\n   including but not limited to software source code, documentation\n   source, and configuration files.\n\n   \"Object\" form shall mean any form resulting from mechanical\n   transformation or translation of a Source form, including but\n   not limited to compiled object code, generated documentation,\n   and conversions to other media types.\n\n   \"Work\" shall mean the work of authorship, whether in Source or\n   Object form, made available under the License, as indicated by a\n   copyright notice that is included in or attached to the work\n   (an example is provided in the Appendix below).\n\n   \"Derivative Works\" shall mean any work, whether in Source or Object\n   form, that is based on (or derived from) the Work and for which the\n   editorial revisions, annotations, elaborations, or other modifications\n   represent, as a whole, an original work of authorship. For the purposes\n   of this License, Derivative Works shall not include works that remain\n   separable from, or merely link (or bind by name) to the interfaces of,\n   the Work and Derivative Works thereof.\n\n   \"Contribution\" shall mean any work of authorship, including\n   the original version of the Work and any modifications or additions\n   to that Work or Derivative Works thereof, that is intentionally\n   submitted to Licensor for inclusion in the Work by the copyright owner\n   or by an individual or Legal Entity authorized to submit on behalf of\n   the copyright owner. For the purposes of this definition, \"submitted\"\n   means any form of electronic, verbal, or written communication sent\n   to the Licensor or its representatives, including but not limited to\n   communication on electronic mailing lists, source code control systems,\n   and issue tracking systems that are managed by, or on behalf of, the\n   Licensor for the purpose of discussing and improving the Work, but\n   excluding communication that is conspicuously marked or otherwise\n   designated in writing by the copyright owner as \"Not a Contribution.\"\n\n   \"Contributor\" shall mean Licensor and any individual or Legal Entity\n   on behalf of whom a Contribution has been received by Licensor and\n   subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   copyright license to reproduce, prepare Derivative Works of,\n   publicly display, publicly perform, sublicense, and distribute the\n   Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   (except as stated in this section) patent license to make, have made,\n   use, offer to sell, sell, import, and otherwise transfer the Work,\n   where such license applies only to those patent claims licensable\n   by such Contributor that are necessarily infringed by their\n   Contribution(s) alone or by combination of their Contribution(s)\n   with the Work to which such Contribution(s) was submitted. If You\n   institute patent litigation against any entity (including a\n   cross-claim or counterclaim in a lawsuit) alleging that the Work\n   or a Contribution incorporated within the Work constitutes direct\n   or contributory patent infringement, then any patent licenses\n   granted to You under this License for that Work shall terminate\n   as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n   Work or Derivative Works thereof in any medium, with or without\n   modifications, and in Source or Object form, provided that You\n   meet the following conditions:\n\n   (a) You must give any other recipients of the Work or\n       Derivative Works a copy of this License; and\n\n   (b) You must cause any modified files to carry prominent notices\n       stating that You changed the files; and\n\n   (c) You must retain, in the Source form of any Derivative Works\n       that You distribute, all copyright, patent, trademark, and\n       attribution notices from the Source form of the Work,\n       excluding those notices that do not pertain to any part of\n       the Derivative Works; and\n\n   (d) If the Work includes a \"NOTICE\" text file as part of its\n       distribution, then any Derivative Works that You distribute must\n       include a readable copy of the attribution notices contained\n       within such NOTICE file, excluding those notices that do not\n       pertain to any part of the Derivative Works, in at least one\n       of the following places: within a NOTICE text file distributed\n       as part of the Derivative Works; within the Source form or\n       documentation, if provided along with the Derivative Works; or,\n       within a display generated by the Derivative Works, if and\n       wherever such third-party notices normally appear. The contents\n       of the NOTICE file are for informational purposes only and\n       do not modify the License. You may add Your own attribution\n       notices within Derivative Works that You distribute, alongside\n       or as an addendum to the NOTICE text from the Work, provided\n       that such additional attribution notices cannot be construed\n       as modifying the License.\n\n   You may add Your own copyright statement to Your modifications and\n   may provide additional or different license terms and conditions\n   for use, reproduction, or distribution of Your modifications, or\n   for any such Derivative Works as a whole, provided Your use,\n   reproduction, and distribution of the Work otherwise complies with\n   the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n   any Contribution intentionally submitted for inclusion in the Work\n   by You to the Licensor shall be under the terms and conditions of\n   this License, without any additional terms or conditions.\n   Notwithstanding the above, nothing herein shall supersede or modify\n   the terms of any separate license agreement you may have executed\n   with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n   names, trademarks, service marks, or product names of the Licensor,\n   except as required for reasonable and customary use in describing the\n   origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n   agreed to in writing, Licensor provides the Work (and each\n   Contributor provides its Contributions) on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n   implied, including, without limitation, any warranties or conditions\n   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n   PARTICULAR PURPOSE. You are solely responsible for determining the\n   appropriateness of using or redistributing the Work and assume any\n   risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n   whether in tort (including negligence), contract, or otherwise,\n   unless required by applicable law (such as deliberate and grossly\n   negligent acts) or agreed to in writing, shall any Contributor be\n   liable to You for damages, including any direct, indirect, special,\n   incidental, or consequential damages of any character arising as a\n   result of this License or out of the use or inability to use the\n   Work (including but not limited to damages for loss of goodwill,\n   work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses), even if such Contributor\n   has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n   the Work or Derivative Works thereof, You may choose to offer,\n   and charge a fee for, acceptance of support, warranty, indemnity,\n   or other liability obligations and/or rights consistent with this\n   License. However, in accepting such obligations, You may act only\n   on Your own behalf and on Your sole responsibility, not on behalf\n   of any other Contributor, and only if You agree to indemnify,\n   defend, and hold each Contributor harmless for any liability\n   incurred by, or claims asserted against, such Contributor by reason\n   of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n   To apply the Apache License to your work, attach the following\n   boilerplate notice, with the fields enclosed by brackets \"[]\"\n   replaced with your own identifying information. (Don't include\n   the brackets!)  The text should be enclosed in the appropriate\n   comment syntax for the file format. We also recommend that a\n   file or class name and description of purpose be included on the\n   same \"printed page\" as the copyright notice for easier\n   identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttps://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "Copyright (c) 2018-2026 The rust-random Project Developers\nCopyright (c) 2014 The Rust Project Developers\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# getrandom: system's random number generator\n\n[![Build Status]][GitHub Actions]\n[![Crate]][crates.io]\n[![Documentation]][docs.rs]\n[![Dependency Status]][deps.rs]\n[![Downloads]][crates.io]\n[![License]][LICENSE-MIT]\n\n`getrandom` is a Rust library for retrieving random data from (operating) system sources.\n\nIt is assumed that the system always provides high-quality, cryptographically secure random\ndata, ideally backed by hardware entropy sources. This crate derives its name from\nthe Linux `getrandom` syscall but is cross-platform, roughly supporting the same set\nof platforms as Rust's `std` library.\n\nThis is a low-level API. Most users should prefer using a higher-level random-number\nlibrary like [`rand`].\n\n[`rand`]: https://crates.io/crates/rand\n\n## Examples\n\n```rust\nfn get_random_u128() -> Result<u128, getrandom::Error> {\n    let mut buf = [0u8; 16];\n    getrandom::fill(&mut buf)?;\n    Ok(u128::from_ne_bytes(buf))\n}\n```\n\n## Supported targets\n\n| Target             | Target Triple      | Implementation\n| ------------------ | ------------------ | --------------\n| Linux, Android     | `*‑linux‑*`        | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`\n| Windows 10+        | `*‑windows‑*`      | [`ProcessPrng`]\n| Windows 7, 8       | `*-win7‑windows‑*` | [`RtlGenRandom`]\n| macOS              | `*‑apple‑darwin`   | [`getentropy`][3]\n| iOS, tvOS, watchOS | `*‑apple‑{ios,tvos,watchos}` | [`CCRandomGenerateBytes`]\n| FreeBSD            | `*‑freebsd`        | [`getrandom`][5]\n| OpenBSD            | `*‑openbsd`        | [`getentropy`][7]\n| NetBSD             | `*‑netbsd`         | [`getrandom`][16] if available, otherwise [`kern.arandom`][8]\n| Dragonfly BSD      | `*‑dragonfly`      | [`getrandom`][9]\n| Solaris            | `*‑solaris`        | [`getrandom`][11] with `GRND_RANDOM`\n| illumos            | `*‑illumos`        | [`getrandom`][12]\n| Fuchsia OS         | `*‑fuchsia`        | [`cprng_draw`]\n| Redox              | `*‑redox`          | `/dev/urandom`\n| Haiku              | `*‑haiku`          | `/dev/urandom` (identical to `/dev/random`)\n| Hermit             | `*-hermit`         | [`sys_read_entropy`]\n| Hurd               | `*-hurd-*`         | [`getrandom`][17]\n| SGX                | `x86_64‑*‑sgx`     | [`RDRAND`]\n| VxWorks            | `*‑wrs‑vxworks‑*`  | `randABytes` after checking entropy pool initialization with `randSecure`\n| Emscripten         | `*‑emscripten`     | [`getentropy`][13]\n| WASI 0.1           | `wasm32‑wasip1`    | [`random_get`]\n| WASI 0.2           | `wasm32‑wasip2`    | [`get-random-u64`]\n| SOLID              | `*-kmc-solid_*`    | `SOLID_RNG_SampleRandomBytes`\n| Nintendo 3DS       | `*-nintendo-3ds`   | [`getrandom`][18]\n| ESP-IDF            | `*‑espidf`         | [`esp_fill_random`] WARNING: see \"Early Boot\" section below\n| PS Vita            | `*-vita-*`         | [`getentropy`][19]\n| QNX Neutrino       | `*‑nto-qnx*`       | [`/dev/urandom`][14] (identical to `/dev/random`)\n| AIX                | `*-ibm-aix`        | [`/dev/urandom`][15]\n| Cygwin             | `*-cygwin`         | [`getrandom`][20] (based on [`RtlGenRandom`])\n| Motor OS           | `x86_64-unknown-motor` | [`RDRAND`]\n\nPull Requests that add support for new targets to `getrandom` are always welcome.\n\n### WebAssembly support\n\nThis crate fully supports the [WASI] and [Emscripten] targets. However,\nthe `wasm32-unknown-unknown` target (i.e. the target used by `wasm-pack`)\nis not automatically supported since, from the target name alone, we cannot deduce\nwhich JavaScript interface should be used (or if JavaScript is available at all).\n\nWe do not include support for this target in the default configuration because our JS backend\n(supporting web browsers, web workers and Node.js v19 or later) requires [`wasm-bindgen`],\n**bloating `Cargo.lock`** and **potentially breaking builds** on non-web WASM platforms.\n\nTo enable `getrandom`'s functionality on `wasm32-unknown-unknown` using\n[`Crypto.getRandomValues`] via [`wasm-bindgen`], enable the `wasm_js` crate feature.\n\nWARNING: We strongly recommend against enabling this feature in libraries (except for tests)\nsince it is known to break non-Web WASM builds and further since the usage of `wasm-bindgen`\ncauses significant bloat to `Cargo.lock` (on all targets).\n\nThe only exception to this rule: if your crate already unconditionally depends on `wasm-bindgen`\nor `js-sys` on \"unknown\" WASM targets then it's acceptable to enable this feature unconditionally.\n\n### Opt-in backends\n\n`getrandom` also provides optional (opt-in) backends, which allow users to customize the source\nof randomness based on their specific needs:\n\n| Backend name        | Target               | Target Triple            | Implementation\n| ------------------- | -------------------- | ------------------------ | --------------\n| `linux_getrandom`   | Linux, Android       | `*‑linux‑*`              | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow).\n| `linux_raw`         | Linux, Android       | `*‑linux‑*`              | Same as `linux_getrandom`, but uses raw `asm!`-based syscalls instead of `libc`.\n| `rdrand`            | x86, x86-64          | `x86_64-*`, `i686-*`     | [`RDRAND`] instruction\n| `rndr`              | AArch64              | `aarch64-*`              | [`RNDR`] register\n| `efi_rng`           | UEFI                 | `*-unknown‑uefi`         | [`EFI_RNG_PROTOCOL`] with `EFI_RNG_ALGORITHM_RAW` (requires `std` and Nightly compiler)\n| `windows_legacy`    | Windows              | `*-windows-*`            | [`RtlGenRandom`]\n| `custom`            | All targets          | `*`                      | User-provided custom implementation (see [custom backend])\n| `unsupported`       | All targets          | `*`                      | Always returns `Err(Error::UNSUPPORTED)` (see [unsupported backend])\n| `extern_impl`       | All targets          | `*`                      | Externally-provided custom implementation (see [externally implemented interface])\n\nOpt-in backends can be enabled using the `getrandom_backend` configuration flag.\nThe flag can be set either by specifying the `rustflags` field in [`.cargo/config.toml`]:\n```toml\n# It's recommended to set the flag on a per-target basis:\n[target.'cfg(target_os = \"linux\")']\nrustflags = ['--cfg', 'getrandom_backend=\"linux_getrandom\"']\n```\n\nOr by using the `RUSTFLAGS` environment variable:\n\n```sh\nRUSTFLAGS='--cfg getrandom_backend=\"linux_getrandom\"' cargo build\n```\n\nEnabling an opt-in backend will replace the backend used by default. Doing this for\nan incorrect target (e.g. using `linux_getrandom` while compiling for a Windows target)\nwill result in a compilation error. Be extremely careful while using opt-in backends,\nas incorrect configuration may result in vulnerable applications or applications\nthat always panic.\n\nNote that using an opt-in backend in a library (e.g. for tests or benchmarks)\nWILL NOT have any effect on its downstream users.\n\n[`.cargo/config.toml`]: https://doc.rust-lang.org/cargo/reference/config.html\n\n### Raw Linux syscall support\n\nCurrently the `linux_raw` backend supports only targets with stabilized `asm!` macro,\ni.e. `arm`, `aarch64`, `loongarch64`, `riscv32`, `riscv64`, `s390x`, `x86`, and `x86_64`.\n\nNote that the raw syscall backend may be slower than backends based on `libc::getrandom`,\ne.g. it does not implement vDSO optimizations and on `x86` it uses the infamously slow\n`int 0x80` instruction to perform syscall.\n\n### Custom backend\n\nIf this crate does not support your target out of the box or you have to use\na non-default entropy source, then you can provide a custom implementation.\nYou need to enable the custom backend as described in the\n[opt-in backends][opt-in] section.\n\nNext, you need to define an `extern` function with the following signature:\n\n```rust\nuse getrandom::Error;\n\n#[unsafe(no_mangle)]\nunsafe extern \"Rust\" fn __getrandom_v03_custom(\n    dest: *mut u8,\n    len: usize,\n) -> Result<(), Error> {\n    todo!()\n}\n```\n\nThis function should, ideally, be defined in the root crate of your project,\ne.g. in your `main.rs`. This function MUST be defined only once for your\nproject, i.e. upstream library crates SHOULD NOT define it outside of\ntests and benchmarks. Improper configuration of this backend may result\nin linking errors.\n\nThe function accepts a pointer to a buffer that should be filled with random\ndata and its length in bytes. Note that the buffer MAY be uninitialized.\nOn success, the function should return `Ok(())` and fully fill the input buffer;\notherwise, it should return an error value.\n\nWhile wrapping functions which work with byte slices you should fully initialize\nthe buffer before passing it to the function:\n```rust\nuse getrandom::Error;\n\nfn my_entropy_source(buf: &mut [u8]) -> Result<(), getrandom::Error> {\n    // ...\n    Ok(())\n}\n\n#[unsafe(no_mangle)]\nunsafe extern \"Rust\" fn __getrandom_v03_custom(\n    dest: *mut u8,\n    len: usize,\n) -> Result<(), Error> {\n    let buf = unsafe {\n        // fill the buffer with zeros\n        core::ptr::write_bytes(dest, 0, len);\n        // create mutable byte slice\n        core::slice::from_raw_parts_mut(dest, len)\n    };\n    my_entropy_source(buf)\n}\n```\n\n### Externally Implemented Interface\n\nUsing the nightly-only feature [`extern_item_impls`] it is possible to provide\na custom backend for `getrandom`, even to override an existing first-party implementation.\nFirst, enable the `extern_impl` opt-in backend to allow usage of this nightly feature.\nThen, you may provide implementations for `fill_uninit`, `u32`, and/or `u64`\nwith an attribute macro from the `implementation` module.\n\n[`extern_item_impls`]: https://github.com/rust-lang/rust/issues/125418\n\n```rust\nuse core::mem::MaybeUninit;\n\n#[cfg(getrandom_backend = \"extern_impl\")]\n#[getrandom::implementation::fill_uninit]\nfn my_fill_uninit_implementation(\n    dest: &mut [MaybeUninit<u8>]\n) -> Result<(), getrandom::Error> {\n    // ...\n    Ok(())\n}\n```\n\nFor further details on what a suitable implementation for `fill_uninit` may look\nlike, see [custom backend].\n\n`getrandom` will provide a default implementation for `u32` and `u64`, but does\nnot currently provide a default for `fill_uninit`, even if one is normally\navailable for the current target. If no implementation is available,\na compilation error will be raised with instructions for how to provide\nan implementation.\n\n### Unsupported backend\n\nIn some rare scenarios, you might be compiling this crate for an unsupported\ntarget (e.g. `wasm32-unknown-unknown`), but this crate's functionality\nis not actually used by your code. If you are confident that `getrandom` is\nnot used in your project, but it gets pulled nevertheless by one of your\ndependencies, then you can enable the `unsupported` backend, which always\nreturns `Err(Error::UNSUPPORTED)`.\n\n### Platform Support\n\nThis crate generally supports the same operating system and platform versions\nthat the Rust standard library does. Additional targets may be supported using\nthe opt-in custom backend.\n\nThis means that as Rust drops support for old versions of operating systems\n(such as old Linux kernel versions, Android API levels, etc.) in stable releases,\n`getrandom` may create new patch releases that remove support for\noutdated platform versions.\n\n### `/dev/urandom` fallback on Linux and Android\n\nOn Linux targets, the `/dev/urandom` fallback is present only if either `target_env`\nis `musl`, or `target_arch` is one of the following: `aarch64`, `arm`, `powerpc`,\n`powerpc64`, `s390x`, `x86`, `x86_64`. Other supported targets [require][platform-support]\nkernel versions that support the `getrandom` system call, so the fallback is not needed.\n\nOn Android targets the fallback is present only for the following `target_arch`es:\n`aarch64`, `arm`, `x86`, `x86_64`. Other `target_arch`es (e.g. RISC-V) require\nsufficiently high API levels.\n\nThe fallback can be disabled by enabling the `linux_getrandom` opt-in backend.\nNote that doing so will bump minimum supported Linux kernel version to 3.17\nand Android API level to 23 (Marshmallow).\n\n### Early boot\n\nSometimes, early in the boot process, the OS has not collected enough\nentropy to securely seed its RNG. This is especially common on virtual\nmachines, where standard \"random\" events are hard to come by.\n\nSome operating system interfaces always block until the RNG is securely\nseeded. This can take anywhere from a few seconds to more than a minute.\nA few (Linux, NetBSD and Solaris) offer a choice between blocking and\ngetting an error; in these cases, we always choose to block.\n\nOn Linux (when the `getrandom` system call is not available), reading from\n`/dev/urandom` never blocks, even when the OS hasn't collected enough\nentropy yet. To avoid returning low-entropy bytes, we first poll\n`/dev/random` and only switch to `/dev/urandom` once this has succeeded.\n\nOn OpenBSD, this kind of entropy accounting isn't available, and on\nNetBSD, blocking on it is discouraged. On these platforms, nonblocking\ninterfaces are used, even when reliable entropy may not be available.\nOn the platforms where it is used, the reliability of entropy accounting\nitself isn't free from controversy. This library provides randomness\nsourced according to the platform's best practices, but each platform has\nits own limits on the grade of randomness it can promise in environments\nwith few sources of entropy.\n\nOn ESP-IDF, if `esp_fill_random` is used before enabling WiFi, BT, or the\nvoltage noise entropy source (SAR ADC), the Hardware RNG will only be seeded\nvia RC_FAST_CLK. This can occur during early boot unless\n`bootloader_random_enable()` is called. For more information see the\n[ESP-IDF RNG Docs][esp-idf-rng] or the\n[RNG section of the ESP32 Technical Reference Manual][esp-trng-docs].\n\n## Error handling\n\nWe always prioritize failure over returning known insecure \"random\" bytes.\nGenerally, on supported platforms, failure is highly unlikely, though not\nimpossible. If an error does occur, it is likely that it will occur\non every call to `getrandom`. Therefore, after the first successful call,\none can be reasonably confident that no errors will occur.\n\n## Panic handling\n\nWe strive to eliminate all potential panics from our backend implementations.\nIn other words, when compiled with optimizations enabled, the generated\nbinary code for `getrandom` functions should not contain any panic branches.\nEven if the platform misbehaves and returns an unexpected result,\nour code should correctly handle it and return an error, e.g.\n[`Error::UNEXPECTED`].\n\n## Sanitizer support\n\nIf your code uses [`fill_uninit`] and you enable\n[MemorySanitizer](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#memorysanitizer)\n(i.e. `-Zsanitizer=memory`), we will automatically handle unpoisoning\nof the destination buffer filled by `fill_uninit`.\n\nYou can run sanitizer tests for your crate dependent on `getrandom` like this:\n```sh\nRUSTFLAGS=\"-Zsanitizer=memory\" cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu\n```\n\n## Minimum Supported Rust Version\n\nThis crate requires Rust 1.85 or later.\n\nThe most reliable way to get an MSRV-respecting behavior is to set\n`CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS=fallback` when doing\n`cargo update -p getrandom`, like so:\n```sh\nCARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS=fallback cargo update -p getrandom\n```\n\n## License\n\nThe `getrandom` library is distributed under either of\n\n * [Apache License, Version 2.0][LICENSE-APACHE]\n * [MIT license][LICENSE-MIT]\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n\n[//]: # (badges)\n\n[GitHub Actions]: https://github.com/rust-random/getrandom/actions?query=branch:master\n[Build Status]: https://github.com/rust-random/getrandom/actions/workflows/tests.yml/badge.svg?branch=master\n[crates.io]: https://crates.io/crates/getrandom\n[Crate]: https://img.shields.io/crates/v/getrandom\n[docs.rs]: https://docs.rs/getrandom\n[Documentation]: https://docs.rs/getrandom/badge.svg\n[deps.rs]: https://deps.rs/repo/github/rust-random/getrandom\n[Dependency Status]: https://deps.rs/repo/github/rust-random/getrandom/status.svg\n[Downloads]: https://img.shields.io/crates/d/getrandom\n[License]: https://img.shields.io/crates/l/getrandom\n\n[//]: # (supported targets)\n\n[1]: https://manned.org/getrandom.2\n[2]: https://manned.org/urandom.4\n[3]: https://www.unix.com/man-page/mojave/2/getentropy/\n[4]: https://www.unix.com/man-page/mojave/4/urandom/\n[5]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable\n[7]: https://man.openbsd.org/getentropy.2\n[8]: https://man.netbsd.org/sysctl.7\n[9]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom\n[11]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html\n[12]: https://illumos.org/man/2/getrandom\n[13]: https://github.com/emscripten-core/emscripten/pull/12240\n[14]: https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/r/random.html\n[15]: https://www.ibm.com/docs/en/aix/7.3?topic=files-random-urandom-devices\n[16]: https://man.netbsd.org/getrandom.2\n[17]: https://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getrandom\n[18]: https://github.com/rust3ds/shim-3ds/commit/b01d2568836dea2a65d05d662f8e5f805c64389d\n[19]: https://github.com/vitasdk/newlib/blob/2d869fe47aaf02b8e52d04e9a2b79d5b210fd016/newlib/libc/sys/vita/getentropy.c\n[20]: https://github.com/cygwin/cygwin/blob/main/winsup/cygwin/libc/getentropy.cc\n\n[`ProcessPrng`]: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng\n[`RtlGenRandom`]: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom\n[`Crypto.getRandomValues`]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues\n[`RDRAND`]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide\n[`RNDR`]: https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/RNDR--Random-Number\n[`CCRandomGenerateBytes`]: https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonRandom.h.auto.html\n[`cprng_draw`]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw\n[`esp_fill_random`]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html#functions\n[esp-idf-rng]: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/random.html\n[esp-trng-docs]: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#rng\n[`EFI_RNG_PROTOCOL`]: https://uefi.org/specs/UEFI/2.10/37_Secure_Technologies.html#efi-rng-protocol\n[`random_get`]: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno\n[`get-random-u64`]: https://github.com/WebAssembly/WASI/blob/v0.2.1/wasip2/random/random.wit#L23-L28\n[configuration flags]: #configuration-flags\n[custom backend]: #custom-backend\n[unsupported backend]: #unsupported-backend\n[`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen\n[`module`]: https://rustwasm.github.io/wasm-bindgen/reference/attributes/on-js-imports/module.html\n[`sys_read_entropy`]: https://github.com/hermit-os/kernel/blob/315f58ff5efc81d9bf0618af85a59963ff55f8b1/src/syscalls/entropy.rs#L47-L55\n[platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html\n[WASI]: https://github.com/WebAssembly/WASI\n[Emscripten]: https://emscripten.org\n[opt-in]: #opt-in-backends\n[externally implemented interface]: #externally-implemented-interface\n\n[//]: # (licenses)\n\n[LICENSE-APACHE]: https://github.com/rust-random/getrandom/blob/master/LICENSE-APACHE\n[LICENSE-MIT]: https://github.com/rust-random/getrandom/blob/master/LICENSE-MIT\n\n[`Error::UNEXPECTED`]: https://docs.rs/getrandom/latest/getrandom/struct.Error.html#associatedconstant.UNEXPECTED\n[`fill_uninit`]: https://docs.rs/getrandom/latest/getrandom/fn.fill_uninit.html\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nSecurity updates are applied only to the latest release.\n\n## Reporting a Vulnerability\n\nIf you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.\n\nPlease disclose it at [security advisory](https://github.com/rust-random/getrandom/security/advisories/new).\n\nThis project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.\n"
  },
  {
    "path": "benches/buffer.rs",
    "content": "//! Basic benchmarks\n#![feature(test)]\nextern crate test;\n\nuse std::{\n    mem::{MaybeUninit, size_of},\n    slice,\n};\n\n// Call getrandom on a zero-initialized stack buffer\n#[inline(always)]\nfn bench_fill<const N: usize>() {\n    let mut buf = [0u8; N];\n    getrandom::fill(&mut buf).unwrap();\n    test::black_box(&buf[..]);\n}\n\n// Call fill_uninit on an uninitialized stack buffer\n#[inline(always)]\nfn bench_fill_uninit<const N: usize>() {\n    let mut uninit = [MaybeUninit::uninit(); N];\n    let buf: &[u8] = getrandom::fill_uninit(&mut uninit).unwrap();\n    test::black_box(buf);\n}\n\n#[bench]\nfn bench_u32(b: &mut test::Bencher) {\n    #[inline(never)]\n    fn inner() -> u32 {\n        getrandom::u32().unwrap()\n    }\n    b.bytes = 4;\n    b.iter(inner);\n}\n\n#[bench]\nfn bench_u32_via_fill(b: &mut test::Bencher) {\n    #[inline(never)]\n    fn inner() -> u32 {\n        let mut res = MaybeUninit::<u32>::uninit();\n        let dst: &mut [MaybeUninit<u8>] =\n            unsafe { slice::from_raw_parts_mut(res.as_mut_ptr().cast(), size_of::<u32>()) };\n        getrandom::fill_uninit(dst).unwrap();\n        unsafe { res.assume_init() }\n    }\n    b.bytes = 4;\n    b.iter(inner);\n}\n\n#[bench]\nfn bench_u64(b: &mut test::Bencher) {\n    #[inline(never)]\n    fn inner() -> u64 {\n        getrandom::u64().unwrap()\n    }\n    b.bytes = 8;\n    b.iter(inner);\n}\n\n#[bench]\nfn bench_u64_via_fill(b: &mut test::Bencher) {\n    #[inline(never)]\n    fn inner() -> u64 {\n        let mut res = MaybeUninit::<u64>::uninit();\n        let dst: &mut [MaybeUninit<u8>] =\n            unsafe { slice::from_raw_parts_mut(res.as_mut_ptr().cast(), size_of::<u64>()) };\n        getrandom::fill_uninit(dst).unwrap();\n        unsafe { res.assume_init() }\n    }\n    b.bytes = 8;\n    b.iter(inner);\n}\n\n// We benchmark using #[inline(never)] \"inner\" functions for two reasons:\n//  - Avoiding inlining reduces a source of variance when running benchmarks.\n//  - It is _much_ easier to get the assembly or IR for the inner loop.\n//\n// For example, using cargo-show-asm (https://github.com/pacak/cargo-show-asm),\n// we can get the assembly for a particular benchmark's inner loop by running:\n//   cargo asm --bench buffer --release buffer::p384::bench_getrandom::inner\nmacro_rules! bench {\n    ( $name:ident, $size:expr ) => {\n        mod $name {\n            #[bench]\n            fn bench_fill(b: &mut test::Bencher) {\n                #[inline(never)]\n                fn inner() {\n                    super::bench_fill::<{ $size }>()\n                }\n\n                b.bytes = $size as u64;\n                b.iter(inner);\n            }\n            #[bench]\n            fn bench_fill_uninit(b: &mut test::Bencher) {\n                #[inline(never)]\n                fn inner() {\n                    super::bench_fill_uninit::<{ $size }>()\n                }\n\n                b.bytes = $size as u64;\n                b.iter(inner);\n            }\n        }\n    };\n}\n\n// 16 bytes (128 bits) is the size of an 128-bit AES key/nonce.\nbench!(aes128, 128 / 8);\n\n// 32 bytes (256 bits) is the seed sized used for rand::thread_rng\n// and the `random` value in a ClientHello/ServerHello for TLS.\n// This is also the size of a 256-bit AES/HMAC/P-256/Curve25519 key\n// and/or nonce.\nbench!(p256, 256 / 8);\n\n// A P-384/HMAC-384 key and/or nonce.\nbench!(p384, 384 / 8);\n\n// Initializing larger buffers is not the primary use case of this library, as\n// this should normally be done by a userspace CSPRNG. However, we have a test\n// here to see the effects of a lower (amortized) syscall overhead.\nbench!(page, 4096);\n"
  },
  {
    "path": "build.rs",
    "content": "//! Build script for memory sanitization support\n\nfn main() {\n    // Automatically detect cfg(sanitize = \"memory\") even if cfg(sanitize) isn't\n    // supported. Build scripts get cfg() info, even if the cfg is unstable.\n    println!(\"cargo:rerun-if-changed=build.rs\");\n    let sanitizers = std::env::var(\"CARGO_CFG_SANITIZE\").unwrap_or_default();\n    if sanitizers.contains(\"memory\") {\n        println!(\"cargo:rustc-cfg=getrandom_msan\");\n    }\n}\n"
  },
  {
    "path": "custom_impl_test/Cargo.toml",
    "content": "[package]\nname = \"custom_impl_test\"\ndescription = \"Helper crate for testing custom implementations\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[workspace]\n\n[dependencies]\ngetrandom = { path = \"..\" }\n\n[lints.rust.unexpected_cfgs]\nlevel = \"warn\"\ncheck-cfg = [\n  'cfg(getrandom_backend, values(\"custom\", \"extern_impl\"))',\n]\n"
  },
  {
    "path": "custom_impl_test/src/lib.rs",
    "content": "use core::mem::MaybeUninit;\nuse getrandom::Error;\n\n/// Chosen by fair dice roll.\nconst SEED: u64 = 0x9095_810F_1B2B_E175;\n\nstruct Xoshiro128PlusPlus {\n    s: [u32; 4],\n}\n\nimpl Xoshiro128PlusPlus {\n    fn new(mut seed: u64) -> Self {\n        const PHI: u64 = 0x9e3779b97f4a7c15;\n        let mut s = [0u32; 4];\n        for val in s.iter_mut() {\n            seed = seed.wrapping_add(PHI);\n            let mut z = seed;\n            z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9);\n            z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb);\n            z = z ^ (z >> 31);\n            *val = z as u32;\n        }\n        Self { s }\n    }\n\n    fn next_u32(&mut self) -> u32 {\n        let res = self.s[0]\n            .wrapping_add(self.s[3])\n            .rotate_left(7)\n            .wrapping_add(self.s[0]);\n\n        let t = self.s[1] << 9;\n\n        self.s[2] ^= self.s[0];\n        self.s[3] ^= self.s[1];\n        self.s[1] ^= self.s[2];\n        self.s[0] ^= self.s[3];\n\n        self.s[2] ^= t;\n\n        self.s[3] = self.s[3].rotate_left(11);\n\n        res\n    }\n}\n\npub fn custom_impl(dst: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    let mut rng = Xoshiro128PlusPlus::new(SEED);\n\n    let mut chunks = dst.chunks_exact_mut(4);\n    for chunk in &mut chunks {\n        let val = rng.next_u32();\n        let dst_ptr = chunk.as_mut_ptr().cast::<u32>();\n        unsafe { core::ptr::write_unaligned(dst_ptr, val) };\n    }\n    let rem = chunks.into_remainder();\n    if !rem.is_empty() {\n        let val = rng.next_u32();\n        let src_ptr = &val as *const u32 as *const MaybeUninit<u8>;\n        assert!(rem.len() <= 4);\n        unsafe { core::ptr::copy(src_ptr, rem.as_mut_ptr(), rem.len()) };\n    }\n    Ok(())\n}\n\n#[cfg(getrandom_backend = \"custom\")]\n#[unsafe(no_mangle)]\nunsafe extern \"Rust\" fn __getrandom_v03_custom(dst_ptr: *mut u8, len: usize) -> Result<(), Error> {\n    let dst = unsafe { core::slice::from_raw_parts_mut(dst_ptr.cast(), len) };\n    custom_impl(dst)\n}\n\n#[cfg(getrandom_backend = \"extern_impl\")]\n#[getrandom::implementation::fill_uninit]\nfn my_fill_uninit_implementation(dst: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    custom_impl(dst)\n}\n\n#[test]\nfn test_custom_fill() {\n    let mut buf1 = [0u8; 256];\n    getrandom::fill(&mut buf1).unwrap();\n\n    let mut buf2 = [0u8; 256];\n    custom_impl(unsafe { core::slice::from_raw_parts_mut(buf2.as_mut_ptr().cast(), buf2.len()) })\n        .unwrap();\n\n    assert_eq!(buf1, buf2);\n}\n\n#[test]\nfn test_custom_u32() {\n    let res = getrandom::u32().unwrap();\n    assert_eq!(res, 0xEAD5_840A);\n}\n\n#[test]\nfn test_custom_u64() {\n    let res = getrandom::u64().unwrap();\n    assert_eq!(res, 0xA856_FCC4_EAD5_840A);\n}\n"
  },
  {
    "path": "nopanic_check/Cargo.toml",
    "content": "[package]\nname = \"nopanic_check\"\ndescription = \"Helper crate for checking that getrandom implementation does not contain potential panics\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[workspace]\n\n[lib]\nname = \"getrandom_wrapper\"\ncrate-type = [\"cdylib\"]\n\n[dependencies]\ngetrandom = { path = \"..\" }\n\n[profile.release]\npanic = \"abort\"\nstrip = true\nlto = \"fat\"\n\n[lints.rust.unexpected_cfgs]\nlevel = \"warn\"\ncheck-cfg = [\n  'cfg(getrandom_backend, values(\"custom\"))',\n]\n"
  },
  {
    "path": "nopanic_check/src/lib.rs",
    "content": "// WASI preview 2 requires enabled std\n#![cfg_attr(not(all(target_arch = \"wasm32\", target_env = \"p2\")), no_std)]\n\n#[cfg(not(any(test, all(target_arch = \"wasm32\", target_env = \"p2\"))))]\n#[panic_handler]\nfn panic(_info: &core::panic::PanicInfo) -> ! {\n    unsafe extern \"C\" {\n        fn panic_nonexistent() -> !;\n    }\n    unsafe { panic_nonexistent() }\n}\n\n#[unsafe(no_mangle)]\npub unsafe extern \"C\" fn getrandom_wrapper(buf_ptr: *mut u8, buf_len: usize) -> u32 {\n    let buf = unsafe { core::slice::from_raw_parts_mut(buf_ptr.cast(), buf_len) };\n    let res = getrandom::fill_uninit(buf).map(|_| ());\n    unsafe { core::mem::transmute(res) }\n}\n\n#[cfg(getrandom_backend = \"custom\")]\n#[unsafe(no_mangle)]\nunsafe extern \"Rust\" fn __getrandom_v03_custom(\n    dest: *mut u8,\n    len: usize,\n) -> Result<(), getrandom::Error> {\n    for i in 0..len {\n        unsafe { core::ptr::write(dest.add(i), i as u8) };\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "src/backends/apple_other.rs",
    "content": "//! Implementation for iOS, tvOS, and watchOS where `getentropy` is unavailable.\nuse crate::Error;\nuse core::{ffi::c_void, mem::MaybeUninit};\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    let dst_ptr = dest.as_mut_ptr().cast::<c_void>();\n    let ret = unsafe { libc::CCRandomGenerateBytes(dst_ptr, dest.len()) };\n    if ret == libc::kCCSuccess {\n        Ok(())\n    } else {\n        Err(Error::IOS_RANDOM_GEN)\n    }\n}\n\nimpl Error {\n    /// Call to `CCRandomGenerateBytes` failed.\n    pub(crate) const IOS_RANDOM_GEN: Error = Self::new_internal(10);\n}\n"
  },
  {
    "path": "src/backends/custom.rs",
    "content": "//! An implementation which calls out to an externally defined function.\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    unsafe extern \"Rust\" {\n        fn __getrandom_v03_custom(dest: *mut u8, len: usize) -> Result<(), Error>;\n    }\n    unsafe { __getrandom_v03_custom(dest.as_mut_ptr().cast(), dest.len()) }\n}\n"
  },
  {
    "path": "src/backends/efi_rng.rs",
    "content": "//! Implementation for UEFI using EFI_RNG_PROTOCOL\nuse crate::Error;\nuse core::{\n    mem::MaybeUninit,\n    ptr::{self, NonNull},\n};\nuse r_efi::{\n    efi::{BootServices, Handle},\n    protocols::rng,\n};\n\nextern crate std;\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[cfg(not(target_os = \"uefi\"))]\ncompile_error!(\"`efi_rng` backend can be enabled only for UEFI targets!\");\n\n#[cold]\n#[inline(never)]\nfn init() -> Result<NonNull<rng::Protocol>, Error> {\n    const HANDLE_SIZE: usize = size_of::<Handle>();\n\n    let boot_services = std::os::uefi::env::boot_services()\n        .ok_or(Error::BOOT_SERVICES_UNAVAILABLE)?\n        .cast::<BootServices>();\n\n    let mut handles = [ptr::null_mut(); 16];\n    // `locate_handle` operates with length in bytes\n    let mut buf_size = handles.len() * HANDLE_SIZE;\n    let mut guid = rng::PROTOCOL_GUID;\n    let ret = unsafe {\n        ((*boot_services.as_ptr()).locate_handle)(\n            r_efi::efi::BY_PROTOCOL,\n            &mut guid,\n            ptr::null_mut(),\n            &mut buf_size,\n            handles.as_mut_ptr(),\n        )\n    };\n\n    if ret.is_error() {\n        return Err(Error::from_uefi_code(ret.as_usize()));\n    }\n\n    let handles_len = buf_size / HANDLE_SIZE;\n    let handles = handles.get(..handles_len).ok_or(Error::UNEXPECTED)?;\n\n    let system_handle = std::os::uefi::env::image_handle();\n    for &handle in handles {\n        let mut protocol: MaybeUninit<*mut rng::Protocol> = MaybeUninit::uninit();\n\n        let mut protocol_guid = rng::PROTOCOL_GUID;\n        let ret = unsafe {\n            ((*boot_services.as_ptr()).open_protocol)(\n                handle,\n                &mut protocol_guid,\n                protocol.as_mut_ptr().cast(),\n                system_handle.as_ptr(),\n                ptr::null_mut(),\n                r_efi::system::OPEN_PROTOCOL_GET_PROTOCOL,\n            )\n        };\n\n        let protocol = if ret.is_error() {\n            continue;\n        } else {\n            let protocol = unsafe { protocol.assume_init() };\n            NonNull::new(protocol).ok_or(Error::UNEXPECTED)?\n        };\n\n        // Try to use the acquired protocol handle\n        let mut buf = [0u8; 8];\n        let mut alg_guid = rng::ALGORITHM_RAW;\n        let ret = unsafe {\n            ((*protocol.as_ptr()).get_rng)(\n                protocol.as_ptr(),\n                &mut alg_guid,\n                buf.len(),\n                buf.as_mut_ptr(),\n            )\n        };\n\n        if ret.is_error() {\n            continue;\n        }\n\n        return Ok(protocol);\n    }\n    Err(Error::NO_RNG_HANDLE)\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    #[path = \"../utils/lazy_ptr.rs\"]\n    mod lazy;\n\n    static RNG_PROTOCOL: lazy::LazyPtr<rng::Protocol> = lazy::LazyPtr::new();\n\n    let protocol = RNG_PROTOCOL.try_unsync_init(init)?;\n\n    let mut alg_guid = rng::ALGORITHM_RAW;\n    let ret = unsafe {\n        ((*protocol.as_ptr()).get_rng)(\n            protocol.as_ptr(),\n            &mut alg_guid,\n            dest.len(),\n            dest.as_mut_ptr().cast::<u8>(),\n        )\n    };\n\n    if ret.is_error() {\n        Err(Error::from_uefi_code(ret.as_usize()))\n    } else {\n        Ok(())\n    }\n}\n\nimpl Error {\n    pub(crate) const BOOT_SERVICES_UNAVAILABLE: Error = Self::new_internal(10);\n    pub(crate) const NO_RNG_HANDLE: Error = Self::new_internal(11);\n}\n"
  },
  {
    "path": "src/backends/esp_idf.rs",
    "content": "//! Implementation for ESP-IDF\nuse crate::Error;\nuse core::{ffi::c_void, mem::MaybeUninit};\n\npub use crate::util::{inner_u32, inner_u64};\n\nunsafe extern \"C\" {\n    fn esp_fill_random(buf: *mut c_void, len: usize) -> u32;\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    // Not that NOT enabling WiFi, BT, or the voltage noise entropy source (via `bootloader_random_enable`)\n    // will cause ESP-IDF to return pseudo-random numbers based on the voltage noise entropy, after the initial boot process:\n    // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html\n    //\n    // However tracking if some of these entropy sources is enabled is way too difficult to implement here\n    unsafe { esp_fill_random(dest.as_mut_ptr().cast(), dest.len()) };\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/backends/extern_impl.rs",
    "content": "//! An implementation which calls out to an externally defined function.\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\n/// Declares this function as an external implementation of [`fill_uninit`](crate::fill_uninit).\n#[eii(fill_uninit)]\npub(crate) fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>;\n\n/// Declares this function as an external implementation of [`u32`](crate::u32).\n#[eii(u32)]\npub(crate) fn inner_u32() -> Result<u32, crate::Error> {\n    crate::util::inner_u32()\n}\n\n/// Declares this function as an external implementation of [`u64`](crate::u64).\n#[eii(u64)]\npub(crate) fn inner_u64() -> Result<u64, crate::Error> {\n    crate::util::inner_u64()\n}\n"
  },
  {
    "path": "src/backends/fuchsia.rs",
    "content": "//! Implementation for Fuchsia Zircon\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[link(name = \"zircon\")]\nunsafe extern \"C\" {\n    fn zx_cprng_draw(buffer: *mut u8, length: usize);\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    unsafe { zx_cprng_draw(dest.as_mut_ptr().cast::<u8>(), dest.len()) }\n    Ok(())\n}\n"
  },
  {
    "path": "src/backends/getentropy.rs",
    "content": "//! Implementation using getentropy(2)\n//!\n//! When porting to a new target, ensure that its implementation follows the\n//! POSIX conventions from\n//! <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getentropy.html>.\n//!\n//! Available since:\n//!   - macOS 10.12\n//!   - OpenBSD 5.6\n//!   - Emscripten 2.0.5\n//!   - vita newlib since Dec 2021\n//!\n//! For these targets, we use getentropy(2) because getrandom(2) doesn't exist.\nuse crate::Error;\nuse core::{ffi::c_void, mem::MaybeUninit};\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[path = \"../utils/get_errno.rs\"]\nmod utils;\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    // https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/limits.h.html\n    // says `GETENTROPY_MAX` is at least 256.\n    const GETENTROPY_MAX: usize = 256;\n\n    for chunk in dest.chunks_mut(GETENTROPY_MAX) {\n        let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::<c_void>(), chunk.len()) };\n        match ret {\n            0 => continue,\n            -1 => return Err(Error::from_errno(utils::get_errno())),\n            _ => return Err(Error::UNEXPECTED),\n        }\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "src/backends/getrandom.rs",
    "content": "//! Implementation using getrandom(2).\n//!\n//! Available since:\n//!   - Linux Kernel 3.17, Glibc 2.25, Musl 1.1.20\n//!   - Android API level 23 (Marshmallow)\n//!   - NetBSD 10.0\n//!   - FreeBSD 12.0\n//!   - illumos since Dec 2018\n//!   - DragonFly 5.7\n//!   - Hurd Glibc 2.31\n//!   - shim-3ds since Feb 2022\n//!\n//! For these platforms, we always use the default pool and never set the\n//! GRND_RANDOM flag to use the /dev/random pool. On Linux/Android/Hurd, using\n//! GRND_RANDOM is not recommended. On NetBSD/FreeBSD/Dragonfly/3ds, it does\n//! nothing. On illumos, the default pool is used to implement getentropy(2),\n//! so we assume it is acceptable here.\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[path = \"../utils/sys_fill_exact.rs\"]\nmod utils;\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    utils::sys_fill_exact(dest, |buf| unsafe {\n        libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0)\n    })\n}\n"
  },
  {
    "path": "src/backends/hermit.rs",
    "content": "//! Implementation for Hermit\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\nunsafe extern \"C\" {\n    fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize;\n    // Note that `sys_secure_rand32/64` are implemented using `sys_read_entropy`:\n    // https://github.com/hermit-os/kernel/blob/430da84/src/syscalls/entropy.rs#L62-L104\n    // But this may change in future and can depend on compilation target,\n    // so to future-proof we use these \"syscalls\".\n    fn sys_secure_rand32(value: *mut u32) -> i32;\n    fn sys_secure_rand64(value: *mut u64) -> i32;\n}\n\n#[inline]\npub fn inner_u32() -> Result<u32, Error> {\n    let mut res = MaybeUninit::uninit();\n    let ret = unsafe { sys_secure_rand32(res.as_mut_ptr()) };\n    match ret {\n        0 => Ok(unsafe { res.assume_init() }),\n        -1 => Err(Error::UNSUPPORTED),\n        _ => Err(Error::UNEXPECTED),\n    }\n}\n\n#[inline]\npub fn inner_u64() -> Result<u64, Error> {\n    let mut res = MaybeUninit::uninit();\n    let ret = unsafe { sys_secure_rand64(res.as_mut_ptr()) };\n    match ret {\n        0 => Ok(unsafe { res.assume_init() }),\n        -1 => Err(Error::UNSUPPORTED),\n        _ => Err(Error::UNEXPECTED),\n    }\n}\n\n#[inline]\npub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    while !dest.is_empty() {\n        let res = unsafe { sys_read_entropy(dest.as_mut_ptr().cast::<u8>(), dest.len(), 0) };\n        match res {\n            res if res > 0 => {\n                let len = usize::try_from(res).map_err(|_| Error::UNEXPECTED)?;\n                dest = dest.get_mut(len..).ok_or(Error::UNEXPECTED)?;\n            }\n            code => {\n                let code = i32::try_from(code).map_err(|_| Error::UNEXPECTED)?;\n                return Err(Error::from_neg_error_code(code));\n            }\n        }\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "src/backends/linux_android_with_fallback.rs",
    "content": "//! Implementation for Linux / Android with `/dev/urandom` fallback\nuse super::use_file;\nuse crate::Error;\nuse core::{\n    ffi::c_void,\n    mem::{MaybeUninit, transmute},\n    ptr::{self, NonNull},\n};\nuse use_file::utils;\n\npub use crate::util::{inner_u32, inner_u64};\n\ntype GetRandomFn = unsafe extern \"C\" fn(*mut c_void, libc::size_t, libc::c_uint) -> libc::ssize_t;\n\n/// Sentinel value which indicates that `libc::getrandom` either not available,\n/// or not supported by kernel.\nconst NOT_AVAILABLE: NonNull<c_void> = unsafe { NonNull::new_unchecked(usize::MAX as *mut c_void) };\n\n#[cold]\n#[inline(never)]\nfn init() -> NonNull<c_void> {\n    // Use static linking to `libc::getrandom` on MUSL targets and `dlsym` everywhere else\n    #[cfg(not(target_env = \"musl\"))]\n    let raw_ptr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c\"getrandom\".as_ptr()) };\n    #[cfg(target_env = \"musl\")]\n    let raw_ptr = {\n        let fptr: GetRandomFn = libc::getrandom;\n        unsafe { transmute::<GetRandomFn, *mut c_void>(fptr) }\n    };\n\n    let res_ptr = match NonNull::new(raw_ptr) {\n        Some(fptr) => {\n            let getrandom_fn = unsafe { transmute::<*mut c_void, GetRandomFn>(fptr.as_ptr()) };\n            // Check that `getrandom` syscall is supported by kernel\n            let res = unsafe { getrandom_fn(ptr::dangling_mut(), 0, 0) };\n            if cfg!(getrandom_test_linux_fallback) {\n                NOT_AVAILABLE\n            } else if res.is_negative() {\n                match utils::get_errno() {\n                    libc::ENOSYS => NOT_AVAILABLE, // No kernel support\n                    // The fallback on EPERM is intentionally not done on Android since this workaround\n                    // seems to be needed only for specific Linux-based products that aren't based\n                    // on Android. See https://github.com/rust-random/getrandom/issues/229.\n                    #[cfg(target_os = \"linux\")]\n                    libc::EPERM => NOT_AVAILABLE, // Blocked by seccomp\n                    _ => fptr,\n                }\n            } else {\n                fptr\n            }\n        }\n        None => NOT_AVAILABLE,\n    };\n\n    #[cfg(getrandom_test_linux_without_fallback)]\n    if res_ptr == NOT_AVAILABLE {\n        panic!(\"Fallback is triggered with enabled `getrandom_test_linux_without_fallback`\")\n    }\n\n    res_ptr\n}\n\n// Prevent inlining of the fallback implementation\n#[inline(never)]\nfn use_file_fallback(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    use_file::fill_inner(dest)\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    #[path = \"../utils/lazy_ptr.rs\"]\n    mod lazy;\n\n    static GETRANDOM_FN: lazy::LazyPtr<c_void> = lazy::LazyPtr::new();\n    let fptr = GETRANDOM_FN.unsync_init(init);\n\n    if fptr == NOT_AVAILABLE {\n        use_file_fallback(dest)\n    } else {\n        // note: `transmute` is currently the only way to convert a pointer into a function reference\n        let getrandom_fn = unsafe { transmute::<*mut c_void, GetRandomFn>(fptr.as_ptr()) };\n        utils::sys_fill_exact(dest, |buf| unsafe {\n            getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0)\n        })\n    }\n}\n"
  },
  {
    "path": "src/backends/linux_raw.rs",
    "content": "//! Implementation for Linux / Android using `asm!`-based syscalls.\npub use crate::util::{inner_u32, inner_u64};\nuse crate::{Error, MaybeUninit};\n\n#[cfg(not(any(target_os = \"android\", target_os = \"linux\")))]\ncompile_error!(\"`linux_raw` backend can be enabled only for Linux/Android targets!\");\n\n#[path = \"../utils/sanitizer.rs\"]\nmod utils;\n\n#[allow(non_upper_case_globals)]\nunsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize {\n    let r0;\n\n    // Based on `rustix` and `linux-raw-sys` code.\n    cfg_if! {\n        if #[cfg(all(\n            target_arch = \"arm\",\n            any(target_abi = \"eabi\", target_abi = \"eabihf\"),\n        ))] {\n            const __NR_getrandom: u32 = 384;\n            // In thumb-mode, r7 is the frame pointer and is not permitted to be used in\n            // an inline asm operand, so we have to use a different register and copy it\n            // into r7 inside the inline asm.\n            // Theoretically, we could detect thumb mode in the build script, but several\n            // register moves are cheap enough compared to the syscall cost, so we do not\n            // bother with it.\n            unsafe {\n                core::arch::asm!(\n                    \"mov {tmp}, r7\",\n                    \"mov r7, {nr}\",\n                    \"svc 0\",\n                    \"mov r7, {tmp}\",\n                    tmp = out(reg) _,\n                    nr = const __NR_getrandom,\n                    inlateout(\"r0\") buf => r0,\n                    in(\"r1\") buflen,\n                    in(\"r2\") flags,\n                    options(nostack, preserves_flags)\n                );\n            }\n        } else if #[cfg(all(\n            target_arch = \"aarch64\",\n            any(target_abi = \"\", target_abi = \"ilp32\"),\n        ))] {\n            // According to the ILP32 patch for the kernel that hasn't yet\n            // been merged into the mainline, \"AARCH64/ILP32 ABI uses standard\n            // syscall table [...] with the exceptions listed below,\" where\n            // getrandom is not mentioned as an exception.\n            const __NR_getrandom: u32 = 278;\n            unsafe {\n                core::arch::asm!(\n                    \"svc 0\",\n                    in(\"x8\") __NR_getrandom,\n                    inlateout(\"x0\") buf => r0,\n                    in(\"x1\") buflen,\n                    in(\"x2\") flags,\n                    options(nostack, preserves_flags)\n                );\n            }\n        } else if #[cfg(all(\n            target_arch = \"loongarch64\",\n            any(target_abi = \"\", target_abi = \"ilp32\"),\n        ))] {\n            const __NR_getrandom: u32 = 278;\n            unsafe {\n                core::arch::asm!(\n                    \"syscall 0\",\n                    in(\"$a7\") __NR_getrandom,\n                    inlateout(\"$a0\") buf => r0,\n                    in(\"$a1\") buflen,\n                    in(\"$a2\") flags,\n                    options(nostack, preserves_flags)\n                );\n            }\n        } else if #[cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))] {\n            const __NR_getrandom: u32 = 278;\n            unsafe {\n                core::arch::asm!(\n                    \"ecall\",\n                    in(\"a7\") __NR_getrandom,\n                    inlateout(\"a0\") buf => r0,\n                    in(\"a1\") buflen,\n                    in(\"a2\") flags,\n                    options(nostack, preserves_flags)\n                );\n            }\n        } else if #[cfg(target_arch = \"s390x\")] {\n            const __NR_getrandom: u32 = 349;\n            unsafe {\n                core::arch::asm!(\n                    \"svc 0\",\n                    in(\"r1\") __NR_getrandom,\n                    inlateout(\"r2\") buf => r0,\n                    in(\"r3\") buflen,\n                    in(\"r4\") flags,\n                    options(nostack, preserves_flags)\n                );\n            }\n        } else if #[cfg(target_arch = \"x86\")] {\n            const __NR_getrandom: u32 = 355;\n            // `int 0x80` is famously slow, but implementing vDSO is too complex\n            // and `sysenter`/`syscall` have their own portability issues,\n            // so we use the simple \"legacy\" way of doing syscalls.\n            unsafe {\n                core::arch::asm!(\n                    \"int $$0x80\",\n                    in(\"eax\") __NR_getrandom,\n                    in(\"ebx\") buf,\n                    in(\"ecx\") buflen,\n                    in(\"edx\") flags,\n                    lateout(\"eax\") r0,\n                    options(nostack, preserves_flags)\n                );\n            }\n        } else if #[cfg(all(\n            target_arch = \"x86_64\",\n            any(target_abi = \"\", target_abi = \"x32\"),\n        ))] {\n            const __X32_SYSCALL_BIT: u32 = 0x40000000;\n            const OFFSET: u32 = if cfg!(target_pointer_width = \"32\") { __X32_SYSCALL_BIT } else { 0 };\n            const __NR_getrandom: u32 = OFFSET + 318;\n\n            unsafe {\n                core::arch::asm!(\n                    \"syscall\",\n                    in(\"rax\") __NR_getrandom,\n                    in(\"rdi\") buf,\n                    in(\"rsi\") buflen,\n                    in(\"rdx\") flags,\n                    lateout(\"rax\") r0,\n                    lateout(\"rcx\") _,\n                    lateout(\"r11\") _,\n                    options(nostack, preserves_flags)\n                );\n            }\n        } else {\n            compile_error!(\"`linux_raw` backend does not support this target arch\");\n        }\n    }\n\n    r0\n}\n\n#[inline]\npub fn fill_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    // Value of this error code is stable across all target arches.\n    const EINTR: isize = -4;\n\n    loop {\n        let ret = unsafe { getrandom_syscall(dest.as_mut_ptr().cast(), dest.len(), 0) };\n        match usize::try_from(ret) {\n            Ok(0) => return Err(Error::UNEXPECTED),\n            Ok(len) => {\n                let (l, r) = dest.split_at_mut_checked(len).ok_or(Error::UNEXPECTED)?;\n                unsafe { utils::unpoison(l) };\n                dest = r;\n                if dest.is_empty() {\n                    return Ok(());\n                }\n            }\n            Err(_) if ret == EINTR => continue,\n            Err(_) => {\n                let code = i32::try_from(ret).map_err(|_| Error::UNEXPECTED)?;\n                return Err(Error::from_neg_error_code(code));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/backends/netbsd.rs",
    "content": "//! Implementation for NetBSD\n//!\n//! `getrandom(2)` was introduced in NetBSD 10. To support older versions we\n//! implement our own weak linkage to it, and provide a fallback based on the\n//! KERN_ARND sysctl.\nuse crate::Error;\nuse core::{\n    cmp,\n    ffi::c_void,\n    mem::{self, MaybeUninit},\n    ptr::{self, NonNull},\n};\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[path = \"../utils/sys_fill_exact.rs\"]\nmod utils;\n\nunsafe extern \"C\" fn polyfill_using_kern_arand(\n    buf: *mut c_void,\n    buflen: libc::size_t,\n    flags: libc::c_uint,\n) -> libc::ssize_t {\n    debug_assert_eq!(flags, 0);\n\n    const MIB_LEN: libc::c_uint = 2;\n    static MIB: [libc::c_int; MIB_LEN as usize] = [libc::CTL_KERN, libc::KERN_ARND];\n\n    // NetBSD will only return up to 256 bytes at a time, and\n    // older NetBSD kernels will fail on longer buffers.\n    let mut len = cmp::min(buflen, 256);\n    let ret = unsafe { libc::sysctl(MIB.as_ptr(), MIB_LEN, buf, &mut len, ptr::null(), 0) };\n\n    match ret {\n        0 if len <= 256 => libc::ssize_t::try_from(len).expect(\"len is in the range of 0..=256\"),\n        -1 => -1,\n        // Zero return result will be converted into `Error::UNEXPECTED` by `sys_fill_exact`\n        _ => 0,\n    }\n}\n\ntype GetRandomFn = unsafe extern \"C\" fn(*mut c_void, libc::size_t, libc::c_uint) -> libc::ssize_t;\n\n#[cold]\n#[inline(never)]\nfn init() -> NonNull<c_void> {\n    let ptr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c\"getrandom\".as_ptr()) };\n    if !cfg!(getrandom_test_netbsd_fallback) {\n        if let Some(ptr) = NonNull::new(ptr) {\n            return ptr;\n        }\n    }\n    // Verify `polyfill_using_kern_arand` has the right signature.\n    const POLYFILL: GetRandomFn = polyfill_using_kern_arand;\n    unsafe { NonNull::new_unchecked(POLYFILL as *mut c_void) }\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    #[path = \"../utils/lazy_ptr.rs\"]\n    mod lazy;\n\n    static GETRANDOM_FN: lazy::LazyPtr<c_void> = lazy::LazyPtr::new();\n\n    let fptr = GETRANDOM_FN.unsync_init(init);\n    let fptr = unsafe { mem::transmute::<*mut c_void, GetRandomFn>(fptr.as_ptr()) };\n    utils::sys_fill_exact(dest, |buf| unsafe {\n        fptr(buf.as_mut_ptr().cast::<c_void>(), buf.len(), 0)\n    })\n}\n"
  },
  {
    "path": "src/backends/rdrand.rs",
    "content": "//! RDRAND backend for x86(-64) targets\nuse crate::{Error, util::slice_as_uninit};\nuse core::mem::{MaybeUninit, size_of};\n\n#[cfg(not(any(target_arch = \"x86_64\", target_arch = \"x86\")))]\ncompile_error!(\"`rdrand` backend can be enabled only for x86 and x86-64 targets!\");\n\ncfg_if! {\n    if #[cfg(target_arch = \"x86_64\")] {\n        use core::arch::x86_64 as arch;\n        use arch::_rdrand64_step as rdrand_step;\n        type Word = u64;\n    } else if #[cfg(target_arch = \"x86\")] {\n        use core::arch::x86 as arch;\n        use arch::_rdrand32_step as rdrand_step;\n        type Word = u32;\n    }\n}\n\n// Recommendation from \"Intel® Digital Random Number Generator (DRNG) Software\n// Implementation Guide\" - Section 5.2.1 and \"Intel® 64 and IA-32 Architectures\n// Software Developer’s Manual\" - Volume 1 - Section 7.3.17.1.\nconst RETRY_LIMIT: usize = 10;\n\n#[target_feature(enable = \"rdrand\")]\nfn rdrand() -> Option<Word> {\n    for _ in 0..RETRY_LIMIT {\n        let mut val = 0;\n        // SAFETY: this function is safe to call from a `[target_feature(enable\n        // = \"rdrand\")]` context (it itself is annotated with\n        // `target_feature(enable = \"rdrand\")`) but was marked unsafe until\n        // https://github.com/rust-lang/stdarch/commit/59864cd which was pulled\n        // in via https://github.com/rust-lang/rust/commit/f2eb88b which is\n        // expected to be included in 1.93.0. Since our MSRV is 1.85, we need to\n        // use unsafe here and suppress the lint.\n        //\n        // TODO(MSRV 1.93): remove allow(unused_unsafe) and the unsafe block.\n        #[allow(unused_unsafe)]\n        if unsafe { rdrand_step(&mut val) } == 1 {\n            return Some(val);\n        }\n    }\n    None\n}\n\n// \"rdrand\" target feature requires \"+rdrand\" flag, see https://github.com/rust-lang/rust/issues/49653.\n#[cfg(all(target_env = \"sgx\", not(target_feature = \"rdrand\")))]\ncompile_error!(\n    \"SGX targets require 'rdrand' target feature. Enable by using -C target-feature=+rdrand.\"\n);\n\n// Run a small self-test to make sure we aren't repeating values\n// Adapted from Linux's test in arch/x86/kernel/cpu/rdrand.c\n// Fails with probability < 2^(-90) on 32-bit systems\n#[target_feature(enable = \"rdrand\")]\nfn self_test() -> bool {\n    // On AMD, RDRAND returns 0xFF...FF on failure, count it as a collision.\n    let mut prev = Word::MAX;\n    let mut fails = 0;\n    for _ in 0..8 {\n        match rdrand() {\n            Some(val) if val == prev => fails += 1,\n            Some(val) => prev = val,\n            None => return false,\n        };\n    }\n    fails <= 2\n}\n\n#[cold]\n#[inline(never)]\nfn init() -> bool {\n    #[cfg(not(target_feature = \"rdrand\"))]\n    {\n        // SAFETY: All Rust x86 targets are new enough to have CPUID, and we\n        // check that leaf 1 is supported before using it.\n        //\n        // TODO(MSRV 1.94): remove allow(unused_unsafe) and the unsafe blocks for `__cpuid`.\n        #[allow(unused_unsafe)]\n        let cpuid0 = unsafe { arch::__cpuid(0) };\n        if cpuid0.eax < 1 {\n            return false;\n        }\n        #[allow(unused_unsafe)]\n        let cpuid1 = unsafe { arch::__cpuid(1) };\n\n        let vendor_id = [\n            cpuid0.ebx.to_le_bytes(),\n            cpuid0.edx.to_le_bytes(),\n            cpuid0.ecx.to_le_bytes(),\n        ];\n        if vendor_id == [*b\"Auth\", *b\"enti\", *b\"cAMD\"] {\n            let mut family = (cpuid1.eax >> 8) & 0xF;\n            if family == 0xF {\n                family += (cpuid1.eax >> 20) & 0xFF;\n            }\n            // AMD CPUs families before 17h (Zen) sometimes fail to set CF when\n            // RDRAND fails after suspend. Don't use RDRAND on those families.\n            // See https://bugzilla.redhat.com/show_bug.cgi?id=1150286\n            if family < 0x17 {\n                return false;\n            }\n        }\n\n        const RDRAND_FLAG: u32 = 1 << 30;\n        if cpuid1.ecx & RDRAND_FLAG == 0 {\n            return false;\n        }\n    }\n\n    // SAFETY: We have already checked that rdrand is available.\n    unsafe { self_test() }\n}\n\nfn is_rdrand_good() -> bool {\n    #[path = \"../utils/lazy_bool.rs\"]\n    mod lazy;\n\n    static RDRAND_GOOD: lazy::LazyBool = lazy::LazyBool::new();\n\n    RDRAND_GOOD.unsync_init(init)\n}\n\n#[target_feature(enable = \"rdrand\")]\nfn rdrand_exact(dest: &mut [MaybeUninit<u8>]) -> Option<()> {\n    // We use chunks_exact_mut instead of chunks_mut as it allows almost all\n    // calls to memcpy to be elided by the compiler.\n    let mut chunks = dest.chunks_exact_mut(size_of::<Word>());\n    for chunk in chunks.by_ref() {\n        let src = rdrand()?.to_ne_bytes();\n        chunk.copy_from_slice(slice_as_uninit(&src));\n    }\n\n    let tail = chunks.into_remainder();\n    let n = tail.len();\n    if n > 0 {\n        let src = rdrand()?.to_ne_bytes();\n        tail.copy_from_slice(slice_as_uninit(&src[..n]));\n    }\n    Some(())\n}\n\n#[cfg(target_arch = \"x86_64\")]\n#[target_feature(enable = \"rdrand\")]\nfn rdrand_u32() -> Option<u32> {\n    rdrand().map(crate::util::truncate)\n}\n\n#[cfg(target_arch = \"x86_64\")]\n#[target_feature(enable = \"rdrand\")]\nfn rdrand_u64() -> Option<u64> {\n    rdrand()\n}\n\n#[cfg(target_arch = \"x86\")]\n#[target_feature(enable = \"rdrand\")]\nfn rdrand_u32() -> Option<u32> {\n    rdrand()\n}\n\n#[cfg(target_arch = \"x86\")]\n#[target_feature(enable = \"rdrand\")]\nfn rdrand_u64() -> Option<u64> {\n    let a = rdrand()?;\n    let b = rdrand()?;\n    Some((u64::from(a) << 32) | u64::from(b))\n}\n\n#[inline]\npub fn inner_u32() -> Result<u32, Error> {\n    if !is_rdrand_good() {\n        return Err(Error::NO_RDRAND);\n    }\n    // SAFETY: After this point, we know rdrand is supported.\n    unsafe { rdrand_u32() }.ok_or(Error::FAILED_RDRAND)\n}\n\n#[inline]\npub fn inner_u64() -> Result<u64, Error> {\n    if !is_rdrand_good() {\n        return Err(Error::NO_RDRAND);\n    }\n    // SAFETY: After this point, we know rdrand is supported.\n    unsafe { rdrand_u64() }.ok_or(Error::FAILED_RDRAND)\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    if !is_rdrand_good() {\n        return Err(Error::NO_RDRAND);\n    }\n    // SAFETY: After this point, we know rdrand is supported.\n    unsafe { rdrand_exact(dest) }.ok_or(Error::FAILED_RDRAND)\n}\n\nimpl Error {\n    /// RDRAND instruction failed due to a hardware issue.\n    pub(crate) const FAILED_RDRAND: Error = Self::new_internal(10);\n    /// RDRAND instruction unsupported on this target.\n    pub(crate) const NO_RDRAND: Error = Self::new_internal(11);\n}\n"
  },
  {
    "path": "src/backends/rndr.rs",
    "content": "//! RNDR register backend for aarch64 targets\n//!\n//! Arm Architecture Reference Manual for A-profile architecture:\n//! ARM DDI 0487K.a, ID032224, D23.2.147 RNDR, Random Number\nuse crate::{\n    Error,\n    util::{slice_as_uninit, truncate},\n};\nuse core::arch::asm;\nuse core::mem::{MaybeUninit, size_of};\n\n#[cfg(not(target_arch = \"aarch64\"))]\ncompile_error!(\"the `rndr` backend can be enabled only for AArch64 targets!\");\n\nconst RETRY_LIMIT: usize = 5;\n\n/// Read a random number from the aarch64 RNDR register\n///\n/// Callers must ensure that FEAT_RNG is available on the system\n/// The function assumes that the RNDR register is available\n/// If it fails to read a random number, it will retry up to 5 times\n/// After 5 failed reads the function will return `None`\n#[target_feature(enable = \"rand\")]\nunsafe fn rndr() -> Option<u64> {\n    for _ in 0..RETRY_LIMIT {\n        let mut x: u64;\n        let mut nzcv: u64;\n\n        // AArch64 RNDR register is accessible by s3_3_c2_c4_0\n        unsafe {\n            asm!(\n                \"mrs {x}, RNDR\",\n                \"mrs {nzcv}, NZCV\",\n                x = out(reg) x,\n                nzcv = out(reg) nzcv,\n            );\n        }\n\n        // If the hardware returns a genuine random number, PSTATE.NZCV is set to 0b0000\n        if nzcv == 0 {\n            return Some(x);\n        }\n    }\n\n    None\n}\n\n#[target_feature(enable = \"rand\")]\nunsafe fn rndr_fill(dest: &mut [MaybeUninit<u8>]) -> Option<()> {\n    let mut chunks = dest.chunks_exact_mut(size_of::<u64>());\n    for chunk in chunks.by_ref() {\n        let src = unsafe { rndr() }?.to_ne_bytes();\n        chunk.copy_from_slice(slice_as_uninit(&src));\n    }\n\n    let tail = chunks.into_remainder();\n    let n = tail.len();\n    if n > 0 {\n        let src = unsafe { rndr() }?.to_ne_bytes();\n        tail.copy_from_slice(slice_as_uninit(&src[..n]));\n    }\n    Some(())\n}\n\n#[cfg(target_feature = \"rand\")]\nfn is_rndr_available() -> bool {\n    true\n}\n\n#[cfg(not(target_feature = \"rand\"))]\nfn is_rndr_available() -> bool {\n    #[path = \"../utils/lazy_bool.rs\"]\n    mod lazy;\n\n    static RNDR_GOOD: lazy::LazyBool = lazy::LazyBool::new();\n\n    cfg_if::cfg_if! {\n        if #[cfg(feature = \"std\")] {\n            extern crate std;\n            RNDR_GOOD.unsync_init(|| std::arch::is_aarch64_feature_detected!(\"rand\"))\n        } else if #[cfg(target_os = \"linux\")] {\n            /// Check whether FEAT_RNG is available on the system\n            ///\n            /// Requires the caller either be running in EL1 or be on a system supporting MRS\n            /// emulation. Due to the above, the implementation is currently restricted to Linux.\n            ///\n            /// Relying on runtime detection bumps minimum supported Linux kernel version to 4.11.\n            fn mrs_check() -> bool {\n                let mut id_aa64isar0: u64;\n\n                // If FEAT_RNG is implemented, ID_AA64ISAR0_EL1.RNDR (bits 60-63) are 0b0001\n                // This is okay to do from EL0 in Linux because Linux will emulate MRS as per\n                // https://docs.kernel.org/arch/arm64/cpu-feature-registers.html\n                unsafe {\n                    asm!(\n                        \"mrs {id}, ID_AA64ISAR0_EL1\",\n                        id = out(reg) id_aa64isar0,\n                    );\n                }\n\n                (id_aa64isar0 >> 60) & 0xf >= 1\n            }\n\n            RNDR_GOOD.unsync_init(mrs_check)\n        } else {\n            compile_error!(\n                \"RNDR `no_std` runtime detection is currently supported only on Linux targets. \\\n                Either enable the `std` crate feature, or `rand` target feature at compile time.\"\n            );\n        }\n    }\n}\n\n#[inline]\npub fn inner_u32() -> Result<u32, Error> {\n    if !is_rndr_available() {\n        return Err(Error::RNDR_NOT_AVAILABLE);\n    }\n    // SAFETY: after this point, we know the `rand` target feature is enabled\n    let res = unsafe { rndr() };\n    res.map(truncate).ok_or(Error::RNDR_FAILURE)\n}\n\n#[inline]\npub fn inner_u64() -> Result<u64, Error> {\n    if !is_rndr_available() {\n        return Err(Error::RNDR_NOT_AVAILABLE);\n    }\n    // SAFETY: after this point, we know the `rand` target feature is enabled\n    let res = unsafe { rndr() };\n    res.ok_or(Error::RNDR_FAILURE)\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    if !is_rndr_available() {\n        return Err(Error::RNDR_NOT_AVAILABLE);\n    }\n    // SAFETY: after this point, we know the `rand` target feature is enabled\n    unsafe { rndr_fill(dest).ok_or(Error::RNDR_FAILURE) }\n}\n\nimpl Error {\n    /// RNDR register read failed due to a hardware issue.\n    pub(crate) const RNDR_FAILURE: Error = Self::new_internal(10);\n    /// RNDR register is not supported on this target.\n    pub(crate) const RNDR_NOT_AVAILABLE: Error = Self::new_internal(11);\n}\n"
  },
  {
    "path": "src/backends/solaris.rs",
    "content": "//! Solaris implementation using getrandom(2).\n//!\n//! While getrandom(2) has been available since Solaris 11.3, it has a few\n//! quirks not present on other OSes. First, on Solaris 11.3, calls will always\n//! fail if bufsz > 1024. Second, it will always either fail or completely fill\n//! the buffer (returning bufsz). Third, error is indicated by returning 0,\n//! rather than by returning -1. Finally, \"if GRND_RANDOM is not specified\n//! then getrandom(2) is always a non blocking call\". This _might_ imply that\n//! in early-boot scenarios with low entropy, getrandom(2) will not properly\n//! block. To be safe, we set GRND_RANDOM, mirroring the man page examples.\n//!\n//! For more information, see the man page linked in lib.rs and this blog post:\n//! https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2\n//! which also explains why this crate should not use getentropy(2).\nuse crate::Error;\nuse core::{ffi::c_void, mem::MaybeUninit};\nuse libc::___errno as errno_location;\n\npub use crate::util::{inner_u32, inner_u64};\n\nconst MAX_BYTES: usize = 1024;\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    for chunk in dest.chunks_mut(MAX_BYTES) {\n        let ptr = chunk.as_mut_ptr().cast::<c_void>();\n        let ret = unsafe { libc::getrandom(ptr, chunk.len(), libc::GRND_RANDOM) };\n        // In case the man page has a typo, we also check for negative ret.\n        // If getrandom(2) succeeds, it should have completely filled chunk.\n        match usize::try_from(ret) {\n            // Good. Keep going.\n            Ok(ret) if ret == chunk.len() => {}\n            // The syscall failed.\n            Ok(0) => {\n                let errno = unsafe { core::ptr::read(errno_location()) };\n                return Err(Error::from_errno(errno));\n            }\n            // All other cases should be impossible.\n            _ => return Err(Error::UNEXPECTED),\n        }\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "src/backends/solid.rs",
    "content": "//! Implementation for SOLID\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\nunsafe extern \"C\" {\n    pub fn SOLID_RNG_SampleRandomBytes(buffer: *mut u8, length: usize) -> i32;\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    let ret = unsafe { SOLID_RNG_SampleRandomBytes(dest.as_mut_ptr().cast::<u8>(), dest.len()) };\n    if ret >= 0 {\n        Ok(())\n    } else {\n        Err(Error::from_neg_error_code(ret))\n    }\n}\n"
  },
  {
    "path": "src/backends/unsupported.rs",
    "content": "//! Implementation that errors at runtime.\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\npub fn fill_inner(_dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    Err(Error::UNSUPPORTED)\n}\n"
  },
  {
    "path": "src/backends/use_file.rs",
    "content": "//! Implementations that just need to read from a file\nuse crate::Error;\nuse core::{\n    ffi::{CStr, c_void},\n    mem::MaybeUninit,\n    sync::atomic::{AtomicI32, Ordering},\n};\n\n#[cfg(not(any(target_os = \"android\", target_os = \"linux\")))]\npub use crate::util::{inner_u32, inner_u64};\n\n#[path = \"../utils/sys_fill_exact.rs\"]\npub(super) mod utils;\n\n/// For all platforms, we use `/dev/urandom` rather than `/dev/random`.\n/// For more information see the linked man pages in lib.rs.\n///   - On Linux, \"/dev/urandom is preferred and sufficient in all use cases\".\n///   - On Redox, only /dev/urandom is provided.\n///   - On AIX, /dev/urandom will \"provide cryptographically secure output\".\n///   - On Haiku and QNX Neutrino they are identical.\nconst FILE_PATH: &CStr = c\"/dev/urandom\";\n\n// File descriptor is a \"nonnegative integer\", so we can safely use negative sentinel values.\nconst FD_UNINIT: libc::c_int = -1;\nconst FD_ONGOING_INIT: libc::c_int = -2;\n\n// In theory `libc::c_int` could be something other than `i32`, but for the\n// targets we currently support that use `use_file`, it is always `i32`.\n// If/when we add support for a target where that isn't the case, we may\n// need to use a different atomic type or make other accommodations. The\n// compiler will let us know if/when that is the case, because the\n// `FD.store(fd)` would fail to compile.\n//\n// The opening of the file, by libc/libstd/etc. may write some unknown\n// state into in-process memory. (Such state may include some sanitizer\n// bookkeeping, or we might be operating in a unikernal-like environment\n// where all the \"kernel\" file descriptor bookkeeping is done in our\n// process.) `get_fd_locked` stores into FD using `Ordering::Release` to\n// ensure any such state is synchronized. `get_fd` loads from `FD` with\n// `Ordering::Acquire` to synchronize with it.\nstatic FD: AtomicI32 = AtomicI32::new(FD_UNINIT);\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    let mut fd = FD.load(Ordering::Acquire);\n    if fd == FD_UNINIT || fd == FD_ONGOING_INIT {\n        fd = open_or_wait()?;\n    }\n    utils::sys_fill_exact(dest, |buf| unsafe {\n        libc::read(fd, buf.as_mut_ptr().cast::<c_void>(), buf.len())\n    })\n}\n\n/// Open a file in read-only mode.\nfn open_readonly(path: &CStr) -> Result<libc::c_int, Error> {\n    loop {\n        let fd = unsafe { libc::open(path.as_ptr(), libc::O_RDONLY | libc::O_CLOEXEC) };\n        if fd >= 0 {\n            return Ok(fd);\n        }\n        let errno = utils::get_errno();\n        // We should try again if open() was interrupted.\n        if errno != libc::EINTR {\n            return Err(Error::from_errno(errno));\n        }\n    }\n}\n\n#[cold]\n#[inline(never)]\nfn open_or_wait() -> Result<libc::c_int, Error> {\n    loop {\n        match FD.load(Ordering::Acquire) {\n            FD_UNINIT => {\n                let res = FD.compare_exchange_weak(\n                    FD_UNINIT,\n                    FD_ONGOING_INIT,\n                    Ordering::AcqRel,\n                    Ordering::Relaxed,\n                );\n                if res.is_ok() {\n                    break;\n                }\n            }\n            FD_ONGOING_INIT => sync::wait(),\n            fd => return Ok(fd),\n        }\n    }\n\n    let res = open_fd();\n    let val = match res {\n        Ok(fd) => fd,\n        Err(_) => FD_UNINIT,\n    };\n    FD.store(val, Ordering::Release);\n\n    // On non-Linux targets `wait` is just 1 ms sleep,\n    // so we don't need any explicit wake up in addition\n    // to updating value of `FD`.\n    #[cfg(any(target_os = \"android\", target_os = \"linux\"))]\n    sync::wake();\n\n    res\n}\n\nfn open_fd() -> Result<libc::c_int, Error> {\n    #[cfg(any(target_os = \"android\", target_os = \"linux\"))]\n    sync::wait_until_rng_ready()?;\n    let fd = open_readonly(FILE_PATH)?;\n    debug_assert!(fd >= 0);\n    Ok(fd)\n}\n\n#[cfg(not(any(target_os = \"android\", target_os = \"linux\")))]\nmod sync {\n    /// Sleep 1 ms before checking `FD` again.\n    ///\n    /// On non-Linux targets the critical section only opens file,\n    /// which should not block, so in the unlikely contended case,\n    /// we can sleep-wait for the opening operation to finish.\n    pub(super) fn wait() {\n        let rqtp = libc::timespec {\n            tv_sec: 0,\n            tv_nsec: 1_000_000,\n        };\n        let mut rmtp = libc::timespec {\n            tv_sec: 0,\n            tv_nsec: 0,\n        };\n        // We do not care if sleep gets interrupted, so the return value is ignored\n        unsafe {\n            libc::nanosleep(&rqtp, &mut rmtp);\n        }\n    }\n}\n\n#[cfg(any(target_os = \"android\", target_os = \"linux\"))]\nmod sync {\n    use super::{Error, FD, FD_ONGOING_INIT, open_readonly, utils};\n\n    /// Wait for atomic `FD` to change value from `FD_ONGOING_INIT` to something else.\n    ///\n    /// Futex syscall with `FUTEX_WAIT` op puts the current thread to sleep\n    /// until futex syscall with `FUTEX_WAKE` op gets executed for `FD`.\n    ///\n    /// For more information read: https://www.man7.org/linux/man-pages/man2/futex.2.html\n    pub(super) fn wait() {\n        let op = libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG;\n        let timeout_ptr = core::ptr::null::<libc::timespec>();\n        let ret = unsafe { libc::syscall(libc::SYS_futex, &FD, op, FD_ONGOING_INIT, timeout_ptr) };\n        // FUTEX_WAIT should return either 0 or EAGAIN error\n        debug_assert!({\n            match ret {\n                0 => true,\n                -1 => utils::get_errno() == libc::EAGAIN,\n                _ => false,\n            }\n        });\n    }\n\n    /// Wake up all threads which wait for value of atomic `FD` to change.\n    pub(super) fn wake() {\n        let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG;\n        let ret = unsafe { libc::syscall(libc::SYS_futex, &FD, op, libc::INT_MAX) };\n        debug_assert!(ret >= 0);\n    }\n\n    // Polls /dev/random to make sure it is ok to read from /dev/urandom.\n    //\n    // Polling avoids draining the estimated entropy from /dev/random;\n    // short-lived processes reading even a single byte from /dev/random could\n    // be problematic if they are being executed faster than entropy is being\n    // collected.\n    //\n    // OTOH, reading a byte instead of polling is more compatible with\n    // sandboxes that disallow `poll()` but which allow reading /dev/random,\n    // e.g. sandboxes that assume that `poll()` is for network I/O. This way,\n    // fewer applications will have to insert pre-sandbox-initialization logic.\n    // Often (blocking) file I/O is not allowed in such early phases of an\n    // application for performance and/or security reasons.\n    //\n    // It is hard to write a sandbox policy to support `libc::poll()` because\n    // it may invoke the `poll`, `ppoll`, `ppoll_time64` (since Linux 5.1, with\n    // newer versions of glibc), and/or (rarely, and probably only on ancient\n    // systems) `select`. depending on the libc implementation (e.g. glibc vs\n    // musl), libc version, potentially the kernel version at runtime, and/or\n    // the target architecture.\n    //\n    // BoringSSL and libstd don't try to protect against insecure output from\n    // `/dev/urandom'; they don't open `/dev/random` at all.\n    //\n    // OpenSSL uses `libc::select()` unless the `dev/random` file descriptor\n    // is too large; if it is too large then it does what we do here.\n    //\n    // libsodium uses `libc::poll` similarly to this.\n    pub(super) fn wait_until_rng_ready() -> Result<(), Error> {\n        let fd = open_readonly(c\"/dev/random\")?;\n        let mut pfd = libc::pollfd {\n            fd,\n            events: libc::POLLIN,\n            revents: 0,\n        };\n\n        let res = loop {\n            // A negative timeout means an infinite timeout.\n            let res = unsafe { libc::poll(&mut pfd, 1, -1) };\n            if res >= 0 {\n                // We only used one fd, and cannot timeout.\n                debug_assert_eq!(res, 1);\n                break Ok(());\n            }\n            let errno = utils::get_errno();\n            // Assuming that `poll` is called correctly,\n            // on Linux it can return only EINTR and ENOMEM errors.\n            match errno {\n                libc::EINTR => continue,\n                _ => break Err(Error::from_errno(errno)),\n            }\n        };\n        unsafe { libc::close(fd) };\n        res\n    }\n}\n"
  },
  {
    "path": "src/backends/vxworks.rs",
    "content": "//! Implementation for VxWorks\nuse crate::Error;\nuse core::{\n    cmp::Ordering::{Equal, Greater, Less},\n    mem::MaybeUninit,\n    sync::atomic::{AtomicBool, Ordering::Relaxed},\n};\n\npub use crate::util::{inner_u32, inner_u64};\n\nstatic RNG_INIT: AtomicBool = AtomicBool::new(false);\n\n#[cold]\nfn init() -> Result<(), Error> {\n    let ret = unsafe { libc::randSecure() };\n    match ret.cmp(&0) {\n        Greater => RNG_INIT.store(true, Relaxed),\n        Equal => unsafe {\n            libc::usleep(10);\n        },\n        Less => return Err(Error::VXWORKS_RAND_SECURE),\n    }\n    Ok(())\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    while !RNG_INIT.load(Relaxed) {\n        init()?;\n    }\n\n    // Prevent overflow of i32\n    let chunk_size = usize::try_from(i32::MAX).expect(\"VxWorks does not support 16-bit targets\");\n    for chunk in dest.chunks_mut(chunk_size) {\n        let chunk_len: libc::c_int = chunk\n            .len()\n            .try_into()\n            .expect(\"chunk size is bounded by i32::MAX\");\n        let p: *mut libc::c_uchar = chunk.as_mut_ptr().cast();\n        let ret = unsafe { libc::randABytes(p, chunk_len) };\n        match ret {\n            0 => continue,\n            -1 => {\n                let errno = unsafe { libc::errnoGet() };\n                return Err(Error::from_errno(errno));\n            }\n            _ => return Err(Error::UNEXPECTED),\n        }\n    }\n    Ok(())\n}\n\nimpl Error {\n    /// On VxWorks, call to `randSecure` failed (random number generator is not yet initialized).\n    pub(crate) const VXWORKS_RAND_SECURE: Error = Self::new_internal(10);\n}\n"
  },
  {
    "path": "src/backends/wasi_p1.rs",
    "content": "//! Implementation for WASI Preview 1\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\n// This linking is vendored from the wasi crate:\n// https://docs.rs/wasi/0.11.0+wasi-snapshot-preview1/src/wasi/lib_generated.rs.html#2344-2350\n#[link(wasm_import_module = \"wasi_snapshot_preview1\")]\nunsafe extern \"C\" {\n    fn random_get(arg0: i32, arg1: i32) -> i32;\n}\n\n/// WASI p1 uses `u16` for error codes in its witx definitions:\n/// https://github.com/WebAssembly/WASI/blob/38454e9e/legacy/preview1/witx/typenames.witx#L34-L39\nconst MAX_ERROR_CODE: i32 = u16::MAX as i32;\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    // Based on the wasi code:\n    // https://docs.rs/wasi/0.11.0+wasi-snapshot-preview1/src/wasi/lib_generated.rs.html#2046-2062\n    // Note that size of an allocated object can not be bigger than isize::MAX bytes.\n    // WASI 0.1 supports only 32-bit WASM, so casting length to `i32` is safe.\n    #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]\n    let ret = unsafe { random_get(dest.as_mut_ptr() as i32, dest.len() as i32) };\n    match ret {\n        0 => Ok(()),\n        // WASI functions should return positive error codes which are smaller than `MAX_ERROR_CODE`\n        code if code <= MAX_ERROR_CODE => Err(Error::from_neg_error_code(-code)),\n        _ => Err(Error::UNEXPECTED),\n    }\n}\n"
  },
  {
    "path": "src/backends/wasi_p2_3.rs",
    "content": "//! Implementation for WASIp2 and WASIp3.\nuse crate::Error;\nuse core::{mem::MaybeUninit, ptr::copy_nonoverlapping};\n\n#[cfg(target_env = \"p2\")]\nuse wasip2 as wasi;\n\n// Workaround to silence `unexpected_cfgs` warning\n// on Rust version between 1.85 and 1.91\n#[cfg(not(target_env = \"p2\"))]\n#[cfg(target_env = \"p3\")]\nuse wasip3 as wasi;\n\n#[cfg(not(target_env = \"p2\"))]\n#[cfg(not(target_env = \"p3\"))]\ncompile_error!(\"Unknown version of WASI (only previews 1, 2 and 3 are supported)\");\n\nuse wasi::random::random::get_random_u64;\n\n#[inline]\npub fn inner_u32() -> Result<u32, Error> {\n    let val = get_random_u64();\n    Ok(crate::util::truncate(val))\n}\n\n#[inline]\npub fn inner_u64() -> Result<u64, Error> {\n    Ok(get_random_u64())\n}\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    let (prefix, chunks, suffix) = unsafe { dest.align_to_mut::<MaybeUninit<u64>>() };\n\n    // We use `get_random_u64` instead of `get_random_bytes` because the latter creates\n    // an allocation due to the Wit IDL [restrictions][0]. This should be fine since\n    // the main use case of `getrandom` is seed generation.\n    //\n    // [0]: https://github.com/WebAssembly/wasi-random/issues/27\n    if !prefix.is_empty() {\n        let val = get_random_u64();\n        let src = (&val as *const u64).cast();\n        unsafe {\n            copy_nonoverlapping(src, prefix.as_mut_ptr(), prefix.len());\n        }\n    }\n\n    for dst in chunks {\n        dst.write(get_random_u64());\n    }\n\n    if !suffix.is_empty() {\n        let val = get_random_u64();\n        let src = (&val as *const u64).cast();\n        unsafe {\n            copy_nonoverlapping(src, suffix.as_mut_ptr(), suffix.len());\n        }\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/backends/wasm_js.rs",
    "content": "//! Implementation for WASM based on Web and Node.js\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[cfg(not(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\"))))]\ncompile_error!(\"`wasm_js` backend can be enabled only for OS-less WASM targets!\");\n\nuse wasm_bindgen::{prelude::wasm_bindgen, JsValue};\n\n// Maximum buffer size allowed in `Crypto.getRandomValuesSize` is 65536 bytes.\n// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues\nconst MAX_BUFFER_SIZE: usize = 65536;\n\n#[cfg(not(target_feature = \"atomics\"))]\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    for chunk in dest.chunks_mut(MAX_BUFFER_SIZE) {\n        if get_random_values(chunk).is_err() {\n            return Err(Error::WEB_CRYPTO);\n        }\n    }\n    Ok(())\n}\n\n#[cfg(target_feature = \"atomics\")]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    // getRandomValues does not work with all types of WASM memory,\n    // so we initially write to browser memory to avoid exceptions.\n    let buf_len = usize::min(dest.len(), MAX_BUFFER_SIZE);\n    let buf_len_u32 = buf_len\n        .try_into()\n        .expect(\"buffer length is bounded by MAX_BUFFER_SIZE\");\n    let buf = js_sys::Uint8Array::new_with_length(buf_len_u32);\n    for chunk in dest.chunks_mut(buf_len) {\n        let chunk_len = chunk\n            .len()\n            .try_into()\n            .expect(\"chunk length is bounded by MAX_BUFFER_SIZE\");\n        // The chunk can be smaller than buf's length, so we call to\n        // JS to create a smaller view of buf without allocation.\n        let sub_buf = if chunk_len == buf_len_u32 {\n            &buf\n        } else {\n            &buf.subarray(0, chunk_len)\n        };\n\n        if get_random_values(sub_buf).is_err() {\n            return Err(Error::WEB_CRYPTO);\n        }\n\n        sub_buf.copy_to_uninit(chunk);\n    }\n    Ok(())\n}\n\n#[wasm_bindgen]\nunsafe extern \"C\" {\n    // Crypto.getRandomValues()\n    #[cfg(not(target_feature = \"atomics\"))]\n    #[wasm_bindgen(js_namespace = [\"globalThis\", \"crypto\"], js_name = getRandomValues, catch)]\n    fn get_random_values(buf: &mut [MaybeUninit<u8>]) -> Result<(), JsValue>;\n    #[cfg(target_feature = \"atomics\")]\n    #[wasm_bindgen(js_namespace = [\"globalThis\", \"crypto\"], js_name = getRandomValues, catch)]\n    fn get_random_values(buf: &js_sys::Uint8Array) -> Result<(), JsValue>;\n}\n\nimpl Error {\n    /// The environment does not support the Web Crypto API.\n    pub(crate) const WEB_CRYPTO: Error = Self::new_internal(10);\n}\n"
  },
  {
    "path": "src/backends/windows.rs",
    "content": "//! Implementation for Windows 10 and later\n//!\n//! On Windows 10 and later, ProcessPrng \"is the primary interface to the\n//! user-mode per-processor PRNGs\" and only requires bcryptprimitives.dll,\n//! making it a better option than the other Windows RNG APIs:\n//!   - BCryptGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom\n//!     - Requires bcrypt.dll (which loads bcryptprimitives.dll anyway)\n//!     - Can cause crashes/hangs as BCrypt accesses the Windows Registry:\n//!       https://github.com/rust-lang/rust/issues/99341\n//!     - Causes issues inside sandboxed code:\n//!       https://issues.chromium.org/issues/40277768\n//!   - CryptGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom\n//!     - Deprecated and not available on UWP targets\n//!     - Requires advapi32.lib/advapi32.dll (in addition to bcryptprimitives.dll)\n//!     - Thin wrapper around ProcessPrng\n//!   - RtlGenRandom: https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom\n//!     - Deprecated and not available on UWP targets\n//!     - Requires advapi32.dll (in addition to bcryptprimitives.dll)\n//!     - Requires using name \"SystemFunction036\"\n//!     - Thin wrapper around ProcessPrng\n//!\n//! For more information see the Windows RNG Whitepaper: https://aka.ms/win10rng\nuse crate::Error;\nuse core::mem::MaybeUninit;\n\npub use crate::util::{inner_u32, inner_u64};\n\n// Binding to the Windows.Win32.Security.Cryptography.ProcessPrng API. As\n// bcryptprimitives.dll lacks an import library, we use \"raw-dylib\".\n#[cfg_attr(\n    target_arch = \"x86\",\n    link(\n        name = \"bcryptprimitives\",\n        kind = \"raw-dylib\",\n        import_name_type = \"undecorated\"\n    )\n)]\n#[cfg_attr(\n    not(target_arch = \"x86\"),\n    link(name = \"bcryptprimitives\", kind = \"raw-dylib\")\n)]\nunsafe extern \"system\" {\n    fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;\n}\n#[expect(clippy::upper_case_acronyms)]\ntype BOOL = core::ffi::c_int;\nconst TRUE: BOOL = 1;\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    let result = unsafe { ProcessPrng(dest.as_mut_ptr().cast::<u8>(), dest.len()) };\n    // On Windows 10 and later, `ProcessPrng` is documented to always return\n    // TRUE. All potential errors are handled during loading of\n    // `BCryptPrimitive.dll`. See the \"Process base PRNG\" section in the\n    // aforementioned Windows RNG whitepaper for more information.\n    //\n    // The Zig project found that Windows 8 implements `ProcessPrng` in a way\n    // that may fail and return a value other than `TRUE`. Although recent\n    // versions of the Rust toolchain do not support Windows 8, we cannot rule\n    // out this backend being used in an executable that will run on Windows 8\n    // (e.g. a fork of this crate backported to have an MSRV lower than 1.76,\n    // or a fork of the Rust toolchain to support older Windows versions, or\n    // other build hacks).\n    //\n    // Further, Wine's implementation of `ProcessPrng` CAN fail, in every\n    // version through Wine 11.2, and this may be the case for any other Windows\n    // emulation layers.\n    if result == TRUE {\n        Ok(())\n    } else {\n        Err(Error::UNEXPECTED)\n    }\n}\n"
  },
  {
    "path": "src/backends/windows_legacy.rs",
    "content": "//! Legacy implementation for Windows XP and later\n//!\n//! For targets where we cannot use ProcessPrng (added in Windows 10), we use\n//! RtlGenRandom. See windows.rs for a more detailed discussion of the Windows\n//! RNG APIs (and why we don't use BCryptGenRandom). On versions prior to\n//! Windows 10, this implementation is secure. On Windows 10 and later, this\n//! implementation behaves identically to the windows.rs implementation, except\n//! that it forces the loading of an additional DLL (advapi32.dll).\n//!\n//! This implementation will not work on UWP targets (which lack advapi32.dll),\n//! but such targets require Windows 10, so can use the standard implementation.\nuse crate::Error;\nuse core::{ffi::c_void, mem::MaybeUninit};\n\npub use crate::util::{inner_u32, inner_u64};\n\n#[cfg(not(windows))]\ncompile_error!(\"`windows_legacy` backend can be enabled only for Windows targets!\");\n\n// Binding to the Windows.Win32.Security.Authentication.Identity.RtlGenRandom\n// API. Don't use windows-targets as it doesn't support Windows 7 targets.\n#[link(name = \"advapi32\")]\nunsafe extern \"system\" {\n    #[link_name = \"SystemFunction036\"]\n    fn RtlGenRandom(randombuffer: *mut c_void, randombufferlength: u32) -> BOOLEAN;\n}\n#[allow(clippy::upper_case_acronyms)]\ntype BOOLEAN = u8;\nconst TRUE: BOOLEAN = 1u8;\n\n#[inline]\npub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {\n    // Prevent overflow of u32\n    let chunk_size = usize::try_from(i32::MAX).expect(\"Windows does not support 16-bit targets\");\n    for chunk in dest.chunks_mut(chunk_size) {\n        let chunk_len = u32::try_from(chunk.len()).expect(\"chunk size is bounded by i32::MAX\");\n        let ret = unsafe { RtlGenRandom(chunk.as_mut_ptr().cast::<c_void>(), chunk_len) };\n        if ret != TRUE {\n            return Err(Error::WINDOWS_RTL_GEN_RANDOM);\n        }\n    }\n    Ok(())\n}\n\nimpl Error {\n    /// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.\n    pub(crate) const WINDOWS_RTL_GEN_RANDOM: Error = Self::new_internal(10);\n}\n"
  },
  {
    "path": "src/backends.rs",
    "content": "//! System-specific implementations.\n//!\n//! This module should provide `fill_inner` with the signature\n//! `fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error>`.\n//! The function MUST fully initialize `dest` when `Ok(())` is returned;\n//! the function may need to use `sanitizer::unpoison` as well.\n//! The function MUST NOT ever write uninitialized bytes into `dest`,\n//! regardless of what value it returns.\n\ncfg_if! {\n    if #[cfg(getrandom_backend = \"custom\")] {\n        mod custom;\n        pub use custom::*;\n    } else if #[cfg(getrandom_backend = \"linux_getrandom\")] {\n        mod getrandom;\n        pub use getrandom::*;\n    } else if #[cfg(getrandom_backend = \"linux_raw\")] {\n        mod linux_raw;\n        pub use linux_raw::*;\n    } else if #[cfg(getrandom_backend = \"rdrand\")] {\n        mod rdrand;\n        pub use rdrand::*;\n    } else if #[cfg(getrandom_backend = \"rndr\")] {\n        mod rndr;\n        pub use rndr::*;\n    } else if #[cfg(getrandom_backend = \"efi_rng\")] {\n        mod efi_rng;\n        pub use efi_rng::*;\n    } else if #[cfg(getrandom_backend = \"windows_legacy\")] {\n        mod windows_legacy;\n        pub use windows_legacy::*;\n    } else if #[cfg(getrandom_backend = \"unsupported\")] {\n        mod unsupported;\n        pub use unsupported::*;\n    } else if #[cfg(getrandom_backend = \"extern_impl\")] {\n        pub(crate) mod extern_impl;\n        pub use extern_impl::*;\n    } else if #[cfg(all(target_os = \"linux\", target_env = \"\"))] {\n        mod linux_raw;\n        pub use linux_raw::*;\n    } else if #[cfg(target_os = \"espidf\")] {\n        mod esp_idf;\n        pub use esp_idf::*;\n    } else if #[cfg(any(\n        target_os = \"haiku\",\n        target_os = \"redox\",\n        target_os = \"nto\",\n        target_os = \"aix\",\n    ))] {\n        mod use_file;\n        pub use use_file::*;\n    } else if #[cfg(any(\n        target_os = \"macos\",\n        target_os = \"openbsd\",\n        target_os = \"vita\",\n        target_os = \"emscripten\",\n    ))] {\n        mod getentropy;\n        pub use getentropy::*;\n    } else if #[cfg(any(\n        // Rust supports Android API level 19 (KitKat) [0] and the next upgrade targets\n        // level 21 (Lollipop) [1], while `getrandom(2)` was added only in\n        // level 23 (Marshmallow). Note that it applies only to the \"old\" `target_arch`es,\n        // RISC-V Android targets sufficiently new API level, same will apply for potential\n        // new Android `target_arch`es.\n        // [0]: https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html\n        // [1]: https://github.com/rust-lang/rust/pull/120593\n        all(\n            target_os = \"android\",\n            any(\n                target_arch = \"aarch64\",\n                target_arch = \"arm\",\n                target_arch = \"x86\",\n                target_arch = \"x86_64\",\n            ),\n        ),\n        // Only on these `target_arch`es Rust supports Linux kernel versions (3.2+)\n        // that precede the version (3.17) in which `getrandom(2)` was added:\n        // https://doc.rust-lang.org/stable/rustc/platform-support.html\n        all(\n            target_os = \"linux\",\n            any(\n                target_arch = \"aarch64\",\n                target_arch = \"arm\",\n                target_arch = \"powerpc\",\n                target_arch = \"powerpc64\",\n                target_arch = \"s390x\",\n                target_arch = \"x86\",\n                target_arch = \"x86_64\",\n                // Minimum supported Linux kernel version for MUSL targets\n                // is not specified explicitly (as of Rust 1.77) and they\n                // are used in practice to target pre-3.17 kernels.\n                all(\n                    target_env = \"musl\",\n                    not(\n                        any(\n                            target_arch = \"riscv64\",\n                            target_arch = \"riscv32\",\n                        ),\n                    ),\n                ),\n            ),\n        )\n    ))] {\n        mod use_file;\n        mod linux_android_with_fallback;\n        pub use linux_android_with_fallback::*;\n    } else if #[cfg(any(\n        target_os = \"android\",\n        target_os = \"linux\",\n        target_os = \"dragonfly\",\n        target_os = \"freebsd\",\n        target_os = \"hurd\",\n        target_os = \"illumos\",\n        target_os = \"cygwin\",\n        // Check for target_arch = \"arm\" to only include the 3DS. Does not\n        // include the Nintendo Switch (which is target_arch = \"aarch64\").\n        all(target_os = \"horizon\", target_arch = \"arm\"),\n    ))] {\n        mod getrandom;\n        pub use getrandom::*;\n    } else if #[cfg(target_os = \"solaris\")] {\n        mod solaris;\n        pub use solaris::*;\n    } else if #[cfg(target_os = \"netbsd\")] {\n        mod netbsd;\n        pub use netbsd::*;\n    } else if #[cfg(target_os = \"fuchsia\")] {\n        mod fuchsia;\n        pub use fuchsia::*;\n    } else if #[cfg(any(\n        target_os = \"ios\",\n        target_os = \"visionos\",\n        target_os = \"watchos\",\n        target_os = \"tvos\",\n    ))] {\n        mod apple_other;\n        pub use apple_other::*;\n    } else if #[cfg(all(target_arch = \"wasm32\", target_os = \"wasi\"))] {\n        cfg_if! {\n            if #[cfg(target_env = \"p1\")] {\n                mod wasi_p1;\n                pub use wasi_p1::*;\n            } else {\n                mod wasi_p2_3;\n                pub use wasi_p2_3::*;\n            }\n        }\n    } else if #[cfg(target_os = \"hermit\")] {\n        mod hermit;\n        pub use hermit::*;\n    } else if #[cfg(all(target_arch = \"x86_64\", target_os = \"motor\"))] {\n        mod rdrand;\n        pub use rdrand::*;\n    } else if #[cfg(target_os = \"vxworks\")] {\n        mod vxworks;\n        pub use vxworks::*;\n    } else if #[cfg(target_os = \"solid_asp3\")] {\n        mod solid;\n        pub use solid::*;\n    } else if #[cfg(all(windows, target_vendor = \"win7\"))] {\n        mod windows_legacy;\n        pub use windows_legacy::*;\n    } else if #[cfg(windows)] {\n        mod windows;\n        pub use windows::*;\n    } else if #[cfg(all(target_arch = \"x86_64\", target_env = \"sgx\"))] {\n        mod rdrand;\n        pub use rdrand::*;\n    } else if #[cfg(all(target_arch = \"wasm32\", any(target_os = \"unknown\", target_os = \"none\")))] {\n        cfg_if! {\n            if #[cfg(feature = \"wasm_js\")] {\n                mod wasm_js;\n                pub use wasm_js::*;\n            } else {\n                compile_error!(concat!(\n                    \"The wasm32-unknown-unknown targets are not supported by default; \\\n                    you may need to enable the \\\"wasm_js\\\" crate feature. \\\n                    For more information see: \\\n                    https://docs.rs/getrandom/\", env!(\"CARGO_PKG_VERSION\"), \"/#webassembly-support\"\n                ));\n            }\n        }\n    } else {\n        compile_error!(concat!(\n            \"target is not supported. You may need to define a custom backend see: \\\n            https://docs.rs/getrandom/\", env!(\"CARGO_PKG_VERSION\"), \"/#custom-backend\"\n        ));\n    }\n}\n"
  },
  {
    "path": "src/error.rs",
    "content": "#[cfg(feature = \"std\")]\nextern crate std;\n\nuse core::fmt;\n\ncfg_if::cfg_if!(\n    if #[cfg(target_os = \"uefi\")] {\n        // See the UEFI spec for more information:\n        // https://uefi.org/specs/UEFI/2.10/Apx_D_Status_Codes.html\n\n        /// Raw error code.\n        ///\n        /// This alias mirrors unstable [`std::io::RawOsError`].\n        ///\n        /// [`std::io::RawOsError`]: https://doc.rust-lang.org/std/io/type.RawOsError.html\n        pub type RawOsError = usize;\n        type NonZeroRawOsError = core::num::NonZeroUsize;\n        const UEFI_ERROR_FLAG: RawOsError = 1 << (RawOsError::BITS - 1);\n    } else {\n        /// Raw error code.\n        ///\n        /// This alias mirrors unstable [`std::io::RawOsError`].\n        ///\n        /// [`std::io::RawOsError`]: https://doc.rust-lang.org/std/io/type.RawOsError.html\n        pub type RawOsError = i32;\n        type NonZeroRawOsError = core::num::NonZeroI32;\n    }\n);\n\n/// A small and `no_std` compatible error type\n///\n/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and\n/// if so, which error code the OS gave the application. If such an error is\n/// encountered, please consult with your system documentation.\n///\n/// *If this crate's `\"std\"` Cargo feature is enabled*, then:\n/// - [`getrandom::Error`][Error] implements\n///   [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html)\n/// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements\n///   [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html).\n\n// note: on non-UEFI targets OS errors are represented as negative integers,\n// while on UEFI targets OS errors have the highest bit set to 1.\n#[derive(Copy, Clone, Eq, PartialEq)]\npub struct Error(NonZeroRawOsError);\n\nimpl Error {\n    /// This target/platform is not supported by `getrandom`.\n    pub const UNSUPPORTED: Error = Self::new_internal(0);\n    /// The platform-specific `errno` returned a non-positive value.\n    pub const ERRNO_NOT_POSITIVE: Error = Self::new_internal(1);\n    /// Encountered an unexpected situation which should not happen in practice.\n    pub const UNEXPECTED: Error = Self::new_internal(2);\n\n    /// Internal errors can be in the range of 2^16..2^17\n    const INTERNAL_START: RawOsError = 1 << 16;\n    /// Custom errors can be in the range of 2^17..(2^17 + 2^16)\n    const CUSTOM_START: RawOsError = 1 << 17;\n\n    /// Creates a new `Error` instance from a positive error code.\n    ///\n    /// Returns [`Error::ERRNO_NOT_POSITIVE`] for zero and negative error codes.\n    #[cfg(not(target_os = \"uefi\"))]\n    #[allow(dead_code)]\n    pub(super) fn from_errno(errno: i32) -> Self {\n        if errno > 0 {\n            let code = errno\n                .checked_neg()\n                .expect(\"Positive number can be always negated\");\n            Error::from_neg_error_code(code)\n        } else {\n            Error::ERRNO_NOT_POSITIVE\n        }\n    }\n\n    /// Creates a new `Error` instance from a negative error code.\n    ///\n    /// Returns [`Error::UNEXPECTED`] for zero and positive error codes.\n    #[cfg(not(target_os = \"uefi\"))]\n    #[allow(dead_code)]\n    pub(super) fn from_neg_error_code(code: RawOsError) -> Self {\n        if code < 0 {\n            let code = NonZeroRawOsError::new(code).expect(\"`code` is negative\");\n            Self(code)\n        } else {\n            Error::UNEXPECTED\n        }\n    }\n\n    /// Creates a new instance of an `Error` from an UEFI error code.\n    #[cfg(target_os = \"uefi\")]\n    #[allow(dead_code)]\n    pub(super) fn from_uefi_code(code: RawOsError) -> Self {\n        if code & UEFI_ERROR_FLAG != 0 {\n            let code = NonZeroRawOsError::new(code).expect(\"The highest bit of `code` is set to 1\");\n            Self(code)\n        } else {\n            Self::UNEXPECTED\n        }\n    }\n\n    /// Extract the raw OS error code (if this error came from the OS)\n    ///\n    /// This method is identical to [`std::io::Error::raw_os_error()`][1], except\n    /// that it works in `no_std` contexts. On most targets this method returns\n    /// `Option<i32>`, but some platforms (e.g. UEFI) may use a different primitive\n    /// type like `usize`. Consult with the [`RawOsError`] docs for more information.\n    ///\n    /// If this method returns `None`, the error value can still be formatted via\n    /// the `Display` implementation.\n    ///\n    /// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error\n    /// [`RawOsError`]: https://doc.rust-lang.org/std/io/type.RawOsError.html\n    #[inline]\n    pub fn raw_os_error(self) -> Option<RawOsError> {\n        let code = self.0.get();\n\n        // note: in this method we need to cover only backends which rely on\n        // `Error::{from_error_code, from_errno, from_uefi_code}` methods,\n        // on all other backends this method always returns `None`.\n\n        #[cfg(target_os = \"uefi\")]\n        {\n            if code & UEFI_ERROR_FLAG != 0 {\n                Some(code)\n            } else {\n                None\n            }\n        }\n\n        #[cfg(not(target_os = \"uefi\"))]\n        {\n            // On most targets `std` expects positive error codes while retrieving error strings:\n            // - `libc`-based targets use `strerror_r` which expects positive error codes.\n            // - Hermit relies on the `hermit-abi` crate, which expects positive error codes:\n            //   https://docs.rs/hermit-abi/0.4.0/src/hermit_abi/errno.rs.html#400-532\n            // - WASIp1 uses the same conventions as `libc`:\n            //   https://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/wasi/os.rs#L57-L67\n            //\n            // The only exception is Solid, `std` expects negative system error codes, see:\n            // https://github.com/rust-lang/rust/blob/1.85.0/library/std/src/sys/pal/solid/error.rs#L5-L31\n            if code >= 0 {\n                None\n            } else if cfg!(not(target_os = \"solid_asp3\")) {\n                code.checked_neg()\n            } else {\n                Some(code)\n            }\n        }\n    }\n\n    /// Creates a new instance of an `Error` from a particular custom error code.\n    pub const fn new_custom(n: u16) -> Error {\n        // SAFETY: code > 0 as CUSTOM_START > 0 and adding `n` won't overflow `RawOsError`.\n        let code = Error::CUSTOM_START + (n as RawOsError);\n        Error(unsafe { NonZeroRawOsError::new_unchecked(code) })\n    }\n\n    /// Creates a new instance of an `Error` from a particular internal error code.\n    pub(crate) const fn new_internal(n: u16) -> Error {\n        // SAFETY: code > 0 as INTERNAL_START > 0 and adding `n` won't overflow `RawOsError`.\n        let code = Error::INTERNAL_START + (n as RawOsError);\n        Error(unsafe { NonZeroRawOsError::new_unchecked(code) })\n    }\n\n    fn internal_desc(&self) -> Option<&'static str> {\n        let desc = match *self {\n            Error::UNSUPPORTED => \"getrandom: this target is not supported\",\n            Error::ERRNO_NOT_POSITIVE => \"errno: did not return a positive value\",\n            Error::UNEXPECTED => \"unexpected situation\",\n            #[cfg(any(\n                target_os = \"ios\",\n                target_os = \"visionos\",\n                target_os = \"watchos\",\n                target_os = \"tvos\",\n            ))]\n            Error::IOS_RANDOM_GEN => \"SecRandomCopyBytes: iOS Security framework failure\",\n            #[cfg(all(windows, target_vendor = \"win7\"))]\n            Error::WINDOWS_RTL_GEN_RANDOM => \"RtlGenRandom: Windows system function failure\",\n            #[cfg(all(\n                feature = \"wasm_js\",\n                target_arch = \"wasm32\",\n                any(target_os = \"unknown\", target_os = \"none\")\n            ))]\n            Error::WEB_CRYPTO => \"Web Crypto API is unavailable\",\n            #[cfg(target_os = \"vxworks\")]\n            Error::VXWORKS_RAND_SECURE => \"randSecure: VxWorks RNG module is not initialized\",\n\n            #[cfg(any(\n                getrandom_backend = \"rdrand\",\n                all(target_arch = \"x86_64\", target_env = \"sgx\")\n            ))]\n            Error::FAILED_RDRAND => \"RDRAND: failed multiple times: CPU issue likely\",\n            #[cfg(any(\n                getrandom_backend = \"rdrand\",\n                all(target_arch = \"x86_64\", target_env = \"sgx\")\n            ))]\n            Error::NO_RDRAND => \"RDRAND: instruction not supported\",\n\n            #[cfg(getrandom_backend = \"rndr\")]\n            Error::RNDR_FAILURE => \"RNDR: Could not generate a random number\",\n            #[cfg(getrandom_backend = \"rndr\")]\n            Error::RNDR_NOT_AVAILABLE => \"RNDR: Register not supported\",\n            _ => return None,\n        };\n        Some(desc)\n    }\n}\n\nimpl core::error::Error for Error {}\n\nimpl fmt::Debug for Error {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        let mut dbg = f.debug_struct(\"Error\");\n        if let Some(errno) = self.raw_os_error() {\n            dbg.field(\"os_error\", &errno);\n            #[cfg(feature = \"std\")]\n            dbg.field(\"description\", &std::io::Error::from_raw_os_error(errno));\n        } else if let Some(desc) = self.internal_desc() {\n            dbg.field(\"internal_code\", &self.0.get());\n            dbg.field(\"description\", &desc);\n        } else {\n            dbg.field(\"unknown_code\", &self.0.get());\n        }\n        dbg.finish()\n    }\n}\n\nimpl fmt::Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        if let Some(errno) = self.raw_os_error() {\n            cfg_if! {\n                if #[cfg(feature = \"std\")] {\n                    std::io::Error::from_raw_os_error(errno).fmt(f)\n                } else {\n                    write!(f, \"OS Error: {errno}\")\n                }\n            }\n        } else if let Some(desc) = self.internal_desc() {\n            f.write_str(desc)\n        } else {\n            write!(f, \"Unknown Error: {}\", self.0.get())\n        }\n    }\n}\n"
  },
  {
    "path": "src/error_std_impls.rs",
    "content": "extern crate std;\n\nuse crate::Error;\nuse std::io;\n\nimpl From<Error> for io::Error {\n    fn from(err: Error) -> Self {\n        match err.raw_os_error() {\n            Some(errno) => io::Error::from_raw_os_error(errno),\n            None => io::Error::other(err),\n        }\n    }\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "// Overwrite links to crate items with intra-crate links\n//! [`Error::UNEXPECTED`]: Error::UNEXPECTED\n//! [`fill_uninit`]: fill_uninit\n\n#![no_std]\n#![doc(\n    html_logo_url = \"https://www.rust-lang.org/logos/rust-logo-128x128-blk.png\",\n    html_favicon_url = \"https://www.rust-lang.org/favicon.ico\"\n)]\n#![doc = include_str!(\"../README.md\")]\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![cfg_attr(getrandom_backend = \"efi_rng\", feature(uefi_std))]\n#![cfg_attr(getrandom_backend = \"extern_impl\", feature(extern_item_impls))]\n\n#[macro_use]\nextern crate cfg_if;\n\nuse core::mem::MaybeUninit;\n\nmod backends;\nmod error;\nmod util;\n\n#[cfg(feature = \"std\")]\nmod error_std_impls;\n\n/// `rand_core` adapter\n#[cfg(feature = \"sys_rng\")]\nmod sys_rng;\n\n#[cfg(feature = \"sys_rng\")]\npub use rand_core;\n#[cfg(feature = \"sys_rng\")]\npub use sys_rng::SysRng;\n\npub use crate::error::{Error, RawOsError};\n\n/// Attribute macros for overwriting the core functionality of this crate.\n///\n/// This allows `getrandom` to provide a default implementation and a common interface\n/// for all crates to use, while giving users a safe way to override that default where required.\n///\n/// Must be enabled via the `extern_impl` opt-in backend, as this functionality\n/// is currently limited to nightly.\n///\n/// # Examples\n///\n/// ```rust\n/// # use core::mem::MaybeUninit;\n/// # #[cfg(getrandom_backend = \"extern_impl\")]\n/// #[getrandom::implementation::fill_uninit]\n/// fn my_fill_uninit_implementation(\n///     dest: &mut [MaybeUninit<u8>]\n/// ) -> Result<(), getrandom::Error> {\n///     // ...\n/// #   let _ = dest;\n/// #   Err(Error::UNSUPPORTED)\n/// }\n/// ```\n#[cfg(getrandom_backend = \"extern_impl\")]\npub mod implementation {\n    pub use crate::backends::extern_impl::{fill_uninit, u32, u64};\n}\n\n/// Fill `dest` with random bytes from the system's preferred random number source.\n///\n/// This function returns an error on any failure, including partial reads. We\n/// make no guarantees regarding the contents of `dest` on error. If `dest` is\n/// empty, `getrandom` immediately returns success, making no calls to the\n/// underlying operating system.\n///\n/// Blocking is possible, at least during early boot; see module documentation.\n///\n/// In general, `getrandom` will be fast enough for interactive usage, though\n/// significantly slower than a user-space CSPRNG; for the latter consider\n/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).\n///\n/// # Examples\n///\n/// ```\n/// # fn main() -> Result<(), getrandom::Error> {\n/// let mut buf = [0u8; 32];\n/// getrandom::fill(&mut buf)?;\n/// # Ok(()) }\n/// ```\n#[inline]\npub fn fill(dest: &mut [u8]) -> Result<(), Error> {\n    // SAFETY: The `&mut MaybeUninit<_>` reference doesn't escape,\n    // and `fill_uninit` guarantees it will never de-initialize\n    // any part of `dest`.\n    fill_uninit(unsafe { util::slice_as_uninit_mut(dest) })?;\n    Ok(())\n}\n\n/// Fill potentially uninitialized buffer `dest` with random bytes from\n/// the system's preferred random number source and return a mutable\n/// reference to those bytes.\n///\n/// On successful completion this function is guaranteed to return a slice\n/// which points to the same memory as `dest` and has the same length.\n/// In other words, it's safe to assume that `dest` is initialized after\n/// this function has returned `Ok`.\n///\n/// No part of `dest` will ever be de-initialized at any point, regardless\n/// of what is returned.\n///\n/// # Examples\n///\n/// ```ignore\n/// # // We ignore this test since `uninit_array` is unstable.\n/// #![feature(maybe_uninit_uninit_array)]\n/// # fn main() -> Result<(), getrandom::Error> {\n/// let mut buf = core::mem::MaybeUninit::uninit_array::<1024>();\n/// let buf: &mut [u8] = getrandom::fill_uninit(&mut buf)?;\n/// # Ok(()) }\n/// ```\n#[inline]\npub fn fill_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {\n    if !dest.is_empty() {\n        backends::fill_inner(dest)?;\n    }\n\n    #[cfg(getrandom_msan)]\n    unsafe extern \"C\" {\n        fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize);\n    }\n\n    // SAFETY: `dest` has been fully initialized by `imp::fill_inner`\n    // since it returned `Ok`.\n    Ok(unsafe { util::slice_assume_init_mut(dest) })\n}\n\n/// Get random `u32` from the system's preferred random number source.\n///\n/// # Examples\n///\n/// ```\n/// # fn main() -> Result<(), getrandom::Error> {\n/// let rng_seed = getrandom::u32()?;\n/// # Ok(()) }\n/// ```\n#[inline]\npub fn u32() -> Result<u32, Error> {\n    backends::inner_u32()\n}\n\n/// Get random `u64` from the system's preferred random number source.\n///\n/// # Examples\n///\n/// ```\n/// # fn main() -> Result<(), getrandom::Error> {\n/// let rng_seed = getrandom::u64()?;\n/// # Ok(()) }\n/// ```\n#[inline]\npub fn u64() -> Result<u64, Error> {\n    backends::inner_u64()\n}\n"
  },
  {
    "path": "src/sys_rng.rs",
    "content": "use crate::Error;\nuse rand_core::{TryCryptoRng, TryRng};\n\n/// A [`TryRng`] interface over the system's preferred random number source\n///\n/// This is a zero-sized struct. It can be freely constructed with just `SysRng`.\n///\n/// This struct is also available as [`rand::rngs::SysRng`] when using [rand].\n///\n/// # Usage example\n///\n/// `SysRng` implements [`TryRng`]:\n/// ```\n/// use getrandom::{rand_core::TryRng, SysRng};\n///\n/// let mut key = [0u8; 32];\n/// SysRng.try_fill_bytes(&mut key).unwrap();\n/// ```\n///\n/// Using it as an [`Rng`] is possible using [`UnwrapErr`]:\n/// ```\n/// use getrandom::rand_core::{Rng, UnwrapErr};\n/// use getrandom::SysRng;\n///\n/// let mut rng = UnwrapErr(SysRng);\n/// let random_u64 = rng.next_u64();\n/// ```\n///\n/// [rand]: https://crates.io/crates/rand\n/// [`rand::rngs::SysRng`]: https://docs.rs/rand/latest/rand/rngs/struct.SysRng.html\n/// [`Rng`]: rand_core::Rng\n/// [`UnwrapErr`]: rand_core::UnwrapErr\n#[derive(Clone, Copy, Debug, Default)]\npub struct SysRng;\n\nimpl TryRng for SysRng {\n    type Error = Error;\n\n    #[inline]\n    fn try_next_u32(&mut self) -> Result<u32, Error> {\n        crate::u32()\n    }\n\n    #[inline]\n    fn try_next_u64(&mut self) -> Result<u64, Error> {\n        crate::u64()\n    }\n\n    #[inline]\n    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {\n        crate::fill(dest)\n    }\n}\n\nimpl TryCryptoRng for SysRng {}\n"
  },
  {
    "path": "src/util.rs",
    "content": "#![allow(dead_code)]\nuse crate::Error;\nuse core::{mem::MaybeUninit, ptr, slice};\n\n/// Polyfill for `maybe_uninit_slice` feature's\n/// `MaybeUninit::slice_assume_init_mut`. Every element of `slice` must have\n/// been initialized.\n#[inline(always)]\npub unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {\n    let ptr = ptr::from_mut(slice) as *mut [T];\n    // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.\n    unsafe { &mut *ptr }\n}\n\n#[inline]\npub fn uninit_slice_fill_zero(slice: &mut [MaybeUninit<u8>]) -> &mut [u8] {\n    unsafe { ptr::write_bytes(slice.as_mut_ptr(), 0, slice.len()) };\n    unsafe { slice_assume_init_mut(slice) }\n}\n\n#[inline(always)]\npub fn slice_as_uninit<T>(slice: &[T]) -> &[MaybeUninit<T>] {\n    let ptr = ptr::from_ref(slice) as *const [MaybeUninit<T>];\n    // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.\n    unsafe { &*ptr }\n}\n\n/// View an mutable initialized array as potentially-uninitialized.\n///\n/// This is unsafe because it allows assigning uninitialized values into\n/// `slice`, which would be undefined behavior.\n#[inline(always)]\npub unsafe fn slice_as_uninit_mut<T>(slice: &mut [T]) -> &mut [MaybeUninit<T>] {\n    let ptr = ptr::from_mut(slice) as *mut [MaybeUninit<T>];\n    // SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.\n    unsafe { &mut *ptr }\n}\n\n/// Default implementation of `inner_u32` on top of `fill_uninit`\n#[inline]\npub fn inner_u32() -> Result<u32, Error> {\n    let mut res = MaybeUninit::<u32>::uninit();\n    // SAFETY: the created slice has the same size as `res`\n    let dst = unsafe {\n        let p: *mut MaybeUninit<u8> = res.as_mut_ptr().cast();\n        slice::from_raw_parts_mut(p, core::mem::size_of::<u32>())\n    };\n    crate::fill_uninit(dst)?;\n    // SAFETY: `dst` has been fully initialized by `imp::fill_inner`\n    // since it returned `Ok`.\n    Ok(unsafe { res.assume_init() })\n}\n\n/// Default implementation of `inner_u64` on top of `fill_uninit`\n#[inline]\npub fn inner_u64() -> Result<u64, Error> {\n    let mut res = MaybeUninit::<u64>::uninit();\n    // SAFETY: the created slice has the same size as `res`\n    let dst = unsafe {\n        let p: *mut MaybeUninit<u8> = res.as_mut_ptr().cast();\n        slice::from_raw_parts_mut(p, core::mem::size_of::<u64>())\n    };\n    crate::fill_uninit(dst)?;\n    // SAFETY: `dst` has been fully initialized by `imp::fill_inner`\n    // since it returned `Ok`.\n    Ok(unsafe { res.assume_init() })\n}\n\n/// Truncates `u64` and returns the lower 32 bits as `u32`\npub(crate) fn truncate(val: u64) -> u32 {\n    u32::try_from(val & u64::from(u32::MAX)).expect(\"The higher 32 bits are masked\")\n}\n"
  },
  {
    "path": "src/utils/get_errno.rs",
    "content": "cfg_if! {\n    if #[cfg(any(target_os = \"netbsd\", target_os = \"openbsd\", target_os = \"android\", target_os = \"cygwin\"))] {\n        use libc::__errno as errno_location;\n    } else if #[cfg(any(target_os = \"linux\", target_os = \"emscripten\", target_os = \"hurd\", target_os = \"redox\", target_os = \"dragonfly\"))] {\n        use libc::__errno_location as errno_location;\n    } else if #[cfg(target_os = \"illumos\")] {\n        use libc::___errno as errno_location;\n    } else if #[cfg(any(target_os = \"macos\", target_os = \"freebsd\"))] {\n        use libc::__error as errno_location;\n    } else if #[cfg(target_os = \"haiku\")] {\n        use libc::_errnop as errno_location;\n    } else if #[cfg(target_os = \"nto\")] {\n        use libc::__get_errno_ptr as errno_location;\n    } else if #[cfg(any(all(target_os = \"horizon\", target_arch = \"arm\"), target_os = \"vita\"))] {\n        unsafe extern \"C\" {\n            // Not provided by libc: https://github.com/rust-lang/libc/issues/1995\n            fn __errno() -> *mut libc::c_int;\n        }\n        use __errno as errno_location;\n    } else if #[cfg(target_os = \"aix\")] {\n        use libc::_Errno as errno_location;\n    } else {\n        compile_error!(\"errno_location is not provided for the target\");\n    }\n}\n\npub(crate) fn get_errno() -> libc::c_int {\n    unsafe { core::ptr::read(errno_location()) }\n}\n"
  },
  {
    "path": "src/utils/lazy_bool.rs",
    "content": "use core::sync::atomic::{AtomicU8, Ordering::Relaxed};\n\n/// Lazily caches a `bool` in an `AtomicU8`.\n///\n/// Initialization is intentionally unsynchronized: concurrent callers may race\n/// and run `init` more than once. Once a value is produced, it is cached and\n/// reused by subsequent calls.\n///\n/// Uses `Relaxed` ordering because this helper only publishes the cached\n/// value itself.\npub(crate) struct LazyBool(AtomicU8);\n\nimpl LazyBool {\n    const UNINIT: u8 = u8::MAX;\n\n    /// Create new `LazyBool`.\n    pub const fn new() -> Self {\n        Self(AtomicU8::new(Self::UNINIT))\n    }\n\n    /// Call the `init` closure and return the result after caching it.\n    #[cold]\n    fn cold_init(&self, init: impl FnOnce() -> bool) -> bool {\n        let val = u8::from(init());\n        self.0.store(val, Relaxed);\n        val != 0\n    }\n\n    /// Retrieve the cached value if it was already initialized or call the `init` closure\n    /// and return the result after caching it.\n    #[inline]\n    pub fn unsync_init(&self, init: impl FnOnce() -> bool) -> bool {\n        let val = self.0.load(Relaxed);\n        if val == Self::UNINIT {\n            return self.cold_init(init);\n        }\n        val != 0\n    }\n}\n"
  },
  {
    "path": "src/utils/lazy_ptr.rs",
    "content": "use core::{\n    convert::Infallible,\n    ptr::{self, NonNull},\n    sync::atomic::{AtomicPtr, Ordering::Relaxed},\n};\n\n/// Lazily caches a non-null pointer in an `AtomicPtr`.\n///\n/// Initialization is intentionally unsynchronized: concurrent callers may race\n/// and run `init` more than once. Once a value is produced, it is cached and\n/// reused by subsequent calls.\n///\n/// For fallible initialization (`try_unsync_init`), only successful values are\n/// cached; errors are returned to the caller and are not cached.\n///\n/// Uses `Ordering::Relaxed` because this helper only publishes the cached\n/// pointer value. Callers must not rely on this mechanism to synchronize\n/// unrelated memory side effects performed by `init`.\npub(crate) struct LazyPtr<T>(AtomicPtr<T>);\n\nimpl<T> LazyPtr<T> {\n    /// Create new `LazyPtr`.\n    pub const fn new() -> Self {\n        Self(AtomicPtr::new(ptr::null_mut()))\n    }\n\n    /// Call the `init` closure and return the result after caching it in the case of success.\n    #[cold]\n    fn cold_init<E>(&self, init: impl FnOnce() -> Result<NonNull<T>, E>) -> Result<NonNull<T>, E> {\n        let val = init()?;\n        self.0.store(val.as_ptr(), Relaxed);\n        Ok(val)\n    }\n\n    /// Retrieve the cached value if it was already initialized or call the potentially fallible\n    /// `init` closure and return the result after caching it in the case of success.\n    #[inline]\n    pub fn try_unsync_init<E>(\n        &self,\n        init: impl FnOnce() -> Result<NonNull<T>, E>,\n    ) -> Result<NonNull<T>, E> {\n        let p = self.0.load(Relaxed);\n        match NonNull::new(p) {\n            Some(val) => Ok(val),\n            None => self.cold_init(init),\n        }\n    }\n\n    /// Retrieve the cached value if it was already initialized or call the `init` closure\n    /// and return the result after caching it.\n    #[inline]\n    #[allow(dead_code, reason = \"Some modules use only `try_unsync_init`\")]\n    pub fn unsync_init(&self, init: impl FnOnce() -> NonNull<T>) -> NonNull<T> {\n        let Ok(p): Result<_, Infallible> = self.try_unsync_init(|| Ok(init()));\n        p\n    }\n}\n"
  },
  {
    "path": "src/utils/sanitizer.rs",
    "content": "use core::mem::MaybeUninit;\n\n/// Unpoisons `buf` if MSAN support is enabled.\n///\n/// Most backends do not need to unpoison their output. Rust language- and\n/// library- provided functionality unpoisons automatically. Similarly, libc\n/// either natively supports MSAN and/or MSAN hooks libc-provided functions\n/// to unpoison outputs on success. Only when all of these things are\n/// bypassed do we need to do it ourselves.\n///\n/// The call to unpoison should be done as close to the write as possible.\n/// For example, if the backend partially fills the output buffer in chunks,\n/// each chunk should be unpoisoned individually. This way, the correctness of\n/// the chunking logic can be validated (in part) using MSAN.\npub unsafe fn unpoison(buf: &mut [MaybeUninit<u8>]) {\n    cfg_if! {\n        if #[cfg(getrandom_msan)] {\n            unsafe extern \"C\" {\n                fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize);\n            }\n            let a = buf.as_mut_ptr().cast();\n            let size = buf.len();\n            unsafe { __msan_unpoison(a, size) };\n        } else {\n            let _ = buf;\n        }\n    }\n}\n"
  },
  {
    "path": "src/utils/sys_fill_exact.rs",
    "content": "use crate::Error;\nuse core::mem::MaybeUninit;\n\nmod get_errno;\nmod sanitizer;\n\npub(crate) use get_errno::get_errno;\n\n/// Fill a buffer by repeatedly invoking `sys_fill`.\n///\n/// The `sys_fill` function:\n///   - should return -1 and set errno on failure\n///   - should return the number of bytes written on success\npub(crate) fn sys_fill_exact(\n    mut buf: &mut [MaybeUninit<u8>],\n    sys_fill: impl Fn(&mut [MaybeUninit<u8>]) -> libc::ssize_t,\n) -> Result<(), Error> {\n    while !buf.is_empty() {\n        let res = sys_fill(buf);\n        match res {\n            res if res > 0 => {\n                let len = usize::try_from(res).map_err(|_| Error::UNEXPECTED)?;\n                let (l, r) = buf.split_at_mut_checked(len).ok_or(Error::UNEXPECTED)?;\n                unsafe { sanitizer::unpoison(l) };\n                buf = r;\n            }\n            -1 => {\n                let errno = get_errno();\n                // We should try again if the call was interrupted.\n                if errno != libc::EINTR {\n                    return Err(Error::from_errno(errno));\n                }\n            }\n            // Negative return codes not equal to -1 should be impossible.\n            // EOF (ret = 0) should be impossible, as the data we are reading\n            // should be an infinite stream of random bytes.\n            _ => return Err(Error::UNEXPECTED),\n        }\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "tests/mod.rs",
    "content": "//! Main `getrandom` tests\nuse core::mem::MaybeUninit;\nuse getrandom::{fill, fill_uninit};\n\n#[cfg(all(feature = \"wasm_js\", target_arch = \"wasm32\", target_os = \"unknown\"))]\nuse wasm_bindgen_test::wasm_bindgen_test as test;\n\n#[test]\nfn test_zero() {\n    // Test that APIs are happy with zero-length requests\n    fill(&mut [0u8; 0]).unwrap();\n    let res = fill_uninit(&mut []).unwrap();\n    assert!(res.is_empty());\n}\n\ntrait DiffBits: Sized {\n    fn diff_bits(ab: (&Self, &Self)) -> usize;\n}\n\nimpl DiffBits for u8 {\n    fn diff_bits((a, b): (&Self, &Self)) -> usize {\n        (a ^ b).count_ones() as usize\n    }\n}\n\nimpl DiffBits for u32 {\n    fn diff_bits((a, b): (&Self, &Self)) -> usize {\n        (a ^ b).count_ones() as usize\n    }\n}\n\nimpl DiffBits for u64 {\n    fn diff_bits((a, b): (&Self, &Self)) -> usize {\n        (a ^ b).count_ones() as usize\n    }\n}\n\n// Return the number of bits in which s1 and s2 differ\nfn num_diff_bits<T: DiffBits>(s1: &[T], s2: &[T]) -> usize {\n    assert_eq!(s1.len(), s2.len());\n    s1.iter().zip(s2.iter()).map(T::diff_bits).sum()\n}\n\n// Tests the quality of calling getrandom on two large buffers\n#[test]\nfn test_diff() {\n    const N: usize = 1000;\n    let mut v1 = [0u8; N];\n    let mut v2 = [0u8; N];\n    fill(&mut v1).unwrap();\n    fill(&mut v2).unwrap();\n\n    let mut t1 = [MaybeUninit::uninit(); N];\n    let mut t2 = [MaybeUninit::uninit(); N];\n    let r1 = fill_uninit(&mut t1).unwrap();\n    let r2 = fill_uninit(&mut t2).unwrap();\n    assert_eq!(r1.len(), N);\n    assert_eq!(r2.len(), N);\n\n    // Between 3.5 and 4.5 bits per byte should differ. Probability of failure:\n    // ~ 2^(-94) = 2 * CDF[BinomialDistribution[8000, 0.5], 3500]\n    let d1 = num_diff_bits(&v1, &v2);\n    assert!(d1 > 3500);\n    assert!(d1 < 4500);\n    let d2 = num_diff_bits(r1, r2);\n    assert!(d2 > 3500);\n    assert!(d2 < 4500);\n}\n\n#[test]\nfn test_diff_u32() {\n    const N: usize = 1000 / 4;\n    let mut v1 = [0u32; N];\n    let mut v2 = [0u32; N];\n    for v in v1.iter_mut() {\n        *v = getrandom::u32().unwrap();\n    }\n    for v in v2.iter_mut() {\n        *v = getrandom::u32().unwrap();\n    }\n\n    // Between 3.5 and 4.5 bits per byte should differ. Probability of failure:\n    // ~ 2^(-94) = 2 * CDF[BinomialDistribution[8000, 0.5], 3500]\n    let d1 = num_diff_bits(&v1, &v2);\n    assert!(d1 > 3500);\n    assert!(d1 < 4500);\n}\n\n#[test]\nfn test_diff_u64() {\n    const N: usize = 1000 / 8;\n    let mut v1 = [0u64; N];\n    let mut v2 = [0u64; N];\n    for v in v1.iter_mut() {\n        *v = getrandom::u64().unwrap();\n    }\n    for v in v2.iter_mut() {\n        *v = getrandom::u64().unwrap();\n    }\n\n    // Between 3.5 and 4.5 bits per byte should differ. Probability of failure:\n    // ~ 2^(-94) = 2 * CDF[BinomialDistribution[8000, 0.5], 3500]\n    let d1 = num_diff_bits(&v1, &v2);\n    assert!(d1 > 3500);\n    assert!(d1 < 4500);\n}\n\n#[test]\nfn test_small() {\n    const N: usize = 64;\n    // For each buffer size, get at least 256 bytes and check that between\n    // 3 and 5 bits per byte differ. Probability of failure:\n    // ~ 2^(-91) = 64 * 2 * CDF[BinomialDistribution[8*256, 0.5], 3*256]\n    for size in 1..=N {\n        let mut num_bytes = 0;\n        let mut diff_bits = 0;\n        while num_bytes < 256 {\n            let mut buf1 = [0u8; N];\n            let mut buf2 = [0u8; N];\n\n            let s1 = &mut buf1[..size];\n            let s2 = &mut buf2[..size];\n\n            fill(s1).unwrap();\n            fill(s2).unwrap();\n\n            num_bytes += size;\n            diff_bits += num_diff_bits(s1, s2);\n        }\n        assert!(diff_bits > 3 * num_bytes);\n        assert!(diff_bits < 5 * num_bytes);\n    }\n}\n\n// Tests the quality of calling getrandom repeatedly on small buffers\n#[test]\nfn test_small_uninit() {\n    const N: usize = 64;\n    // For each buffer size, get at least 256 bytes and check that between\n    // 3 and 5 bits per byte differ. Probability of failure:\n    // ~ 2^(-91) = 64 * 2 * CDF[BinomialDistribution[8*256, 0.5], 3*256]\n    for size in 1..=N {\n        let mut num_bytes = 0;\n        let mut diff_bits = 0;\n        while num_bytes < 256 {\n            let mut buf1 = [MaybeUninit::uninit(); N];\n            let mut buf2 = [MaybeUninit::uninit(); N];\n\n            let s1 = &mut buf1[..size];\n            let s2 = &mut buf2[..size];\n\n            let r1 = fill_uninit(s1).unwrap();\n            let r2 = fill_uninit(s2).unwrap();\n            assert_eq!(r1.len(), size);\n            assert_eq!(r2.len(), size);\n\n            num_bytes += size;\n            diff_bits += num_diff_bits(r1, r2);\n        }\n        assert!(diff_bits > 3 * num_bytes);\n        assert!(diff_bits < 5 * num_bytes);\n    }\n}\n\n#[test]\nfn test_huge() {\n    let mut huge = [0u8; 100_000];\n    fill(&mut huge).unwrap();\n}\n\n#[test]\nfn test_huge_uninit() {\n    const N: usize = 100_000;\n    let mut huge = [MaybeUninit::uninit(); N];\n    let res = fill_uninit(&mut huge).unwrap();\n    assert_eq!(res.len(), N);\n}\n\n#[test]\n#[cfg_attr(\n    target_arch = \"wasm32\",\n    ignore = \"The thread API always fails/panics on WASM\"\n)]\nfn test_multithreading() {\n    extern crate std;\n    use std::{sync::mpsc::channel, thread, vec};\n\n    let mut txs = vec![];\n    for _ in 0..20 {\n        let (tx, rx) = channel();\n        txs.push(tx);\n\n        thread::spawn(move || {\n            // wait until all the tasks are ready to go.\n            rx.recv().unwrap();\n            let mut v = [0u8; 1000];\n\n            for _ in 0..100 {\n                fill(&mut v).unwrap();\n                thread::yield_now();\n            }\n        });\n    }\n\n    // start all the tasks\n    for tx in txs.iter() {\n        tx.send(()).unwrap();\n    }\n}\n"
  },
  {
    "path": "tests/sys_rng.rs",
    "content": "//! Tests for `SysRng`\n#![cfg(feature = \"sys_rng\")]\n\nuse getrandom::SysRng;\nuse getrandom::rand_core::TryRng;\n\n#[test]\nfn test_sys_rng() {\n    let x = SysRng.try_next_u64().unwrap();\n    let y = SysRng.try_next_u64().unwrap();\n    assert!(x != 0);\n    assert!(x != y);\n}\n\n#[test]\nfn test_construction() {\n    assert!(SysRng.try_next_u64().unwrap() != 0);\n}\n"
  }
]