-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathobliv_ocalls.c
More file actions
486 lines (397 loc) · 11.6 KB
/
obliv_ocalls.c
File metadata and controls
486 lines (397 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
#include "postgres.h"
#include "access/htup_details.h"
#include "access/genam.h"
#include "access/hash.h"
#include "access/heapam.h"
#include "storage/smgr.h"
#include "storage/bufpage.h"
#include "include/obliv_page.h"
#include "include/oblivpg_fdw.h"
#include "include/obliv_status.h"
#include "include/obliv_ocalls.h"
#include "utils/fmgroids.h"
#ifndef UNSAFE
#include "Enclave_u.h"
#else
#include "Enclave_dt.h"
#endif
#include "oram/plblock.h"
typedef struct SoeHashPageOpaqueData
{
BlockNumber hasho_prevblkno; /* see above */
BlockNumber hasho_nextblkno; /* see above */
Bucket hasho_bucket; /* bucket number this pg belongs to */
uint16 hasho_flag; /* page type code + flag bits, see above */
uint16 hasho_page_id; /* for identification of hash indexes */
int o_blkno; /* real block number or Dummy Block */
} SoeHashPageOpaqueData;
typedef SoeHashPageOpaqueData * SoeHashPageOpaque;
#define SOE_CONTEXT "SOE_CONTEXT"
FdwOblivTableStatus status;
char *tableName = "mirror_usertable";
char *indexName = "mirror_usertable_key";
Oid ihOID;
void
oc_logger(const char *str)
{
elog(DEBUG1, "%s", str);
}
void
print_status()
{
elog(DEBUG1, "tableName is %s and indexName is %s ", tableName, indexName);
}
void
setupOblivStatus(FdwOblivTableStatus instatus, const char *tbName, const char *idName, Oid indexHandlerOID)
{
status.relTableMirrorId = instatus.relTableMirrorId;
status.relIndexMirrorId = instatus.relIndexMirrorId;
status.tableRelFileNode = instatus.tableRelFileNode;
status.filesInitated = instatus.filesInitated;
status.indexNBlocks = instatus.indexNBlocks;
status.tableNBlocks = instatus.tableNBlocks;
ihOID = indexHandlerOID;
//tableName = (char *) palloc(strlen(tbName) + 1);
//indexName = (char *) palloc(strlen(idName) + 1);
//memcpy(tableName, tbName, strlen(tbName) + 1);
//memcpy(indexName, idName, strlen(idName) + 1);
}
void
closeOblivStatus()
{
pfree(tableName);
pfree(indexName);
}
/**
* The initialization follows the underlying hash index relation follows
* the logic of the function _hash_alloc_buckets in the hashpage.c file.
*
* The idea of this initialization procedure is to create the requested
* number of blocks (nblocks) as empty pages in the index relation file,
* including the metapage which was initialized by the database when the index
* is created.
*
* With this procedure, the hash index functions in the enclave can ask for any
* page on storage within the range of the nblocks and initialize the page as it
* sees fit. The hash within the enclave works with a virtual index file
* abstraction that maps the enclave pages to the index relation pages
* pre-allocated in this procedure.
*/
void
initIndex(const char *filename, const char *pages, unsigned int nblocks, unsigned int blockSize, int initOffset)
{
Relation rel;
int offset = 0;
Buffer buffer = 0;
Page page = NULL;
//elog(DEBUG1, "Requested to init index %s for tableName %s and index name %s", filename, tableName, indexName);
if (status.relIndexMirrorId != InvalidOid)
{
rel = index_open(status.relIndexMirrorId, ExclusiveLock);
do
{
/**
* when the index is initialized by the database the first four blocks
* of an Hash index already exist and have some defined data.
* we override this blocks
* to be initialized by the soe blocks.
**/
if (ihOID == F_HASHHANDLER && (initOffset + offset) < 4)
{
buffer = ReadBuffer(rel, offset);
}
else if (ihOID == F_BTHANDLER && (initOffset + offset) == 0)
{
/**
* When the btree index is created, block 0 is initiated and
* has content that must be deleted.
*/
buffer = ReadBuffer(rel, offset);
}
else
{
buffer = ReadBuffer(rel, P_NEW);
}
/**
* Buffers are not being locked as this extension is not
* considering concurrent accesses to the
* relations. It might raise some unexpected errors if the
* postgres implementation checks if buffers
* have pins or locks associated.
**/
page = BufferGetPage(buffer);
memcpy(page, pages + (offset * BLCKSZ), blockSize);
/*
* We mark all the new buffers dirty, but do nothing to write them
* out; they'll probably get used soon, and even if they are not,
* a crash will leave an okay all-zeroes page on disk.
*/
MarkBufferDirty(buffer);
/**
* The original function RelationAdddExtraBlocks updates the
* free space map of the relation but this function does not.
* The free space map is not updated for now and
* must be considered if it can be used at all since it keeps
* track in plaintext how much
* space is free in each relation block. Only use the fsm if
* it's really necessary for the prototype.
*/
ReleaseBuffer(buffer);
offset += 1;
} while (offset < nblocks);
index_close(rel, ExclusiveLock);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Oblivious table with name %s does not exist in the database",
filename)));
}
}
/**
* This function follows a logic similar to the function
* RelationAddExtraBlocks in hio.c which pre-extend a
* relation by a calculated amount of blocks. The idea in this
* function (fileInit) is to initiate every page in
* the ORAM relation so that future read or write requests don't have to
* worry about this. Furthermore, since we know the
* exact number of blocks the relation must have, we can allocate
* the space once and never worry about this again.
**/
void
initRelation(const char *filename, const char *pages, unsigned int nblocks, unsigned int blockSize)
{
Relation rel;
Buffer buffer = 0;
int offset = 0;
Page page = NULL;
//elog(DEBUG1, "Initializing heap relation %s with nblocks %d of size %d", filename, nblocks, blockSize);
if (status.relTableMirrorId != InvalidOid)
{
rel = heap_open(status.relTableMirrorId, ExclusiveLock);
do
{
buffer = ReadBuffer(rel, P_NEW);
/**
* Buffers are not being locked as this extension is not
* considering concurrent accesses to the
* relations. It might raise some unexpected errors if the
* postgres implementation checks if buffers
* have pins or locks associated.
**/
page = BufferGetPage(buffer);
if(!PageIsVerified(pages + (offset * BLCKSZ), BufferGetBlockNumber(buffer))){
elog(ERROR, "Page is not verified when init relation. block %d", offset);
};
memcpy(page, (pages + (offset * BLCKSZ)), blockSize);
/*
* We mark all the new buffers dirty, but do nothing to write them
* out; they'll probably get used soon, and even if they are not,
* a crash will leave an okay all-zeroes page on disk.
*/
MarkBufferDirty(buffer);
/**
* The original function RelationAdddExtraBlocks updates the
* free space map of the relation but this function does not.
* The free space map is not updated for now and
* must be considered if it can be used at all since it keeps
* track in plaintext how much
* space is free in each relation block. Only use the fsm if
* it's really necessary for the prototype.
*/
ReleaseBuffer(buffer);
offset += 1;
} while (offset < nblocks);
heap_close(rel, ExclusiveLock);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Oblivious table with name %s does not exist in the database",
filename)));
}
}
#ifndef UNSAFE
void
#else
sgx_status_t
#endif
outFileInit(const char *filename, const char *pages, unsigned int nblocks, unsigned int blocksize, int pageSize, int initOffset)
{
if (strcmp(filename, tableName) == 0)
{
initRelation(filename, pages, nblocks, blocksize);
}
else if (strcmp(filename, indexName) == 0)
{
initIndex(filename, pages, nblocks, blocksize, initOffset);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Enclave requested a file initialization for %s, %s, %s that is not supported",
filename, tableName, indexName)));
}
#ifdef UNSAFE
return SGX_SUCCESS;
#endif
}
#ifndef UNSAFE
void
#else
sgx_status_t
#endif
outFileRead(char *page, const char *filename, int blkno, int pageSize)
{
Relation rel;
Buffer buffer;
Page heapPage;
bool isIndex;
Oid targetTable;
//elog(DEBUG1, "outFileRead relation %s blocknum %d and size %d", filename, blkno, pageSize);
if (strcmp(filename, tableName) == 0)
{
isIndex = false;
targetTable = status.relTableMirrorId;
}
else if (strcmp(filename, indexName) == 0)
{
isIndex = true;
targetTable = status.relIndexMirrorId;
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Enclave requested a file read for %s, %s, %s that is not supported",
filename, tableName, indexName)));
}
if (targetTable != InvalidOid)
{
if (isIndex)
{
rel = index_open(targetTable, RowExclusiveLock);
}
else
{
rel = heap_open(targetTable, RowExclusiveLock);
}
/**
* Buffers are not being locked as this extension is not
* considering concurrent accesses to the
* relations. It might raise some unexpected errors if the
* postgres implementation checks if buffers
* have pins or locks associated.
**/
buffer = ReadBuffer(rel, blkno);
heapPage = BufferGetPage(buffer);
memcpy(page, heapPage, pageSize);
ReleaseBuffer(buffer);
if (isIndex)
{
index_close(rel, RowExclusiveLock);
}
else
{
heap_close(rel, RowExclusiveLock);
}
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Oblivious table with name %s does not exist in the database",
filename)));
}
#ifdef UNSAFE
return SGX_SUCCESS;
#endif
}
#ifndef UNSAFE
void
#else
sgx_status_t
#endif
outFileWrite(const char *page, const char *filename, int blkno, int pageSize)
{
Relation rel;
Page heapPage;
Buffer buffer;
bool isIndex;
Oid targetTable;
//elog(DEBUG1, "outFileWrite relation %s blocknum %d and size %d", filename, blkno, pageSize);
buffer = 0;
if (strcmp(filename, tableName) == 0)
{
isIndex = false;
targetTable = status.relTableMirrorId;
}
else if (strcmp(filename, indexName) == 0)
{
isIndex = true;
targetTable = status.relIndexMirrorId;
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Enclave requested a outFileWrite for %s that is not supported",
filename)));
}
if (status.relTableMirrorId != InvalidOid)
{
if (isIndex)
{
rel = index_open(targetTable, RowExclusiveLock);
}
else
{
rel = heap_open(targetTable, RowExclusiveLock);
}
buffer = ReadBuffer(rel, blkno);
/**
* Buffers are not being locked as this extension is not
* considering concurrent accesses to the
* relations. It might raise some unexpected errors if the
* postgres implementation checks if buffers
* have pins or locks associated.
**/
heapPage = BufferGetPage(buffer);
memcpy(heapPage, page, pageSize);
MarkBufferDirty(buffer);
ReleaseBuffer(buffer);
if (isIndex)
{
index_close(rel, RowExclusiveLock);
}
else
{
heap_close(rel, RowExclusiveLock);
}
}
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("Oblivious table with name %s does not exist in the database",
filename)));
}
#ifdef UNSAFE
return SGX_SUCCESS;
#endif
}
#ifndef UNSAFE
void
#else
sgx_status_t
#endif
outFileClose(const char *filename)
{
elog(DEBUG1, "OutFileClose invoked");
#ifdef UNSAFE
return SGX_SUCCESS;
#endif
}