10
10
11
11
#ifdef PERCONA_EXT
12
12
13
+ typedef struct TDESMgrRelationData
14
+ {
15
+ /* parent data */
16
+ SMgrRelationData reln ;
17
+ /*
18
+ * for md.c; per-fork arrays of the number of open segments
19
+ * (md_num_open_segs) and the segments themselves (md_seg_fds).
20
+ */
21
+ int md_num_open_segs [MAX_FORKNUM + 1 ];
22
+ struct _MdfdVec * md_seg_fds [MAX_FORKNUM + 1 ];
23
+
24
+ bool encrypted_relation ;
25
+ RelKeyData relKey ;
26
+ } TDESMgrRelationData ;
27
+
28
+ typedef TDESMgrRelationData * TDESMgrRelation ;
29
+
30
+ /*
31
+ * we only encrypt main and init forks
32
+ */
33
+ static inline bool
34
+ tde_is_encryption_required (TDESMgrRelation tdereln , ForkNumber forknum )
35
+ {
36
+ return (tdereln -> encrypted_relation && (forknum == MAIN_FORKNUM || forknum == INIT_FORKNUM ));
37
+ }
38
+
13
39
static RelKeyData *
14
40
tde_smgr_get_key (SMgrRelation reln )
15
41
{
@@ -62,22 +88,21 @@ static void
62
88
tde_mdwritev (SMgrRelation reln , ForkNumber forknum , BlockNumber blocknum ,
63
89
const void * * buffers , BlockNumber nblocks , bool skipFsync )
64
90
{
65
- AesInit ();
66
-
67
- RelKeyData * rkd = tde_smgr_get_key (reln );
91
+ TDESMgrRelation tdereln = (TDESMgrRelation )reln ;
92
+ RelKeyData * rkd = & tdereln -> relKey ;
68
93
69
- if ( rkd == NULL )
94
+ if (! tde_is_encryption_required ( tdereln , forknum ) )
70
95
{
71
96
mdwritev (reln , forknum , blocknum , buffers , nblocks , skipFsync );
72
-
73
- return ;
74
97
}
75
98
else
76
99
{
77
100
char * local_blocks = palloc (BLCKSZ * (nblocks + 1 ));
78
101
char * local_blocks_aligned = (char * )TYPEALIGN (PG_IO_ALIGN_SIZE , local_blocks );
79
102
const void * * local_buffers = palloc (sizeof (void * ) * nblocks );
80
103
104
+ AesInit ();
105
+
81
106
for (int i = 0 ; i < nblocks ; ++ i )
82
107
{
83
108
int out_len = BLCKSZ ;
@@ -102,29 +127,26 @@ static void
102
127
tde_mdextend (SMgrRelation reln , ForkNumber forknum , BlockNumber blocknum ,
103
128
const void * buffer , bool skipFsync )
104
129
{
105
- RelKeyData * rkd ;
130
+ TDESMgrRelation tdereln = (TDESMgrRelation )reln ;
131
+ RelKeyData * rkd = & tdereln -> relKey ;
106
132
107
- AesInit ();
108
-
109
- rkd = tde_smgr_get_key (reln );
110
-
111
- if (rkd == NULL )
133
+ if (!tde_is_encryption_required (tdereln , forknum ))
112
134
{
113
135
mdextend (reln , forknum , blocknum , buffer , skipFsync );
114
-
115
- return ;
116
136
}
117
137
else
118
138
{
119
-
120
139
char * local_blocks = palloc (BLCKSZ * (1 + 1 ));
121
140
char * local_blocks_aligned = (char * )TYPEALIGN (PG_IO_ALIGN_SIZE , local_blocks );
122
141
int out_len = BLCKSZ ;
142
+ unsigned char iv [16 ] = {
143
+ 0 ,
144
+ };
123
145
124
- unsigned char iv [ 16 ] = { 0 ,} ;
125
- memcpy (iv + 4 , & blocknum , sizeof (BlockNumber ));
146
+ AesInit () ;
147
+ memcpy (iv + 4 , & blocknum , sizeof (BlockNumber ));
126
148
127
- AesEncrypt (rkd -> internal_key .key , iv , ((char * )buffer ), BLCKSZ , local_blocks_aligned , & out_len );
149
+ AesEncrypt (rkd -> internal_key .key , iv , ((char * )buffer ), BLCKSZ , local_blocks_aligned , & out_len );
128
150
129
151
mdextend (reln , forknum , blocknum , local_blocks_aligned , skipFsync );
130
152
@@ -136,21 +158,23 @@ static void
136
158
tde_mdreadv (SMgrRelation reln , ForkNumber forknum , BlockNumber blocknum ,
137
159
void * * buffers , BlockNumber nblocks )
138
160
{
139
- RelKeyData * rkd ;
140
161
int out_len = BLCKSZ ;
141
-
142
- AesInit () ;
162
+ TDESMgrRelation tdereln = ( TDESMgrRelation ) reln ;
163
+ RelKeyData * rkd = & tdereln -> relKey ;
143
164
144
165
mdreadv (reln , forknum , blocknum , buffers , nblocks );
145
166
146
- rkd = tde_smgr_get_key (reln );
147
-
148
- if (rkd == NULL )
167
+ if (!tde_is_encryption_required (tdereln , forknum ))
149
168
return ;
150
169
170
+ AesInit ();
171
+
151
172
for (int i = 0 ; i < nblocks ; ++ i )
152
173
{
153
174
bool allZero = true;
175
+ BlockNumber bn = blocknum + i ;
176
+ unsigned char iv [16 ] = {0 ,};
177
+
154
178
for (int j = 0 ; j < 32 ; ++ j )
155
179
{
156
180
if (((char * * )buffers )[i ][j ] != 0 )
@@ -167,8 +191,6 @@ tde_mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
167
191
if (allZero )
168
192
continue ;
169
193
170
- BlockNumber bn = blocknum + i ;
171
- unsigned char iv [16 ] = {0 ,};
172
194
memcpy (iv + 4 , & bn , sizeof (BlockNumber ));
173
195
174
196
AesDecrypt (rkd -> internal_key .key , iv , ((char * * )buffers )[i ], BLCKSZ , ((char * * )buffers )[i ], & out_len );
@@ -178,20 +200,50 @@ tde_mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
178
200
static void
179
201
tde_mdcreate (SMgrRelation reln , ForkNumber forknum , bool isRedo )
180
202
{
203
+ TDESMgrRelation tdereln = (TDESMgrRelation )reln ;
181
204
// This is the only function that gets called during actual CREATE TABLE/INDEX (EVENT TRIGGER)
182
205
// so we create the key here by loading it
183
206
// Later calls then decide to encrypt or not based on the existence of the key
184
- tde_smgr_get_key (reln );
207
+ RelKeyData * key = tde_smgr_get_key (reln );
208
+ if (key )
209
+ {
210
+ tdereln -> encrypted_relation = true;
211
+ memcpy (& tdereln -> relKey , key , sizeof (RelKeyData ));
212
+ }
213
+ else
214
+ {
215
+ tdereln -> encrypted_relation = false;
216
+ }
217
+
185
218
return mdcreate (reln , forknum , isRedo );
186
219
}
187
220
221
+ /*
222
+ * mdopen() -- Initialize newly-opened relation.
223
+ */
224
+ static void
225
+ tde_mdopen (SMgrRelation reln )
226
+ {
227
+ TDESMgrRelation tdereln = (TDESMgrRelation )reln ;
228
+ RelKeyData * key = tde_smgr_get_key (reln );
229
+ if (key )
230
+ {
231
+ tdereln -> encrypted_relation = true;
232
+ memcpy (& tdereln -> relKey , key , sizeof (RelKeyData ));
233
+ }
234
+ else
235
+ {
236
+ tdereln -> encrypted_relation = false;
237
+ }
238
+ mdopen (reln );
239
+ }
188
240
189
241
static SMgrId tde_smgr_id ;
190
242
static const struct f_smgr tde_smgr = {
191
243
.name = "tde" ,
192
244
.smgr_init = mdinit ,
193
245
.smgr_shutdown = NULL ,
194
- .smgr_open = mdopen ,
246
+ .smgr_open = tde_mdopen ,
195
247
.smgr_close = mdclose ,
196
248
.smgr_create = tde_mdcreate ,
197
249
.smgr_exists = mdexists ,
@@ -210,7 +262,7 @@ static const struct f_smgr tde_smgr = {
210
262
211
263
void RegisterStorageMgr (void )
212
264
{
213
- tde_smgr_id = smgr_register (& tde_smgr , 0 );
265
+ tde_smgr_id = smgr_register (& tde_smgr , sizeof ( TDESMgrRelationData ) );
214
266
215
267
// TODO: figure out how this part should work in a real extension
216
268
storage_manager_id = tde_smgr_id ;
0 commit comments