-
Notifications
You must be signed in to change notification settings - Fork 164
Decide whether to zeroize buffer or encrypt it back on tag check failure #660
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
Comments
The main argument for re-encryption is having a consistent behavior across all of our crates, IMO. Currently all of them except for |
I agree that we should be consistent. My main concern is that implementing re-encryption may not be always easy. It's far easier to just zeroize output buffer and test it using the test macro. I guess if |
Nearly all of the current implementations are currently two-pass and return the unaltered ciphertext buffer on tag verification failure. No mutation of the buffer is performed at all in that case, which seems desirable. If we want to add a test for the behavior on decryption failure as I suggested in RustCrypto/traits#1803 and tested for an all-zero output, we would need to modify all of the AEADs to modify the buffer on decryption failure rather than leaving it unchanged, which seems undesirable. |
What do you think about buffer-to-buffer operations with two-pass modes? Should we always copy ciphertext to the output buffer on tag mismatch?
This should be relatively straightforward to implement, so I don't think it's a big issue. Especially considering that we would have to add the ciphertext copying for all two-pass crates. In other words, it will be far easier to write I agree with your point (voiced in the Zulip chat) that re-encryption is closer to the ideal of "do not decrypt until ciphertext integrity is verified", though it looks a bit weird to copy ciphertext in the buffer-to-buffer case. |
As a point of reference, it looks like |
If the intent is to guard against chosen-ciphertext attacks when the caller fails to check the tag (a catastrophic failure by the caller), I think it would be best to zeroize the output, because if the original ciphertext is left in the buffer, an attacker could still accomplish the same chosen-ciphertext attack by submitting an incorrect tag with the chosen plaintext. |
A chosen ciphertext attack requires a decryption oracle. If a user submits any message as the "ciphertext", what they get out of re-encryption is the original message they submitted, not an encryption/decryption thereof. |
With one-pass decryption we start to decrypt ciphertext before its integrity was verified. In the case if tag check has failed in the end we need to erase decrypted data. It can be done either by zeroizing the input buffer (as done in
ascon-aead
, see #659) or by encrypting it back (as done inaes-gcm
, see #551).We probably should look into what is done in other libraries outside of the Rust ecosystem.
The text was updated successfully, but these errors were encountered: