name: Security validation
on:
push:
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: security-validation-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: "1"
jobs:
implementation-boundary:
name: Zero unsafe / zero FFI implementation boundary
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install stable Rust and every supported compilation target
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: stable
targets: aarch64-unknown-linux-gnu,wasm32-unknown-unknown,thumbv7em-none-eabihf
- name: Audit compiled and packaged implementation boundaries
run: |
python3 tools/verify-implementation-boundary.py --self-test
python3 tools/verify-remote-release-ready.py --self-test
tools/verify-implementation-boundary.sh
- name: Inspect optimized BLS secret-scalar assembly
run: tools/verify-bls-secret-assembly.sh
- name: Inspect optimized owned GHASH assembly
run: tools/verify-ghash-assembly.sh
format-and-check:
name: Format and all-target workspace check
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install stable Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: stable
components: rustfmt
- name: Check formatting
run: |
cargo fmt --all -- --check
cargo fmt --manifest-path verification/Cargo.toml -- --check
cargo fmt --manifest-path fuzz/Cargo.toml -- --check
cargo fmt --manifest-path migration/legacy-xchacha20poly1305/Cargo.toml -- --check
- name: Check every workspace target with every feature
run: |
cargo check --workspace --all-targets --all-features
RUSTFLAGS="-Dunsafe-code" cargo check --locked --all-targets --all-features \
--manifest-path migration/legacy-xchacha20poly1305/Cargo.toml
workspace-tests:
name: Workspace crate tests
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install stable Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: stable
- name: Run workspace library and integration tests
run: |
cargo test --workspace --all-features --exclude dcrypt-tests --no-fail-fast
cargo test -p dcrypt-tests --lib --all-features
acvp-and-aes-cbc-properties:
name: Complete ACVP and AES-CBC property gates
runs-on: ubuntu-24.04
timeout-minutes: 180
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install stable Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: stable
- name: Run every official ACVP and regression-vector test
run: >-
cargo test --release -p dcrypt-tests --test acvp_tests
-- --test-threads=1 --nocapture
- name: Run the AES-CBC property suite
run: >-
cargo test --release -p dcrypt-tests --test property_aes_cbc
-- --test-threads=1 --nocapture
independent-oracles:
name: Excluded independent interoperability oracles
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install stable Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: stable
- name: Run the non-published differential verification workspace
run: cargo test --release --locked --manifest-path verification/Cargo.toml
- name: Test the isolated decrypt-only legacy migration tool
run: >-
cargo test --release --locked --manifest-path
migration/legacy-xchacha20poly1305/Cargo.toml
statistical-timing:
name: Repository statistical timing regressions (not dudect or ctgrind)
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install stable Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: stable
- name: Run the in-repository statistical timing suite serially
env:
VERBOSE: "1"
run: >-
cargo test -p dcrypt-tests --test constant_time_tests
-- --test-threads=1 --nocapture
dependency-policy:
name: RustSec and workspace dependency policy
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install stable Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: stable
- name: Install pinned security tools
run: |
cargo install --root "$RUNNER_TEMP/security-tools" cargo-audit --version 0.22.2 --locked
cargo install --root "$RUNNER_TEMP/security-tools" cargo-deny --version 0.20.2 --locked
echo "$RUNNER_TEMP/security-tools/bin" >> "$GITHUB_PATH"
- name: Audit resolved dependencies against RustSec
run: |
cargo audit
while IFS=$'\t' read -r category workspace; do
test -n "$category" && test -n "$workspace"
cargo audit --file "$workspace/Cargo.lock"
done < <(python3 tools/verify-implementation-boundary.py --list-classified-workspaces)
- name: Enforce advisories, licenses, bans, and sources for all workspace roots
run: |
cargo deny --workspace --all-features check
while IFS=$'\t' read -r category workspace; do
test -n "$category" && test -n "$workspace"
cargo deny --manifest-path "$workspace/Cargo.toml" \
--all-features check
done < <(python3 tools/verify-implementation-boundary.py --list-classified-workspaces)
miri:
name: Miri (${{ matrix.crate }})
runs-on: ubuntu-24.04
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
crate: [dcrypt-api, dcrypt-common]
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install nightly Rust with Miri
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: nightly-2026-08-07
components: miri
- name: Prepare Miri's sysroot
run: cargo miri setup
- name: Run the public memory-handling tests under Miri
run: cargo miri test -p ${{ matrix.crate }} --lib --all-features
miri-crypto-boundaries:
name: Miri cryptographic parser and key boundaries
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install nightly Rust with Miri
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: nightly-2026-08-07
components: miri
- name: Prepare Miri's sysroot
run: cargo miri setup
- name: Exercise ML-KEM canonical decoder boundaries
run: cargo miri test -p dcrypt-kem --lib --all-features miri_
- name: Exercise ML-DSA expanded-key coherence checks
run: >-
cargo miri test -p dcrypt-sign --lib --all-features
expanded_key_decoder_rejects_malformed_or_incoherent_components
- name: Exercise Ed25519 strict verification
run: >-
cargo miri test -p dcrypt-sign --lib --all-features
rejects_identity_public_key_and_universal_forgery
- name: Exercise the high-level BLS secret owner
run: >-
cargo miri test -p dcrypt-sign --lib --all-features
secret_key_is_canonical_nonzero_and_debug_redacted
- name: Exercise both protected BLS scalar bridges
run: >-
cargo miri test -p dcrypt-algorithms --lib --all-features
secret_big_endian_bridge_matches_g1_and_g2_scalar_multiplication
- name: Exercise RFC 9380 and BLS subgroup rejection
run: |
cargo miri test -p dcrypt-algorithms --lib --all-features rfc9380_g1_random_oracle_vectors
cargo miri test -p dcrypt-algorithms --lib --all-features rfc9380_g2_random_oracle_vectors
cargo miri test -p dcrypt-algorithms --lib --all-features checked_decoders_reject_on_curve_non_subgroup_point
bounded-fuzz:
name: Build and exercise externally controlled decoder fuzz targets
runs-on: ubuntu-24.04
timeout-minutes: 90
steps:
- name: Check out the repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Install nightly Rust
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772
with:
toolchain: nightly-2026-08-07
- name: Install pinned cargo-fuzz
run: cargo install cargo-fuzz --version 0.13.2 --locked
- name: Build and run every classified fuzz target
run: |
while IFS=$'\t' read -r category workspace; do
test -n "$category" && test -n "$workspace"
test "$category" = fuzz || continue
(
cd "$workspace"
mapfile -t fuzz_targets < <(cargo fuzz list)
test "${#fuzz_targets[@]}" -gt 0
for fuzz_target in "${fuzz_targets[@]}"; do
test -n "$fuzz_target"
cargo fuzz build "$fuzz_target"
cargo fuzz run "$fuzz_target" -- -runs=1000 -seed=424242
done
)
done < <(python3 tools/verify-implementation-boundary.py --list-classified-workspaces)