diff --git a/.github/workflows/zeroize.yml b/.github/workflows/zeroize.yml index fc3731a9..b9fbbee6 100644 --- a/.github/workflows/zeroize.yml +++ b/.github/workflows/zeroize.yml @@ -64,4 +64,26 @@ jobs: override: true profile: minimal - run: cargo test --release - - run: cargo test --release --all-features + - run: cargo test --release --features alloc,derive + + # Feature-gated ARM64 SIMD register support (nightly-only) + aarch64: + strategy: + matrix: + include: + - target: aarch64-unknown-linux-gnu + rust: nightly-2022-03-01 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: RustCrypto/actions/cargo-cache@master + - run: ${{ matrix.deps }} + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + profile: minimal + override: true + - uses: RustCrypto/actions/cross-install@master + - run: cross test --release --target ${{ matrix.target }} --features aarch64 + - run: cross test --release --target ${{ matrix.target }} --all-features diff --git a/zeroize/Cargo.toml b/zeroize/Cargo.toml index 9be9e7ab..35b7a268 100644 --- a/zeroize/Cargo.toml +++ b/zeroize/Cargo.toml @@ -21,6 +21,7 @@ zeroize_derive = { version = "1.3", path = "derive", optional = true } [features] default = ["alloc"] +aarch64 = [] alloc = [] derive = ["zeroize_derive"] diff --git a/zeroize/src/aarch64.rs b/zeroize/src/aarch64.rs new file mode 100644 index 00000000..fc6c8f23 --- /dev/null +++ b/zeroize/src/aarch64.rs @@ -0,0 +1,35 @@ +//! [`Zeroize`] impls for ARM64 SIMD registers. +//! +//! Support for this is gated behind an `aarch64` feature because +//! support for `core::arch::aarch64` is currently nightly-only. + +use crate::{atomic_fence, volatile_write, Zeroize}; + +use core::arch::aarch64::*; + +macro_rules! impl_zeroize_for_simd_register { + ($(($type:ty, $vdupq:ident)),+) => { + $( + #[cfg_attr(docsrs, doc(cfg(target_arch = "aarch64")))] + #[cfg_attr(docsrs, doc(cfg(target_feature = "neon")))] + impl Zeroize for $type { + fn zeroize(&mut self) { + volatile_write(self, unsafe { $vdupq(0) }); + atomic_fence(); + } + } + )+ + }; +} + +// TODO(tarcieri): other NEON register types? +impl_zeroize_for_simd_register! { + (uint8x8_t, vdup_n_u8), + (uint8x16_t, vdupq_n_u8), + (uint16x4_t, vdup_n_u16), + (uint16x8_t, vdupq_n_u16), + (uint32x2_t, vdup_n_u32), + (uint32x4_t, vdupq_n_u32), + (uint64x1_t, vdup_n_u64), + (uint64x2_t, vdupq_n_u64) +} diff --git a/zeroize/src/lib.rs b/zeroize/src/lib.rs index cb70f9d2..03c1991b 100644 --- a/zeroize/src/lib.rs +++ b/zeroize/src/lib.rs @@ -238,6 +238,8 @@ extern crate alloc; #[cfg_attr(docsrs, doc(cfg(feature = "zeroize_derive")))] pub use zeroize_derive::{Zeroize, ZeroizeOnDrop}; +#[cfg(all(feature = "aarch64", target_arch = "aarch64"))] +mod aarch64; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] mod x86;