@@ -14,6 +14,9 @@ typedef enum TDEMgrRelationDataEncryptionStatus
14
14
15
15
/* This is an encrypted relation, and we have the key available. */
16
16
RELATION_KEY_AVAILABLE = 1 ,
17
+
18
+ /* This is an encrypted relation, but we haven't loaded the key yet. */
19
+ RELATION_KEY_NOT_AVAILABLE = 2 ,
17
20
} TDEMgrRelationDataEncryptionStatus ;
18
21
19
22
typedef struct TDESMgrRelationData
@@ -36,6 +39,16 @@ typedef TDESMgrRelationData *TDESMgrRelation;
36
39
37
40
static void CalcBlockIv (ForkNumber forknum , BlockNumber bn , const unsigned char * base_iv , unsigned char * iv );
38
41
42
+ static bool
43
+ tde_smgr_is_encrypted (const RelFileLocatorBackend * smgr_rlocator )
44
+ {
45
+ /* Do not try to encrypt/decrypt catalog tables */
46
+ if (IsCatalogRelationOid (smgr_rlocator -> locator .relNumber ))
47
+ return false;
48
+
49
+ return IsSMGRRelationEncrypted (* smgr_rlocator );
50
+ }
51
+
39
52
static InternalKey *
40
53
tde_smgr_get_key (const RelFileLocatorBackend * smgr_rlocator )
41
54
{
@@ -80,18 +93,26 @@ tde_mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
80
93
const void * * buffers , BlockNumber nblocks , bool skipFsync )
81
94
{
82
95
TDESMgrRelation tdereln = (TDESMgrRelation ) reln ;
83
- InternalKey * int_key = & tdereln -> relKey ;
84
96
85
97
if (tdereln -> encryption_status == RELATION_NOT_ENCRYPTED )
86
98
{
87
99
mdwritev (reln , forknum , blocknum , buffers , nblocks , skipFsync );
88
100
}
89
101
else
90
102
{
103
+ InternalKey * int_key ;
91
104
unsigned char * local_blocks = palloc (BLCKSZ * (nblocks + 1 ));
92
105
unsigned char * local_blocks_aligned = (unsigned char * ) TYPEALIGN (PG_IO_ALIGN_SIZE , local_blocks );
93
106
void * * local_buffers = palloc_array (void * , nblocks );
94
107
108
+ if (tdereln -> encryption_status == RELATION_KEY_NOT_AVAILABLE )
109
+ {
110
+ tdereln -> relKey = * tde_smgr_get_key (& reln -> smgr_rlocator );
111
+ tdereln -> encryption_status = RELATION_KEY_AVAILABLE ;
112
+ }
113
+
114
+ int_key = & tdereln -> relKey ;
115
+
95
116
for (int i = 0 ; i < nblocks ; ++ i )
96
117
{
97
118
BlockNumber bn = blocknum + i ;
@@ -139,18 +160,26 @@ tde_mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
139
160
const void * buffer , bool skipFsync )
140
161
{
141
162
TDESMgrRelation tdereln = (TDESMgrRelation ) reln ;
142
- InternalKey * int_key = & tdereln -> relKey ;
143
163
144
164
if (tdereln -> encryption_status == RELATION_NOT_ENCRYPTED )
145
165
{
146
166
mdextend (reln , forknum , blocknum , buffer , skipFsync );
147
167
}
148
168
else
149
169
{
170
+ InternalKey * int_key ;
150
171
unsigned char * local_blocks = palloc (BLCKSZ * (1 + 1 ));
151
172
unsigned char * local_blocks_aligned = (unsigned char * ) TYPEALIGN (PG_IO_ALIGN_SIZE , local_blocks );
152
173
unsigned char iv [16 ];
153
174
175
+ if (tdereln -> encryption_status == RELATION_KEY_NOT_AVAILABLE )
176
+ {
177
+ tdereln -> relKey = * tde_smgr_get_key (& reln -> smgr_rlocator );
178
+ tdereln -> encryption_status = RELATION_KEY_AVAILABLE ;
179
+ }
180
+
181
+ int_key = & tdereln -> relKey ;
182
+
154
183
CalcBlockIv (forknum , blocknum , int_key -> base_iv , iv );
155
184
156
185
AesEncrypt (int_key -> key , iv , ((unsigned char * ) buffer ), BLCKSZ , local_blocks_aligned );
@@ -172,6 +201,13 @@ tde_mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
172
201
173
202
if (tdereln -> encryption_status == RELATION_NOT_ENCRYPTED )
174
203
return ;
204
+ else if (tdereln -> encryption_status == RELATION_KEY_NOT_AVAILABLE )
205
+ {
206
+ tdereln -> relKey = * tde_smgr_get_key (& reln -> smgr_rlocator );
207
+ tdereln -> encryption_status = RELATION_KEY_AVAILABLE ;
208
+ }
209
+
210
+ int_key = & tdereln -> relKey ;
175
211
176
212
for (int i = 0 ; i < nblocks ; ++ i )
177
213
{
@@ -255,21 +291,21 @@ tde_mdcreate(RelFileLocator relold, SMgrRelation reln, ForkNumber forknum, bool
255
291
256
292
/*
257
293
* mdopen() -- Initialize newly-opened relation.
294
+ *
295
+ * The current transaction might already be commited when this function is
296
+ * called, so do not call any code that uses ereport(ERROR) or otherwise tries
297
+ * to abort the transaction.
258
298
*/
259
299
static void
260
300
tde_mdopen (SMgrRelation reln )
261
301
{
262
302
TDESMgrRelation tdereln = (TDESMgrRelation ) reln ;
263
- InternalKey * key ;
264
303
265
304
mdopen (reln );
266
305
267
- key = tde_smgr_get_key (& reln -> smgr_rlocator );
268
-
269
- if (key )
306
+ if (tde_smgr_is_encrypted (& reln -> smgr_rlocator ))
270
307
{
271
- tdereln -> encryption_status = RELATION_KEY_AVAILABLE ;
272
- tdereln -> relKey = * key ;
308
+ tdereln -> encryption_status = RELATION_KEY_NOT_AVAILABLE ;
273
309
}
274
310
else
275
311
{
0 commit comments