[Draft] Implement a fast-key-erasure ChaCha variant - #578
Conversation
| // The counter is incremented like usual (i.e. it is not reset). | ||
| fn generate(&mut self, buffer: &mut [u32; BUFFER_SIZE]) -> usize { | ||
| let _ = self.0.generate(buffer); | ||
| self.0.state[4..12].copy_from_slice(&buffer[0..8]); |
There was a problem hiding this comment.
While this overwrites the original value, doesn't it also leave the newly generated key in the output buffer?
There was a problem hiding this comment.
Aah, is that what this is intended to address? rust-random/rand_core#81
There was a problem hiding this comment.
While this overwrites the original value, doesn't it also leave the newly generated key in the output buffer?
Yes. We could erase it immediately but I didn't see the point: the output buffer should be right next to the key in memory and will be overwritten next time output is generated (the next key update).
Yes, it's related to that PR; see also rust-random/rand#1828 for context.
There was a problem hiding this comment.
I guess I would worry about bugs or other issues leaking the key somehow.
The whole point of these schemes is to erase the keys from memory for the purposes of forward secrecy so it seems safer to me to ensure such keys aren't persisted in places like output buffers that are designed specifically to be accessible to the caller.
There was a problem hiding this comment.
Fair argument; I used Self::erase.
Motivated by rust-random/rand#1826 (comment), I wanted to see if we could support a fast-key-erasure generator. Yes, I believe we can, and without much code.
Performance penalty: 12-13% for 1kiB blocks, 20-25% for single
u32values.Details
There are two parts to this:
I believe this is all that's required for forward security.
Reseeding?
As noted here, forward security (backtracking resistance) arguably has more value than "backward security" (reseeding) since if an attacker has compromised the system state, there is reason to believe they may be able to do so again. On the other hand, periodic reseeding may be useful for other reasons, e.g. if a process is forked without explicit reseeding (i.e. a bug).
Anyway, there is no reason we can't layer one on top of the other.