@@ -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 ;
@@ -144,18 +165,26 @@ tde_mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
144
165
const void * buffer , bool skipFsync )
145
166
{
146
167
TDESMgrRelation tdereln = (TDESMgrRelation ) reln ;
147
- InternalKey * int_key = & tdereln -> relKey ;
148
168
149
169
if (tdereln -> encryption_status == RELATION_NOT_ENCRYPTED )
150
170
{
151
171
mdextend (reln , forknum , blocknum , buffer , skipFsync );
152
172
}
153
173
else
154
174
{
175
+ InternalKey * int_key ;
155
176
unsigned char * local_blocks = palloc (BLCKSZ * (1 + 1 ));
156
177
unsigned char * local_blocks_aligned = (unsigned char * ) TYPEALIGN (PG_IO_ALIGN_SIZE , local_blocks );
157
178
unsigned char iv [16 ];
158
179
180
+ if (tdereln -> encryption_status == RELATION_KEY_NOT_AVAILABLE )
181
+ {
182
+ tdereln -> relKey = * tde_smgr_get_key (& reln -> smgr_rlocator );
183
+ tdereln -> encryption_status = RELATION_KEY_AVAILABLE ;
184
+ }
185
+
186
+ int_key = & tdereln -> relKey ;
187
+
159
188
CalcBlockIv (forknum , blocknum , int_key -> base_iv , iv );
160
189
161
190
AesEncrypt (int_key -> key , iv , ((unsigned char * ) buffer ), BLCKSZ , local_blocks_aligned );
@@ -171,12 +200,19 @@ tde_mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
171
200
void * * buffers , BlockNumber nblocks )
172
201
{
173
202
TDESMgrRelation tdereln = (TDESMgrRelation ) reln ;
174
- InternalKey * int_key = & tdereln -> relKey ;
203
+ InternalKey * int_key ;
175
204
176
205
mdreadv (reln , forknum , blocknum , buffers , nblocks );
177
206
178
207
if (tdereln -> encryption_status == RELATION_NOT_ENCRYPTED )
179
208
return ;
209
+ else if (tdereln -> encryption_status == RELATION_KEY_NOT_AVAILABLE )
210
+ {
211
+ tdereln -> relKey = * tde_smgr_get_key (& reln -> smgr_rlocator );
212
+ tdereln -> encryption_status = RELATION_KEY_AVAILABLE ;
213
+ }
214
+
215
+ int_key = & tdereln -> relKey ;
180
216
181
217
for (int i = 0 ; i < nblocks ; ++ i )
182
218
{
@@ -260,21 +296,21 @@ tde_mdcreate(RelFileLocator relold, SMgrRelation reln, ForkNumber forknum, bool
260
296
261
297
/*
262
298
* mdopen() -- Initialize newly-opened relation.
299
+ *
300
+ * The current transaction might already be commited when this function is
301
+ * called, so do not call any code that uses ereport(ERROR) or otherwise tries
302
+ * to abort the transaction.
263
303
*/
264
304
static void
265
305
tde_mdopen (SMgrRelation reln )
266
306
{
267
307
TDESMgrRelation tdereln = (TDESMgrRelation ) reln ;
268
- InternalKey * key ;
269
308
270
309
mdopen (reln );
271
310
272
- key = tde_smgr_get_key (& reln -> smgr_rlocator );
273
-
274
- if (key )
311
+ if (tde_smgr_is_encrypted (& reln -> smgr_rlocator ))
275
312
{
276
- tdereln -> encryption_status = RELATION_KEY_AVAILABLE ;
277
- tdereln -> relKey = * key ;
313
+ tdereln -> encryption_status = RELATION_KEY_NOT_AVAILABLE ;
278
314
}
279
315
else
280
316
{
0 commit comments