60216 Commits

Author SHA1 Message Date
Anders Åstrand
a08ed99570 Modernize the way we call ereport() part 2
These were not updated in 725c34da520cca4597f6751d1d671c6191466200 and
we still want to use this way of calling ereport() everywhere.
2025-04-16 11:05:52 +02:00
Andreas Karlsson
20ab981941 PG-1440 Remove unnecesary query for test case
This query gave no extra coverage, either in qualitity or quality.
2025-04-16 08:40:49 +02:00
Andreas Karlsson
99ef6b20f9 PG-1440 Only let superusers modify the global key proviers
Since as soon as we have installed pg_tde the database owner can call
any function created by the extension so any database owner can meddle
with any global key provider. The only way to prevent the database owner
to do whatever they want add permissions checks to the C code and here
we keep that check simple by limiting modifying the global key provider
to only the super user.

Additionally we also protect the function for settting the WAL key, for
setting the default key and to be paranoid also the function for using a
global key provider to set the database key. The third is not obvious if
it is necessary or not but I chose to be paranoid and relax that
restirction later once we have demed it to be secure.
2025-04-16 08:40:49 +02:00
Naeem Akhter
dcdcebbf92
PG-1482, PG-1289 Add coverage to repo and percona server version check. (#212)
- Added code coverage to link repo to codecov.io for coverage stats on
PR and merge.
- Added coverage badge on the landing page (readme) of the repo. 
- Updated GH action to run on PUSH/MERGE, as this is required for code
coverage.
- Updated bash files in ci_scripts folder to accommodate tde
installcheck only.
- Added percona server version scheme verification TAP test case.
2025-04-15 19:42:57 +05:00
Artem Gavrilov
c8dd16849f PG-1458 Add default key info/verify funcions 2025-04-15 14:57:27 +02:00
Andreas Karlsson
9823fb75a2 Add Dragos Andriciuc to code owners
Dragos is a new technical writer. Welcome!
2025-04-15 14:33:32 +02:00
Andrew Pogrebnoi
92e40cdc38
XLog signed info when creating a Principal Key
Before this commit, we XLogged an unsigned PrincipalKey info when
creating the key. Which leads to:

1. In case of crash recovery, the redo would rewrite a map_ file with
an empty sign info. And the server would later fail to start with
"Failed to verify principal key header..."

2. Replicas would create a _map file with an empty sign info. Which in
turn leads to a fail on restart.


For PG-1539
2025-04-15 13:03:43 +03:00
Andreas Karlsson
06b671fc04 PG-1460 Always generate a new WAL key on server start
Since you can take a copy of a PostgreSQL data directory and start both
the old and the new version you could get two versions where the same
encrypted counter is used for CTR which would mean we could comapre
them and potentially decrypt the data. For this reason we need to
generate a new WAL key every time we start the server.
2025-04-15 11:24:24 +02:00
Andreas Karlsson
253c8a4a72 PG-1504 Open the relation directly with the RangeVar
Instead of first looking up the oid and then using that to open the
relation we can use relation_openrv() with the RangeVar directly.
2025-04-15 11:23:20 +02:00
Andreas Karlsson
7587e44a09 PG-1504 Return null pointer from event triggers
According to to the manual we should return a null pointer, but it is
contradicted by an example on the same page but let's follow what
plpgsql does.

    An event trigger function must return a NULL pointer
    (not an SQL null value, that is, do not
    set isNull true).
2025-04-15 11:23:20 +02:00
Andreas Karlsson
36b17e8579 PG-1504 Use castNode() when casting nodes
This gives us some extra protection against typos.
2025-04-15 11:23:20 +02:00
Andreas Karlsson
090e356f4b PG-1504 Remove unused field in tdeCurrentCreateEvent 2025-04-15 11:23:20 +02:00
Andreas Karlsson
71ce4c9157 PG-1504 Avoid early return where it does not improve reasbaility 2025-04-15 11:23:20 +02:00
Andreas Karlsson
9d22ae3f81 PG-1504 Remove side effects from checkEncryptionStatus()
A function with that name should not have side effects so let's add
a function which only checks if a table should be encrypted based on
the AM.
2025-04-15 11:23:20 +02:00
Andreas Karlsson
5afe678b60 PG-1504 Do not abuse checkEncryptionClause() for just one feature
The only part of the code which makes sense to call when we know the
table is ecrypted is the check for if a principal key is configured.
2025-04-15 11:23:20 +02:00
Andreas Karlsson
19bef897e6 PG-1510 Use a unique IV per relation fork
The security of the encryption is reduced if we reuse the same
initiation vector more than necessary so we make sure to use a unique IV
per relation fork, with the exception of the initialization fork which
is used by unlogged indexes when restarting the server after a crash. It
is copied with low-level file system functions to the main fork on crash
recovery so it needs to use the same IV as the main fork.

The init fork issue is in no way more a security issue than to the
extent that ideally we should pick a new IV when truncating unlogged
tables on crash recovery but to fix this we would need to change the
SMGR API and moving the copying of the intialization fork into that. And
in the long term this might be what we want to do.
2025-04-15 11:23:02 +02:00
Andreas Karlsson
93ef4510b4 Fix typo in comment of Makefile/meson.build 2025-04-14 11:14:46 +02:00
Andreas Karlsson
a590cf0857 Fix indentation in pg_tde/meson.build 2025-04-14 11:14:46 +02:00
Andreas Karlsson
c717b69727 PG-1437 Clean up frontend and backend sources in meson.build
While the frontend sources right now are a strict subset of the backend
sources that might not always be the case so keep them as separate lists
but clean them up. In the long term we want to refactor this entirely
anyway so let's not overcomplicate this.
2025-04-14 11:14:46 +02:00
Andreas Karlsson
065409d87c PG-1437 Remove TODO about tests for changing key provider type
Sinc we want to add validation for that the principal keys still all
are there some simple test would not suffice so let's instead wait
until we do that to write propoer tests for this.
2025-04-12 16:43:36 +02:00
Andreas Karlsson
4c3b0f8dfb PG-1480 Add regression tests for default key rotation
We had a bug in the default key roitation which was fixed in commit
cb06bea2537a7e9d354aeac0ddb24b3cddc4530f but that commit did not add any
regression test so let's add one where we clear the buffer cache to make
sure we can read the internal keys and use them to decrypt the table
data.
2025-04-11 12:58:50 +02:00
Andreas Karlsson
725c34da52 Modernize our way to call ereport()
Commit e3a87b4991cc2d00b7a3082abb54c5f12baedfd1 added a way to call
ereport() without any extra parentheses which was backported all the way
back to PostgreSQL 12. The new modern way improves code readability
slightly.
2025-04-10 21:18:11 +02:00
Anastasia Alexandrova
d158ba58ac
Update doc link readme (#175)
Co-authored-by: Andrew Pogrebnoi <absourd.noise@gmail.com>
2025-04-10 19:57:23 +02:00
Artem Gavrilov
959a6b65c1
PG-1457 Rename principal key on user API level to just a key (#154)
PG-1457

Replace `principal key` with just a `key` on user API level, as it's the only key that user can directly interact with.
2025-04-10 19:56:54 +02:00
Andreas Karlsson
b83ff3d684 PG-1468 Fix issue with intolerably slow recovery
When we did a recovery, even if tde_heap was not used, 98% of the time
was spent in pg_tde_get_key_from_file() due to our SMGR missing the
shortcicruit from mdcreate() which skips running if the fork already
is open.

The issue was made worse by us not caching negative SMGR key lookups but
that is the subject of another commit.
2025-04-10 19:44:28 +02:00
Zsolt Parragi
9356a40980 Updated review comments 2025-04-10 16:20:48 +02:00
Anastasia Alexadrova
afb7151860 Improved readability 2025-04-10 16:20:48 +02:00
Zsolt Parragi
e0a34487eb Added high level overview to documentation
This is just a conversion of the google doc into markdown, with
actualizing some of the outdated details in the document.

The last section (researc/investigation topics) is left out, as that
doesn't make much sense in a public documentation.
2025-04-10 16:20:48 +02:00
Anders Åstrand
ab2e9b1ed2 Fix typo in KeyringProvideRecord typedef name
The R was pulling double duty in the old name.
2025-04-10 11:43:58 +02:00
Anders Åstrand
0a54910d7a Remove typedefs.list
This file is no longer used by our scripts and is easy to generate when
running pgindent.
2025-04-10 09:20:25 +02:00
Andreas Karlsson
6576f2a464 PG-1532 Rewrite seqeunces using lower level functions
By using SPI and a SQL language function to force the rewrite of
sequences we made life unnecessarily hard for ourselves and also
intoduced a bug where ALTER TABLE could break if the pg_tde extension's
functions were not in the search path.

Instead we re-use the code for updating sequence persistence whe table
persistance is changed. And we only need to look at the table's
presistance since it is always the same as the one of the sequences.
2025-04-08 14:02:54 +02:00
Anders Åstrand
3381f84783 Clarify some namings in keyring code
It's not clear to someone new to the code that "key provider" in these
files refers to what's called "key provider type" elsewhere.

Rename these to make it easier for the next person.
2025-04-08 10:34:35 +02:00
Artem Gavrilov
3b8a234d3e
PG-1457 Key management funcs renaming (#126)
* PG-1457 Rename some key management funcions

* PG-1457 Fix some tests

* PG-1457 Hit CI

* PG-1457 Rename key in CI setup

* PG-1457 Rename pg_tde_verify_global_principal_key to pg_tde_verify_server_principal_key

* PG-1457 Rename keys in tests

* PG-1457 Renaming

* PG-1457 Renaming

* PG-1457 Fix tests

* PG-1457 Fix tests

* PG-1457 Fix tabs

* PG-1457 Fix tests

* PG-1457 Fix tests

* PG-1457 Fix

* PG-1457 Fix test

* PG-1457 Fix test

* PG-1457 Hit CI

* PG-1457 Fix after rebase

* PG-1457 Fix

* PG-1457 Fix

* PG-1457 Fix

* PG-1457 Fix test

* PG-1457 Fix tests

* PG-1457 Fix tests

* PG-1457 Fix
2025-04-08 10:20:16 +02:00
Andreas Karlsson
fef106d785 Remove unnecessary seek when we already know the size
There is no point in looking up the length of the file when we already
know it.
2025-04-07 21:48:37 +02:00
Andreas Karlsson
7638ec548a Make comment about all-zero pages less scary
The comment about all-zero pages created by smgrzeroextend() sounded
much scarier than the reality. In fact trying to encrypt these
all-zero pages might not only be a waste of CPU cycles but also could
decrease security by making us re-use the same IV first with all zeros
and then with the actual data. And the extra amount of protection
we gain from encrypting them is minuscule since they are only added
at the end of the table, soon overwritten and only gives the attacker
a very slightly more accurate table size.
2025-04-07 21:48:23 +02:00
Andreas Karlsson
2616e27844 Clean up tdeheap_xlog_seg_read()
Several variables were at a too long scope or were initialized when
they should not be. Plus convert a while loop to a for loop.
2025-04-07 11:14:47 +02:00
Andreas Karlsson
b11d51ca85 Use separate variables instead of an array when rotating files
This makes the code easier to read plus gives us things like letting
the compiler check for unused variables.
2025-04-07 11:14:28 +02:00
Andreas Karlsson
07756f2734 PG-1530 Fix off-by-one bug when determining which WAL key to use
The end LSN of the current buffer to decript was exclusive while the end
LSN of the key was inclusive which had led to confusion and an
off-by-one bug.

Also add a simple test case for the WAL encryption using the logical
decoding's test plugin.
2025-04-07 10:43:13 +02:00
Andreas Karlsson
d83fc90ac5 Use %m for error message in our modification of pg_regress
This follows the pattern in the rest of the PostgreSQL source code.
2025-04-07 10:30:57 +02:00
Andreas Karlsson
5514727353 PG-1416 Sign principal key info to protect against the wrong principal key
We already had protection against decrypting relation keys with the wrong
principal key but to properly protect us against new relation keys being
encrypted with the wrong principal key we need to also verify that the
principal key was correct when we fetch the principal key from the key
provider. We do so by signing the principal key info header of the key map
file using AES-128-GCM.

This way we cannot get a jumbled mess of relation keys encrypted with
multiple different principal keys.
2025-04-07 10:30:02 +02:00
Andreas Karlsson
e9d4927b2c Use correct type for fd 2025-04-04 21:21:20 +02:00
Andreas Karlsson
d788185440 PG-1437 Simplify pg_tde_read_one_map_entry2()
While this does not merge the two similar functions it removes a lot
of cruft from pg_tde_read_one_map_entry2() making the functions more
similar and the code easier to read.
2025-04-04 21:21:20 +02:00
Andreas Karlsson
36bc82d6c0 PG-1455 Change xlog base IVs to use addition
This way they can eventually be made more similar to using OpenSSL
for encrypting and decrypting the CTR stream.
2025-04-04 19:50:07 +02:00
Andreas Karlsson
72050ff258 PG-1455 Add random base numbers to IVs for WAL encryption
Same as last commit but for the WAL encryption.

Rewrote the calculation in a way gcc's vectorizer likes, as verified
with Godbolt. The code generated by clang is ok and branch free but it
fails to properly vectorize both before and after.
2025-04-04 19:50:07 +02:00
Andreas Karlsson
127c568623 PG-1455 Add random base numbers to IVs for relation data
We might as well increase the entropy by adding a random base value to
the IVs used used when encrypting relations. But since for now the pair
of key + IV is generated and used together it adds little extra security
over what we already have.

We add the IV with XOR since that is a cheap and easy operation which
uases no extra collissions.
2025-04-04 19:50:07 +02:00
Andreas Karlsson
7ea53b4176 PG-1455 Add field with random base IV to relation and WAL keys
For now we do not use this field but we plan to use it when encrypting
Wrelation data and WAL.
2025-04-04 19:50:07 +02:00
Andreas Karlsson
b223d2d254 PG-1437 Fix race condition in the event trigger
If we look up something about a relation in the command start event
trigger we need to hold onto that lock until the end of the command
and not release it so no other commd is able to change the data we
looked at between now and when the DDL command itself actually locks
the relation.
2025-04-04 19:48:52 +02:00
Andreas Karlsson
21a3794bbd PG-1437 Clean up definition of special TDE oids
The oids worked as-is, in general any reserved catalog oid which is
frefers to an object of another type will work as a special magical
oid. Here we decide to use tablespce oids for special database
values and a database oid, 1, for the relation value. But in the
latter case anything would have worked since we are guarnteed to
have no collissions due to the database oid not being and actual
database.

The old solution which use a mix worked too but this is more
consistent.
2025-04-03 12:09:05 +02:00
Andreas Karlsson
9ea86cc19f PG-1437 Document and pick a smaller initial DSA size for principal key cache
The previous 8192 * 100 initial allocation was arbitrary and bigger than
necessary. We pick something bassically as arbitrary but now a multiple of
the actual page size of DSAs, 4 KB.
2025-04-03 11:22:40 +02:00
Andreas Karlsson
ba763da204 PG-1437 Error out if another SMGR has been laoded 2025-04-03 11:22:40 +02:00