Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,27 @@ jobs:
- name: Clippy (no-default-features)
run: cargo clippy --all-targets --no-default-features -- -D warnings

zeroization-test:
name: Run the zeroization test
needs: [style]
runs-on: ubuntu-latest

steps:
- name: Checkout the repo
uses: actions/checkout@v4

- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
components: clippy

- uses: Swatinem/rust-cache@v2

- name: Zeroization test
working-directory: ./contrib/zeroization-test
run: make

test:
name: ${{ matrix.target.name }} ${{ matrix.channel }}
needs: [clippy]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ Cargo.lock
.gdb_history
/afl/*/target
/afl/*/out*
/contrib/*/target
mutants.out*
4 changes: 1 addition & 3 deletions contrib/zeroization-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
name = "vodozemac-zeroization-test"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
publish = false

[profile.release]
debug = true

[dependencies]
vodozemac = { path = "../.." }
ed25519-dalek = "1.0.1"
10 changes: 5 additions & 5 deletions contrib/zeroization-test/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use vodozemac::cipher::key::ExpandedKeys;
use vodozemac::Ed25519SecretKey;

fn use_keys(_keys: ExpandedKeys) {
fn use_keys(_keys: Ed25519SecretKey) {
println!("Point B. Using keys...");
}

fn main() {
// Used for comparison from inside gdb, to ensure the buffer is zeroized.
let _zero: [u8; 80] = [0u8; 80];
let _zero = [0u8; 32];

let secret: [u8; 32] = (0..32).collect::<Vec<_>>().try_into().unwrap();
let secret = [0xFFu8; 32];
println!("Point A. Creating keys...");
let keys = ExpandedKeys::new(&secret);
let keys = Ed25519SecretKey::from_slice(&secret);
use_keys(keys);
println!("Point C. `keys` was dropped so buffer should now be zeroized.")
}
52 changes: 11 additions & 41 deletions contrib/zeroization-test/test_zeroization.txt
Original file line number Diff line number Diff line change
@@ -1,47 +1,25 @@
define is_zeroized_partial
set $addr_to_check = $arg0

# XXX: $_memeq is broken right now and treats the third argument as the number
# of 4-byte words instead of bytes.
if $_memeq(($addr_to_check as *u8) + 16, $zero, 16)
printf "✅ Object at addr %p partially zeroized (last 64 bytes are zero)\n", $addr_to_check
x/80b $addr_to_check
else
printf "❌ Object at addr %p *NOT* even partially zeroized (last 64 bytes are not zero)\n", $addr_to_check
x/80b $addr_to_check
quit 2
end
end

document is_zeroized_partial
Checks whether the object at $arg0 is zeroized.

Since free writes some stuff to the first 16 bytes of the buffer, this version
only checks that the last 80 - 16 = 64 bytes are zeroized.
end

define is_zeroized_full
set $addr_to_check = $arg0

# XXX: $_memeq is broken right now and treats the third argument as the number
# of 4-byte words instead of bytes.
if $_memeq($addr_to_check as *u8, $zero, 20)
if $_memeq($addr_to_check as *u8, $zero, 8)
printf "✅ Object at addr %p fully zeroized\n", $addr_to_check
x/80b $addr_to_check
x/32bx $addr_to_check
else
printf "❌ Object at addr %p *NOT* fully zeroized\n", $addr_to_check
x/80b $addr_to_check
x/32bx $addr_to_check
quit 1
end
end

document is_zeroized_full
Checks whether the object at $arg0 is fully zeroized (all of its 80 bytes are
Checks whether the object at $arg0 is fully zeroized (all of its 32 bytes are
zero).
end

# Point B
break use_keys
break vodozemac_zeroization_test::use_keys

run

Expand All @@ -51,11 +29,11 @@ run
# We save the address of both the original buffer in the frame above and the
# address of the current buffer in `use_keys`.
up
set $addr1 = keys.0
set $addr1 = keys.0.secret_key
set $zero = &_zero

down
set $addr2 = _keys.0
set $addr2 = _keys.0.secret_key


# Since we've placed the buffer behind a Box, these addresses should be the
Expand All @@ -73,16 +51,16 @@ end
# Then we ensure the buffer is not already all zeros, since that almost surely
# indicates that something is wrong.

if $_memeq($addr1, $addr2, 20)
if $_memeq($addr1, $addr2, 32)
printf "✅ The objects have the same content.\n"
else
printf "❌ The objects have *different* content.\n"
quit 1
end

if ! $_memeq($addr1, $zero, 20)
if ! $_memeq($addr1, $zero, 32)
printf "✅ This content isn't all null bytes.\n"
x/80b $addr1
x/32bx $addr1
else
printf "❌ This content *is* all null bytes.\n"
quit 2
Expand All @@ -94,20 +72,12 @@ break free
break 16

# Proceed to the next `free` call. The object should have already been dropped
# and should be fully zeroized (all 80 bytes).
# and should be fully zeroized (all 32 bytes).
continue

is_zeroized_full $addr1
is_zeroized_full $addr2

# Proceed to point C. Since `free` wrote some stuff to the buffer, it should
# now only be partially equal to zero, namely its 64 trailing bytes. Check for
# this.
continue

is_zeroized_partial $addr1
is_zeroized_partial $addr2

# If all was well, we've arrived at this point and the script will finish with
# a success exit code. If something went wrong, we've never reached this point
# and returned a non-zero exit code.