- Feature name:
secret-zeroize-drop
- Start date: 2020-07-08
- RFC PR: iotaledger/bee-rfcs#44
- Bee issue: iotaledger/bee#104
Summary
This RFC does not really introduce a feature but rather a recommendation when dealing with sensitive data; their memory should be securely erased when not used anymore.
Motivation
When dealing with sensitive data like key materials (e.g. seeds, private keys, ...), it is wise to explicitly clear their memory to avoid having them continue existing and potentially exposing them to an attack.
Since such an attack already assumes unauthorized access to the data, this technique is merely an exploit mitigation by ensuring sensitive data is no longer available.
Useful links:
- How to zero a buffer
- Erasing Sensitive Data
- Ensure that sensitive data is not written out to disk
- Would it be good secure programming practice to overwrite a “sensitive” variable before deleting it?
Detailed design
This task is made a bit more complex by compilers that have a tendency of removing zeroing of memory they deem pointless when doing optimizations. It is then not as trivial as resetting the memory to 0.
These optimizations can however be bypassed by using volatile memory.
Zeroize
and Drop
This RFC recommends:
- implementing the following traits on sensitive data types:
- having
Zeroize
andDrop
as requirements of sensitive data traits;
Examples
Traits requirements:
#![allow(unused)] fn main() { trait PrivateKey: Zeroize + Drop { ... } }
If the type is trivial, Zeroize
and Drop
can be derived:
#![allow(unused)] fn main() { #[derive(Zeroize)] #[zeroize(drop)] struct ExamplePrivateKey([u8; 32]); }
Otherwise, Zeroize
and Drop
need to be manually implemented.
-
Zeroize
implementation:#![allow(unused)] fn main() { impl Zeroize for ExamplePrivateKey { fn zeroize(&mut self) { ... } } }
-
Drop
implementation:#![allow(unused)] fn main() { impl Drop for ExamplePrivateKey { fn drop(&mut self) { self.zeroize() } } }
A derive macro
SecretDrop
could be written to derive theDrop
implementation that is always expected to be the same.
Useful links:
Drawbacks
There are no major drawbacks in doing that, except the little overhead it comes with.
Rationale and alternatives
The alternative is to not recommend or enforce anything and risk users exposing their sensitive data to attacks.
Unresolved questions
Even though this technique uses volatile memory and is probably effective most of the time the compiler is still free to move all of the inner data to another part of memory without zeroing the original data since it doesn't consider the value to be dropped yet. A solution to prevent the compiler moving things whenever possible would be to box secrets and access them through Pin.