From 840f11b09886ab5139927dc845f35f5ae032d1f7 Mon Sep 17 00:00:00 2001 From: Ruslan Piasetskyi Date: Sat, 14 Oct 2023 16:48:45 +0200 Subject: [PATCH 1/5] hybrid-array: implement concat and split methods (#958) Convenient methods for concatenation and splitting. The size of the result is calculated in the compile time. This implementation was inspired by GenericArray implementation of Concat and Split traits. Co-authored-by: Ruslan Piasetskyi --- hybrid-array/src/lib.rs | 119 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/hybrid-array/src/lib.rs b/hybrid-array/src/lib.rs index e4817adc..7c407139 100644 --- a/hybrid-array/src/lib.rs +++ b/hybrid-array/src/lib.rs @@ -32,10 +32,12 @@ use core::{ cmp::Ordering, fmt::{self, Debug}, hash::{Hash, Hasher}, - ops::{Deref, DerefMut, Index, IndexMut, Range}, + mem::{ManuallyDrop, MaybeUninit}, + ops::{Add, Deref, DerefMut, Index, IndexMut, Range, Sub}, + ptr, slice::{Iter, IterMut}, }; -use typenum::Unsigned; +use typenum::{Diff, Sum, Unsigned}; /// Hybrid typenum-based and const generic array type. /// @@ -44,6 +46,10 @@ use typenum::Unsigned; #[repr(transparent)] pub struct Array(pub U::ArrayType); +type SplitResult = (Array, Array>); +type SplitRefResult<'a, T, U, N> = (&'a Array, &'a Array>); +type SplitRefMutResult<'a, T, U, N> = (&'a mut Array, &'a mut Array>); + impl Array where U: ArraySize, @@ -126,6 +132,74 @@ where { Self::ref_from_slice(slice).clone() } + + /// Concatenates `self` with `other`. + #[inline] + pub fn concat(self, other: Array) -> Array> + where + N: ArraySize, + U: Add, + Sum: ArraySize, + { + let mut result = MaybeUninit::uninit(); + let result_ptr = result.as_mut_ptr() as *mut Self; + + unsafe { + ptr::write(result_ptr, self); + ptr::write(result_ptr.add(1) as *mut _, other); + result.assume_init() + } + } + + /// Splits `self` at index `N` in two arrays. + /// + /// New arrays hold the original memory from `self`. + #[inline] + pub fn split(self) -> SplitResult + where + U: Sub, + N: ArraySize, + Diff: ArraySize, + { + unsafe { + let array = ManuallyDrop::new(self); + let head = ptr::read(array.as_ptr() as *const _); + let tail = ptr::read(array.as_ptr().add(N::USIZE) as *const _); + (head, tail) + } + } + + /// Splits `&self` at index `N` in two array references. + #[inline] + pub fn split_ref(&self) -> SplitRefResult<'_, T, U, N> + where + U: Sub, + N: ArraySize, + Diff: ArraySize, + { + unsafe { + let array_ptr = self.as_ptr(); + let head = &*(array_ptr as *const _); + let tail = &*(array_ptr.add(N::USIZE) as *const _); + (head, tail) + } + } + + /// Splits `&mut self` at index `N` in two mutable array references. + #[inline] + pub fn split_ref_mut(&mut self) -> SplitRefMutResult<'_, T, U, N> + where + U: Sub, + N: ArraySize, + Diff: ArraySize, + { + unsafe { + let array_ptr = self.as_mut_ptr(); + let head = &mut *(array_ptr as *mut _); + let tail = &mut *(array_ptr.add(N::USIZE) as *mut _); + (head, tail) + } + } } impl AsRef<[T; N]> for Array @@ -698,7 +772,7 @@ impl_array_size! { mod tests { use super::ByteArray; use crate::Array; - use typenum::{U0, U3, U6, U7}; + use typenum::{U0, U2, U3, U4, U6, U7}; const EXAMPLE_SLICE: &[u8] = &[1, 2, 3, 4, 5, 6]; @@ -729,4 +803,43 @@ mod tests { assert!(<&ByteArray::>::try_from(EXAMPLE_SLICE).is_err()); } + + #[test] + fn concat() { + let prefix = ByteArray::::clone_from_slice(&EXAMPLE_SLICE[..2]); + let suffix = ByteArray::::clone_from_slice(&EXAMPLE_SLICE[2..]); + + let array = prefix.concat(suffix); + assert_eq!(array.as_slice(), EXAMPLE_SLICE); + } + + #[test] + fn split() { + let array = ByteArray::::clone_from_slice(EXAMPLE_SLICE); + + let (prefix, suffix) = array.split::(); + + assert_eq!(prefix.as_slice(), &EXAMPLE_SLICE[..2]); + assert_eq!(suffix.as_slice(), &EXAMPLE_SLICE[2..]); + } + + #[test] + fn split_ref() { + let array = ByteArray::::clone_from_slice(EXAMPLE_SLICE); + + let (prefix, suffix) = array.split_ref::(); + + assert_eq!(prefix.as_slice(), &EXAMPLE_SLICE[..3]); + assert_eq!(suffix.as_slice(), &EXAMPLE_SLICE[3..]); + } + + #[test] + fn split_ref_mut() { + let array = &mut ByteArray::::clone_from_slice(EXAMPLE_SLICE); + + let (prefix, suffix) = array.split_ref_mut::(); + + assert_eq!(prefix.as_slice(), &EXAMPLE_SLICE[..4]); + assert_eq!(suffix.as_slice(), &EXAMPLE_SLICE[4..]); + } } From 7d6927b02ebb96300fe15866735eb9a8d35ce111 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 14 Oct 2023 16:59:22 -0600 Subject: [PATCH 2/5] cmov v0.3.1 (#959) --- Cargo.lock | 2 +- cmov/CHANGELOG.md | 12 ++++++++++++ cmov/Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dddc5b2f..b7df12e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,7 +27,7 @@ dependencies = [ [[package]] name = "cmov" -version = "0.3.0" +version = "0.3.1" [[package]] name = "collectable" diff --git a/cmov/CHANGELOG.md b/cmov/CHANGELOG.md index fbf92a71..b446e46d 100644 --- a/cmov/CHANGELOG.md +++ b/cmov/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.1 (2023-10-14) +### Added +- `CmovEq` impl for slices ([#954]) + +### Changed +- Use `#[inline]` instead of `#[inline(always)]` ([#924]) +- `CmovEq` now invokes XOR within the ASM block ([#925]) + +[#924]: https://github.com/RustCrypto/utils/pull/924 +[#925]: https://github.com/RustCrypto/utils/pull/925 +[#954]: https://github.com/RustCrypto/utils/pull/954 + ## 0.3.0 (2023-04-02) ### Added - `miri` support by forcing the `portable` backend ([#864]) diff --git a/cmov/Cargo.toml b/cmov/Cargo.toml index f08912c6..7d6d501b 100644 --- a/cmov/Cargo.toml +++ b/cmov/Cargo.toml @@ -6,7 +6,7 @@ constant-time and not be rewritten as branches by the compiler. Provides wrappers for the CMOV family of instructions on x86/x86_64 and CSEL on AArch64. """ -version = "0.3.0" +version = "0.3.1" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/utils/tree/master/cmov" From 68cc2d80c309a27ddc136f3baad687eeffda56e9 Mon Sep 17 00:00:00 2001 From: hev Date: Fri, 20 Oct 2023 20:43:45 +0800 Subject: [PATCH 3/5] cpufeatures: Add support for LoongArch64 (#955) --- Cargo.lock | 4 +- cpufeatures/Cargo.toml | 13 ++-- cpufeatures/README.md | 22 ++++++- cpufeatures/src/lib.rs | 34 +++++++++- cpufeatures/src/loongarch64.rs | 106 +++++++++++++++++++++++++++++++ cpufeatures/tests/loongarch64.rs | 20 ++++++ 6 files changed, 189 insertions(+), 10 deletions(-) create mode 100644 cpufeatures/src/loongarch64.rs create mode 100644 cpufeatures/tests/loongarch64.rs diff --git a/Cargo.lock b/Cargo.lock index b7df12e9..e25ececa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,9 +115,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "opaque-debug" diff --git a/cpufeatures/Cargo.toml b/cpufeatures/Cargo.toml index 20ff471d..73e90b8e 100644 --- a/cpufeatures/Cargo.toml +++ b/cpufeatures/Cargo.toml @@ -2,8 +2,8 @@ name = "cpufeatures" version = "0.2.9" description = """ -Lightweight runtime CPU feature detection for x86/x86_64 and aarch64 with -no_std support and support for mobile targets including Android and iOS +Lightweight runtime CPU feature detection for aarch64, loongarch64, and x86/x86_64 targets, +with no_std support and support for mobile targets including Android and iOS """ authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -15,10 +15,13 @@ edition = "2018" readme = "README.md" [target.'cfg(all(target_arch = "aarch64", target_vendor = "apple"))'.dependencies] -libc = "0.2.95" +libc = "0.2.149" [target.'cfg(all(target_arch = "aarch64", target_os = "linux"))'.dependencies] -libc = "0.2.95" +libc = "0.2.149" + +[target.'cfg(all(target_arch = "loongarch64", target_os = "linux"))'.dependencies] +libc = "0.2.149" [target.aarch64-linux-android.dependencies] -libc = "0.2.95" +libc = "0.2.149" diff --git a/cpufeatures/README.md b/cpufeatures/README.md index c8d89b08..f199636a 100644 --- a/cpufeatures/README.md +++ b/cpufeatures/README.md @@ -7,7 +7,7 @@ [![Project Chat][chat-image]][chat-link] [![Build Status][build-image]][build-link] -Lightweight and efficient runtime CPU feature detection for `aarch64` and +Lightweight and efficient runtime CPU feature detection for `aarch64`, `loongarch64`, and `x86`/`x86_64` targets. Supports `no_std` as well as mobile targets including iOS and Android, @@ -31,6 +31,26 @@ Target features: - `sha2`* - `sha3`* +## `loongarch64` + +Linux only (LoongArch64 does not support OS-independent feature detection) + +Target features: + +- `lam`* +- `ual`* +- `fpu`* +- `lsx`* +- `lasx`* +- `crc32`* +- `complex`* +- `crypto`* +- `lvz`* +- `lbt.x86`* +- `lbt.arm`* +- `lbt.mips`* +- `ptw`* + ## `x86`/`x86_64` OS independent and `no_std`-friendly diff --git a/cpufeatures/src/lib.rs b/cpufeatures/src/lib.rs index 18bdc7e3..4c916f45 100644 --- a/cpufeatures/src/lib.rs +++ b/cpufeatures/src/lib.rs @@ -18,6 +18,26 @@ //! - `sha2`* //! - `sha3`* //! +//! ## `loongarch64` +//! +//! Linux only (LoongArch64 does not support OS-independent feature detection) +//! +//! Target features: +//! +//! - `lam`* +//! - `ual`* +//! - `fpu`* +//! - `lsx`* +//! - `lasx`* +//! - `crc32`* +//! - `complex`* +//! - `crypto`* +//! - `lvz`* +//! - `lbt.x86`* +//! - `lbt.arm`* +//! - `lbt.mips`* +//! - `ptw`* +//! //! ## `x86`/`x86_64` //! //! OS independent and `no_std`-friendly @@ -107,6 +127,11 @@ #[doc(hidden)] pub mod aarch64; +#[cfg(not(miri))] +#[cfg(target_arch = "loongarch64")] +#[doc(hidden)] +pub mod loongarch64; + #[cfg(not(miri))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] mod x86; @@ -114,8 +139,13 @@ mod x86; #[cfg(miri)] mod miri; -#[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))] -compile_error!("This crate works only on `aarch64`, `x86`, and `x86-64` targets."); +#[cfg(not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "x86", + target_arch = "x86_64" +)))] +compile_error!("This crate works only on `aarch64`, `loongarch64`, `x86`, and `x86-64` targets."); /// Create module with CPU feature detection code. #[macro_export] diff --git a/cpufeatures/src/loongarch64.rs b/cpufeatures/src/loongarch64.rs new file mode 100644 index 00000000..51398d74 --- /dev/null +++ b/cpufeatures/src/loongarch64.rs @@ -0,0 +1,106 @@ +//! LoongArch64 CPU feature detection support. +//! +//! This implementation relies on OS-specific APIs for feature detection. + +// Evaluate the given `$body` expression any of the supplied target features +// are not enabled. Otherwise returns true. +#[macro_export] +#[doc(hidden)] +macro_rules! __unless_target_features { + ($($tf:tt),+ => $body:expr ) => { + { + #[cfg(not(all($(target_feature=$tf,)*)))] + $body + + #[cfg(all($(target_feature=$tf,)*))] + true + } + }; +} + +// Linux runtime detection of target CPU features using `getauxval`. +#[cfg(target_os = "linux")] +#[macro_export] +#[doc(hidden)] +macro_rules! __detect_target_features { + ($($tf:tt),+) => {{ + let hwcaps = $crate::loongarch64::getauxval_hwcap(); + $($crate::check!(hwcaps, $tf) & )+ true + }}; +} + +/// Linux helper function for calling `getauxval` to get `AT_HWCAP`. +#[cfg(target_os = "linux")] +pub fn getauxval_hwcap() -> u64 { + unsafe { libc::getauxval(libc::AT_HWCAP) } +} + +// Linux `expand_check_macro` +#[cfg(target_os = "linux")] +macro_rules! __expand_check_macro { + ($(($name:tt, $hwcap:ident)),* $(,)?) => { + #[macro_export] + #[doc(hidden)] + macro_rules! check { + $( + ($hwcaps:expr, $name) => { + (($hwcaps & $crate::loongarch64::hwcaps::$hwcap) != 0) + }; + )* + } + }; +} + +// Linux `expand_check_macro` +#[cfg(target_os = "linux")] +__expand_check_macro! { + ("cpucfg", CPUCFG), // Enable CPUCFG support. + ("lam", LAM), // Enable LAM support. + ("ual", UAL), // Enable UAL support. + ("fpu", FPU), // Enable FPU support. + ("lsx", LSX), // Enable LSX support. + ("lasx", LASX), // Enable LASX support. + ("crc32", CRC32), // Enable CRC32 support. + ("complex", COMPLEX), // Enable COMPLEX support. + ("crypto", CRYPTO), // Enable CRYPTO support. + ("lvz", LVZ), // Enable LVZ support. + ("lbt.x86", LBT_X86), // Enable LBT_X86 support. + ("lbt.arm", LBT_ARM), // Enable LBT_ARM support. + ("lbt.mips", LBT_MIPS), // Enable LBT_MIPS support. + ("ptw", PTW), // Enable PTW support. +} + +/// Linux hardware capabilities mapped to target features. +/// +/// Note that LLVM target features are coarser grained than what Linux supports +/// and imply more capabilities under each feature. This module attempts to +/// provide that mapping accordingly. +#[cfg(target_os = "linux")] +pub mod hwcaps { + use libc::c_ulong; + + pub const CPUCFG: c_ulong = libc::HWCAP_CPUCFG; + pub const LAM: c_ulong = libc::HWCAP_LAM; + pub const UAL: c_ulong = libc::HWCAP_UAL; + pub const FPU: c_ulong = libc::HWCAP_FPU; + pub const LSX: c_ulong = libc::HWCAP_LSX; + pub const LASX: c_ulong = libc::HWCAP_LASX; + pub const CRC32: c_ulong = libc::HWCAP_CRC32; + pub const COMPLEX: c_ulong = libc::HWCAP_COMPLEX; + pub const CRYPTO: c_ulong = libc::HWCAP_CRYPTO; + pub const LVZ: c_ulong = libc::HWCAP_LVZ; + pub const LBT_X86: c_ulong = libc::HWCAP_LBT_X86; + pub const LBT_ARM: c_ulong = libc::HWCAP_LBT_ARM; + pub const LBT_MIPS: c_ulong = libc::HWCAP_LBT_MIPS; + pub const PTW: c_ulong = libc::HWCAP_PTW; +} + +// On other targets, runtime CPU feature detection is unavailable +#[cfg(not(target_os = "linux"))] +#[macro_export] +#[doc(hidden)] +macro_rules! __detect_target_features { + ($($tf:tt),+) => { + false + }; +} diff --git a/cpufeatures/tests/loongarch64.rs b/cpufeatures/tests/loongarch64.rs new file mode 100644 index 00000000..fbcbe9d3 --- /dev/null +++ b/cpufeatures/tests/loongarch64.rs @@ -0,0 +1,20 @@ +//! LoongArch64 tests + +#![cfg(target_arch = "loongarch64")] + +cpufeatures::new!( + lacaps, "cpucfg", "lam", "ual", "fpu", "lsx", "lasx", "crc32", "complex", "crypto", "lvz", + "lbt.x86", "lbt.arm", "lbt.mips", "ptw" +); + +#[test] +fn init() { + let token: lacaps::InitToken = lacaps::init(); + assert_eq!(token.get(), lacaps::get()); +} + +#[test] +fn init_get() { + let (token, val) = lacaps::init_get(); + assert_eq!(val, token.get()); +} From e70943cb569d317f777c067edc2c70dcecef1a71 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 20 Oct 2023 16:46:10 +0300 Subject: [PATCH 4/5] cpufeatures: release v0.2.10 (#962) --- .github/workflows/cpufeatures.yml | 12 ++++++++++++ Cargo.lock | 26 +++++++++++++------------- cpufeatures/CHANGELOG.md | 6 ++++++ cpufeatures/Cargo.toml | 2 +- 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cpufeatures.yml b/.github/workflows/cpufeatures.yml index 7dff1fd6..68986f21 100644 --- a/.github/workflows/cpufeatures.yml +++ b/.github/workflows/cpufeatures.yml @@ -122,3 +122,15 @@ jobs: # Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates - run: rm ../Cargo.toml - run: cross test --target ${{ matrix.target }} + + # Build-only tests + build-only: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + - run: rustup target add loongarch64-unknown-linux-gnu + - run: cargo build --target loongarch64-unknown-linux-gnu diff --git a/Cargo.lock b/Cargo.lock index e25ececa..1602cfa8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ version = "0.0.2" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.10" dependencies = [ "libc", ] @@ -125,9 +125,9 @@ version = "0.3.0" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -149,18 +149,18 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "serde" -version = "1.0.185" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.185" +version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", @@ -169,9 +169,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -197,9 +197,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "version_check" diff --git a/cpufeatures/CHANGELOG.md b/cpufeatures/CHANGELOG.md index c62941d0..faa33978 100644 --- a/cpufeatures/CHANGELOG.md +++ b/cpufeatures/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.10 (2023-10-20) +### Added +- LoongArch64 target support ([#955]) + +[#955]: https://github.com/RustCrypto/utils/pull/955 + ## 0.2.9 (2023-07-05) ### Added - Support for `avx512vbmi` and `avx512vbmi2` target features ([#926]) diff --git a/cpufeatures/Cargo.toml b/cpufeatures/Cargo.toml index 73e90b8e..aba5773a 100644 --- a/cpufeatures/Cargo.toml +++ b/cpufeatures/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cpufeatures" -version = "0.2.9" +version = "0.2.10" description = """ Lightweight runtime CPU feature detection for aarch64, loongarch64, and x86/x86_64 targets, with no_std support and support for mobile targets including Android and iOS From 29de876de93077131e3430436ecc07965a73248e Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Fri, 20 Oct 2023 17:15:57 +0300 Subject: [PATCH 5/5] block-buffer: add optional Zeroize implementation (#963) --- Cargo.lock | 7 +++++++ block-buffer/CHANGELOG.md | 2 ++ block-buffer/Cargo.toml | 1 + block-buffer/src/lib.rs | 11 +++++++++++ block-buffer/src/read.rs | 10 ++++++++++ block-buffer/src/sealed.rs | 3 +++ 6 files changed, 34 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 1602cfa8..a4ea8e81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,7 @@ dependencies = [ "crypto-common", "generic-array", "hex-literal 0.3.4", + "zeroize 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -225,6 +226,12 @@ dependencies = [ "zeroize_derive", ] +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" + [[package]] name = "zeroize_derive" version = "1.4.2" diff --git a/block-buffer/CHANGELOG.md b/block-buffer/CHANGELOG.md index 14fa050b..c978381d 100644 --- a/block-buffer/CHANGELOG.md +++ b/block-buffer/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `ReadBuffer` type ([#823]) - `serialize` and `deserialize` methods ([#823]) +- Optional implementation of the `Zeroize` trait ([#963]) ### Changed - Supported block sizes are now bounded by the `crypto_common::BlockSizes` trait, @@ -20,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `EagerBuffer::set_data` method. Use the `ReadBuffer` type instead. ([#823]) [#823]: https://github.com/RustCrypto/utils/pull/823 +[#963]: https://github.com/RustCrypto/utils/pull/963 ## 0.10.3 (2022-09-04) ### Added diff --git a/block-buffer/Cargo.toml b/block-buffer/Cargo.toml index 7b121f95..c175ef2f 100644 --- a/block-buffer/Cargo.toml +++ b/block-buffer/Cargo.toml @@ -14,6 +14,7 @@ readme = "README.md" [dependencies] crypto-common = "0.2.0-pre" generic-array = "0.14" +zeroize = { version = "1.4", optional = true, default-features = false } [dev-dependencies] hex-literal = "0.3.3" diff --git a/block-buffer/src/lib.rs b/block-buffer/src/lib.rs index 61438e71..4d73c44d 100644 --- a/block-buffer/src/lib.rs +++ b/block-buffer/src/lib.rs @@ -15,6 +15,8 @@ use generic_array::{ typenum::{Add1, B1}, ArrayLength, GenericArray, }; +#[cfg(feature = "zeroize")] +use zeroize::Zeroize; mod read; mod sealed; @@ -333,3 +335,12 @@ impl BlockBuffer { }) } } + +#[cfg(feature = "zeroize")] +impl Zeroize for BlockBuffer { + #[inline] + fn zeroize(&mut self) { + self.buffer.zeroize(); + self.pos.zeroize(); + } +} diff --git a/block-buffer/src/read.rs b/block-buffer/src/read.rs index fa9237a1..1fb5ac66 100644 --- a/block-buffer/src/read.rs +++ b/block-buffer/src/read.rs @@ -1,6 +1,8 @@ use super::{Block, Error}; use core::{fmt, slice}; use crypto_common::{BlockSizeUser, BlockSizes}; +#[cfg(feature = "zeroize")] +use zeroize::Zeroize; /// Buffer for reading block-generated data. pub struct ReadBuffer { @@ -146,3 +148,11 @@ impl ReadBuffer { (blocks, right) } } + +#[cfg(feature = "zeroize")] +impl Zeroize for ReadBuffer { + #[inline] + fn zeroize(&mut self) { + self.buffer.zeroize(); + } +} diff --git a/block-buffer/src/sealed.rs b/block-buffer/src/sealed.rs index cc7b3ef6..90b408ae 100644 --- a/block-buffer/src/sealed.rs +++ b/block-buffer/src/sealed.rs @@ -3,7 +3,10 @@ use generic_array::{ArrayLength, GenericArray}; /// Sealed trait for buffer kinds. pub trait Sealed { + #[cfg(not(feature = "zeroize"))] type Pos: Default + Clone; + #[cfg(feature = "zeroize")] + type Pos: Default + Clone + zeroize::Zeroize; fn get_pos(buf: &[u8], pos: &Self::Pos) -> usize;