Re: storing an explicit nonce

From: Bruce Momjian <bruce(at)momjian(dot)us>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Stephen Frost <sfrost(at)snowman(dot)net>, Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Tom Kincaid <tomjohnkincaid(at)gmail(dot)com>, Andres Freund <andres(at)anarazel(dot)de>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Thomas Munro <thomas(dot)munro(at)gmail(dot)com>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>, Masahiko Sawada <masahiko(dot)sawada(at)2ndquadrant(dot)com>
Subject: Re: storing an explicit nonce
Date: 2021-05-25 19:45:42
Message-ID: 20210525194542.GG3048@momjian.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

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 <bruce(at)momjian(dot)us> https://momjian.us
EDB https://enterprisedb.com

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

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2021-05-25 19:53:36 Re: CALL versus procedures with output-only arguments
Previous Message Bruce Momjian 2021-05-25 19:34:04 Re: storing an explicit nonce