From 590829bd1cab0c53ce6ca188fffad3268552a6b0 Mon Sep 17 00:00:00 2001 From: Joe Birr-Pixton Date: Thu, 5 Sep 2024 10:15:26 +0100 Subject: [PATCH] add ctgrind-like testing of CodePoint::decode_secret --- .github/workflows/ci.yml | 34 ++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +++ src/base64.rs | 21 +++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ba2f08..c61870a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,10 @@ jobs: with: toolchain: ${{ matrix.rust }} + - name: Install valgrind + if: runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y valgrind + - name: cargo test (debug; default features) run: cargo test env: @@ -166,3 +170,33 @@ jobs: for target in $(cargo fuzz list) ; do cargo fuzz run $target -- -max_total_time=10 done + + valgrind: + name: Check side-channels on base64 decoder + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install stable toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Install valgrind + if: runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y valgrind + + - name: Build and run test + run: > + cargo test --all-features --lib + valgrind + --error-exitcode=99 + --exit-on-first-error=yes + $(cargo test --all-features --no-run --message-format json | + jq --slurp --raw-output + '.[] | ' + 'select(.reason == "compiler-artifact") | ' + 'select(.target.name == "rustls_pki_types") | ' + 'select(.profile.test) | ' + '.executable') diff --git a/Cargo.toml b/Cargo.toml index b6babfe..b1bf88e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,9 @@ alloc = [] std = ["alloc"] web = ["web-time"] +[target.'cfg(all(target_os = "linux", target_arch = "x86_64"))'.dev-dependencies] +crabgrind = "0.1" + [target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies] web-time = { version = "1", optional = true } diff --git a/src/base64.rs b/src/base64.rs index fe0099b..54ec1f8 100644 --- a/src/base64.rs +++ b/src/base64.rs @@ -702,6 +702,27 @@ mod tests { } } + #[test] + fn codepoint_decode_secret_does_not_branch_or_index_on_secret_input() { + // this is using the same theory as + use crabgrind as cg; + + if matches!(cg::run_mode(), cg::RunMode::Native) { + std::println!("SKIPPED: must be run under valgrind"); + return; + } + + let input = [b'a']; + cg::monitor_command(format!( + "make_memory undefined {:p} {}", + input.as_ptr(), + input.len() + )) + .unwrap(); + + core::hint::black_box(CodePoint::decode_secret(input[0])); + } + #[track_caller] fn decode(input: &[u8]) -> alloc::vec::Vec { let length = decoded_length(input.len());