On 10/16/21 16:16, Bruce Momjian wrote:
On Fri, Oct 15, 2021 at 10:57:03PM +0200, Tomas Vondra wrote:
That said, I don't think that's really a huge issue or something that's
a show stopper or a reason to hold off on using XTS.  Note that what
those bits actually *are* isn't leaked, just that they changed in some
fashion inside of that 16-byte cipher text block.  That they're directly
leaked with CTR is why there was concern raised about using that method,
as discussed above and previously.


Yeah. With CTR you pretty learn where the hint bits are exactly, while with
XTS the whole ciphertext changes.

This also means CTR is much more malleable, i.e. you can tweak the
ciphertext bits to flip the plaintext, while with XTS that's not really
possible - it's pretty much guaranteed to break the block structure. Not
sure if that's an issue for our use case, but if it is then neither of the
two modes is a solution.

Yes, this is a vary good point.  Let's look at the impact of _not_ using
the LSN.  For CTR (already rejected) bit changes would be visible by
comparing old/new page contents.  For CBC (also not under consideration)
the first 16-byte block would show a change, and all later 16-byte
blocks would show a change.  For CBC, you see the 16-byte blocks change,
but you have no idea how many bits were changed, and in what locations
in the 16-byte block (AES uses substitution and diffusion).  For XTS,
because earlier blocks don't change the IV used by later blocks like
CBC, you would be able to see each 16-byte block that changed in the 8k
page.  Again, you would not know the number of bits changed or their
locations.

Do we think knowing which 16-byte blocks on an 8k page change would leak
useful information?  If so, we should use the LSN and just accept that
some cases might leak as described above.  If we don't care, then we can
skip the use of the LSN and simplify the patch.

Not sure - it seems a bit weird to force LSN change even in cases that don't
generate any WAL. I was not following the encryption thread and maybe it was
discussed/rejected there, but I've always imagined we'd have a global nonce
generator (similar to a sequence) and we'd store it at the end of each
block, or something like that.

Storing the nonce in the page means more code complexity, possible
performance impact, and the inability to create standbys via binary
replication that use cluster file encryption.


Would it really be that complex? Reserving a bunch of bytes at the end of each encrypted page (a bit like the "special" space, but after encryption) seems fairly straightforward. And I don't quite see why would this have a measurable impact, given the nonce is 16B at most. The encryption is likely way more expensive.

Moreover, it seems fairly reasonable to trade a bit of code complexity for something LSN-based which seems simpler but apparently has various weak points and is much harder to reason about.


regards

--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


Reply via email to