On Tue, May 25, 2021 at 03:34:04PM -0400, Bruce Momjian wrote:
> Let me go into more detail here.  The general rule is that you never
> encrypt _different_ data with the same key/nonce.  Now, since a hint bit
> change changes the data, it should get a new nonce, and since it is a
> newly encrypted page (using a new nonce), it should be WAL logged
> because a torn page would make the data unreadable.
> 
> Now, if we want to consult some security experts and have them tell us
> the hint bit visibility is not a problem, we could get by without using a
> new nonce for hint bit changes, and in that case it doesn't matter if we
> have a separate LSN or custom nonce --- it doesn't get changed for hint
> bit changes.
> 
> My point is that we have to full-page-write cases where we change the
> nonce --- we get a new LSN/nonce for free if we are using the LSN as the
> nonce.  What has made this approach much easier is that you basically
> tie a change of the nonce to require a change of LSN, since you are WAL
> logging it and every nonce change has to be full-page-write WAL logged. 
> This makes the LSN-as-nonce less fragile to breakage than a custom
> nonce, in my opinion, which may explain why my patch is so small.

This issue is covered at the bottom of this patch to the README file:

        
https://github.com/postgres/postgres/compare/bmomjian:cfe-01-doc..bmomjian:_cfe-02-internaldoc.patch

        Hint Bits
        - - - - -
        
        For hint bit changes, the LSN normally doesn't change, which is
        a problem.  By enabling wal_log_hints, you get full page writes
        to the WAL after the first hint bit change of the checkpoint.
        This is useful for two reasons.  First, it generates a new LSN,
        which is needed for the IV to be secure.  Second, full page images
        protect against torn pages, which is an even bigger requirement for
        encryption because the new LSN is re-encrypting the entire page,
        not just the hint bit changes.  You can safely lose the hint bit
        changes, but you need to use the same LSN to decrypt the entire
        page, so a torn page with an LSN change cannot be decrypted.
        To prevent this, wal_log_hints guarantees that the pre-hint-bit
        version (and previous LSN version) of the page is restored.
        
        However, if a hint-bit-modified page is written to the file system
        during a checkpoint, and there is a later hint bit change switching
        the same page from clean to dirty during the same checkpoint, we
        need a new LSN, and wal_log_hints doesn't give us a new LSN here.
        The fix for this is to update the page LSN by writing a dummy
        WAL record via xloginsert.c::LSNForEncryption() in such cases.

Let me know if it needs more detai.

-- 
  Bruce Momjian  <br...@momjian.us>        https://momjian.us
  EDB                                      https://enterprisedb.com

  If only the physical world exists, free will is an illusion.



Reply via email to