zeroize: potetial redesign ideas
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 674
- Forks
- 170
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 10
Description
Right now I see the following issues with public API of zeroize:
- Derived and manually implemented
Zeroizecan be inefficient since they rely on zeroization of fields one by one or on zeroizingDropimpls. - Procedural macros are relatively heavy compile time-wise, so usually we do not derive
Zeroizead rely on manual implementations. ZeroizeOnDropis a somewhat useless trait, I haven't seen it used in practice.Zeroizingusefulness is limited. It can be used only for "primitive" types (e.g. raw keys), complex types do not implementZeroizeand instead implement zeroizingDrop.- Zeroization is enabled for a whole crate using features. It's not possible to use selective zeroization and zeroization is not reflected in any way in user code.
I think most structures should be zeroized using the "flat" zeroization (see #1045) and that it can be useful to have explicit indication in user code of structs being zeroized on drop.
So I would like to suggest roughly this API:
/// Zeroizes memory pointed by `data_ptr`, but not memory
/// potentially reference by `T`.
pub unsafe fn zeroize_flat<T>(data_ptr: *mut T) {
// ...
}
/// Zeroize-on-drop wrapper.
///
/// Note that this wrapper zeroizes only data owned by `T`
/// and does nothing with data referenced by it.
#[repr(transparent)]
pub struct ZeroizeOnDrop<T, const IS_ENABLED: bool = true>(T);
/// Abbreviated alias for `ZeroizeOnDrop`.
pub type Zod<T, const IS_ENABLED: bool = true> = ZeroizeOnDrop<T, IS_ENABLED>;
impl<T, const IS_ENABLED: bool> Drop for ZeroizeOnDrop<T, IS_ENABLED> {
fn drop (&mut self) {
unsafe {
std::ptr::drop_in_place(&mut self.0);
if IS_ENABLED { zeroize_flat(&mut self.0); }
}
}
}
// Impl Deref and DerefMut for `ZeroizeOnDrop`
UPD: FlatPod and FlatZod are removed.
It can be introduced in a backward-compatible way, but for clarity it's probably worth to release it as v2.0.
Users would write code like this:
pub struct Foo {
secret_cipher: Zod<Aes128>,
secret_key: Box<Zod<[u8; 16]>>,
non_secret_hasher: Sha256,
// other fields
}
const ZOD: bool = cfg!(feature = "zeroize");
pub struct Bar1 {
// This field will be zeroized only if `zeroize` feature is enabled
cipher: Zod<Aes128, ZOD>,
}
// Alternatively:
pub struct Bar2<const ZOD: bool = true> {
cipher: Zod<Aes128, ZOD>,
}
While it will be a bit less convinient, I think it's useful to have explicit indication in source code that secret types will be zeroized on drop. We may provide aliases like type ZodAes128 = Zod<Aes128> to improve visibility, but I don't think they are worth the trouble and it should be sufficient to simply references zeroize in docs.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the proposed API in this issue and the flat zeroization discussion in #1045. Clarify whether the project wants a redesign, a backward-compatible addition, or a v2.0 change; done means the API direction and migration scope are agreed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cryptography, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100