-
Notifications
You must be signed in to change notification settings - Fork 256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Zero memory on drop #87
Comments
Yes, you are right, currently most crates do not zeroize inner state on drop. IIUC to implement it without hacks we will need either |
@newpavlov you can do a |
@tarcieri Maybe we can transform the whole hash state into byte slice (using |
@newpavlov or you can just call zeroize on each value in its state in a When const generics land it should be possible to derive a |
@fxha is there a particular hash function or set of them you'd specifically like to have this in? We can add optional |
I think it's good practice to (optionally) erase secret data and don't leak keys in memory. |
I agree (in fact I wrote the most popular crate for it). However hash functions are a bit of an odd fish in this regard. Ones based on the Merkle–Damgård construction (which constitute a large number of the ones in this repo, including the popular I think the hash functions where this would be relevant are, as you pointed out, ones with keys, i.e. ones which provide PRFs. As far as I know the only one in this particular repo that applies to is |
Zeroize cannot prevent the type from being used after zeroing. Internal states often include constants, so zeroizing can leave an internal state that functions but provides less security. |
@tarcieri I don't quite remember, but I was using Blake2 and noticed that my key was copied or something like this. Cleaning the internal state isn't a high priority but basic cleanup should be provided. |
zeroize is the most popular crate for zeroizing memory after use. generic-array is the most popular crate for representing bytes in cryptographic implementations which can't use an allocator. Issues have been opened in RustCrypto about zeroizing instances of generic-array, for instance here: RustCrypto/hashes#87 However, sometimes you want to return generic-array from an API while also commiting it to be zeroized after use, because the caller might forget to do this on some code path. The natural way to do that in zeroize crate is the `Zeroizing` wrapper. However, `Zeroizing` cannot be used with `generic-array` unless `generic-array` implements the `Zeroize` trait. The easiest way to do that is create an optional dependency on `Zeroize` and put the implementation in a conditionally-compiled module, as we did in this commit.
I wonder if we should make the reset capability optional... It would allow us to remove the caching of initial state and thus secret key inside hasher state will be overwritten as soon as first block of data has been processed. How often in your opinion users need to reset MAC states? |
How about adding the Zeroize trait for blake2 at least? I am trying to implement a noise-like protocol where hmac-blake2 is used as a KDF. Right now I am using libsodium including sodium_malloc/free to make sure ephemeral secrecy is guaranteed. The lack of well thought-through zeroization in RustCrypto is a major blocker for moving away from sodium. |
I think an optional The problem with |
Hi! bumping this again because a lot of project effectively need |
(I'm not sure this is valid due to the ordering pre-condition. Doesn't Zeroize use a volatile only guaranteed to be ordered with regard to other volatiles? If so, I think that'd make all use of Zeroize unsafe, so I doubt it, but I obviously may be missing something...)
|
You are thinking of some outdated guidelines. Please read this section of the https://docs.rs/zeroize/latest/zeroize/#what-guarantees-does-this-crate-provide |
In that case, the sole question is if a further write is guaranteed to be ordered, and if not, how to trigger a read it is ordered in regard to (not my field of expertise). Regardless, sounds like my proposed solution could/should work? |
I would probably suggest just adding a The problem with adding a |
Right, I read the history, yet if after the zeroize we re-write the starting state... it's use-after-init-after-zeroize. That shouldn't introduce any unsafety. |
It isn't a "safety" issue in the Rust sense, but the problem is Though I suppose there's an argument to be made that it's no different from |
If a user explicitly calls Zeroize, which is just a stronger reset in this context, and then it's reused 'unexpectedly', I'd argue that's the users fault, yes. |
It's a logical bug. Zeroized state may not be valid for a given hash function. In the worst case scenario, it may even break safety assumptions used by implementation. |
I have a question about the hash memory management but also for other related repositories. As it seems
RustCrypto
useGenericArray
and/or raw arrays for sensitive data like keys and internal buffers but the memory is not overwritten/zeroed on reset or when the buffer/struct is dropped for most crates, right? Are there any plans to change this?The text was updated successfully, but these errors were encountered: