From 87d132977e25cf6931415892d1c4966d67cded73 Mon Sep 17 00:00:00 2001 From: Zsolt Parragi Date: Tue, 27 Feb 2024 13:03:10 +0000 Subject: [PATCH] Also use the CommandID in tuple IVs (#119) Currently tupple iv calculatino is based only on the CTID, which means that when postgres reuses the same address, it also reuses the same IV. This makes our encryption theoretically weaker, in case of some unlikely but not impossible attack scenarios. As an improvement this commit also adds the command id into the calculation. As the (ctid, cid) pair will be basically always unique, this solves the problem. Fixes #112 --- src/encryption/enc_tde.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/encryption/enc_tde.c b/src/encryption/enc_tde.c index 51f89df0..f83a3cf2 100644 --- a/src/encryption/enc_tde.c +++ b/src/encryption/enc_tde.c @@ -20,13 +20,16 @@ static void iv_prefix_debug(const char* iv_prefix, char* out_hex) #endif static void -SetIVPrefix(ItemPointerData* ip, char* iv_prefix) +SetIVPrefix(ItemPointerData* ip, CommandId cid, char* iv_prefix) { /* We have up to 16 bytes for the entire IV * The higher bytes (starting with 15) are used for the incrementing counter * The lower bytes (in this case, 0..5) are used for the tuple identification * Tuple identification is based on CTID, which currently is 48 bytes in * postgres: 4 bytes for the block id and 2 bytes for the position id + * After the CTID, we also add the CommandID, which is 4 bytes + * This ensures that even when postgres reuses the same CTID in time, + * with the different CID we still have a unique IV. */ iv_prefix[0] = ip->ip_blkid.bi_hi / 256; iv_prefix[1] = ip->ip_blkid.bi_hi % 256; @@ -34,6 +37,7 @@ SetIVPrefix(ItemPointerData* ip, char* iv_prefix) iv_prefix[3] = ip->ip_blkid.bi_lo % 256; iv_prefix[4] = ip->ip_posid / 256; iv_prefix[5] = ip->ip_posid % 256; + memcpy(iv_prefix + 6, &cid, 4); } /* @@ -123,7 +127,7 @@ pg_tde_crypt_tuple(HeapTuple tuple, HeapTuple out_tuple, RelKeyData* key, const char *tup_data = (char*)tuple->t_data + tuple->t_data->t_hoff; char *out_data = (char*)out_tuple->t_data + out_tuple->t_data->t_hoff; - SetIVPrefix(&tuple->t_self, iv_prefix); + SetIVPrefix(&tuple->t_self, tuple->t_data->t_choice.t_heap.t_field3.t_cid, iv_prefix); #ifdef ENCRYPTION_DEBUG ereport(LOG, @@ -162,7 +166,7 @@ PGTdePageAddItemExtended(RelFileLocator rel, ItemPointerSet(&ip, bn, off); - SetIVPrefix(&ip, iv_prefix); + SetIVPrefix(&ip, ((HeapTupleHeader)item)->t_choice.t_heap.t_field3.t_cid, iv_prefix); PG_TDE_ENCRYPT_PAGE_ITEM(iv_prefix, 0, data, data_len, toAddr, key); return off;