Skip to content

Commit 64ce7bb

Browse files
committed
Merge branch 'PGPRO-242-aes-ctr-encr' into PGPROEE9_6
2 parents cef538d + 7dfab09 commit 64ce7bb

File tree

7 files changed

+2006
-87
lines changed

7 files changed

+2006
-87
lines changed

src/backend/storage/file/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ subdir = src/backend/storage/file
1212
top_builddir = ../../../..
1313
include $(top_builddir)/src/Makefile.global
1414

15-
OBJS = fd.o cfs.o buffile.o copydir.o reinit.o
15+
OBJS = fd.o cfs.o buffile.o copydir.o reinit.o rijndael.o
1616

1717
include $(top_srcdir)/src/backend/common.mk

src/backend/storage/file/cfs.c

Lines changed: 117 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -245,95 +245,143 @@ char const* cfs_algorithm()
245245

246246
#endif
247247

248-
249-
/* ----------------------------------------------------------------
250-
* Section 2: Encryption related functionality.
251-
*
252-
* TODO
253-
* - replace rc4 algrithm with something more appropriate
254-
* - add more comments
255-
* ----------------------------------------------------------------
256-
*/
257-
static void cfs_rc4_encrypt_block(void* block, uint32 offs, uint32 block_size)
258-
{
259-
uint32 i;
260-
uint8 temp;
261-
uint8* dst = (uint8*)block;
262-
int next_state;
263-
uint8 state[CFS_CIPHER_KEY_SIZE];
264-
int x = 0, y = 0;
265-
uint32 skip = (offs / BLCKSZ + block_size) % CFS_CIPHER_KEY_SIZE;
266-
267-
memcpy(state, cfs_state->cipher_key, CFS_CIPHER_KEY_SIZE);
268-
for (i = 0; i < skip; i++) {
269-
x = (x + 1) % CFS_CIPHER_KEY_SIZE;
270-
y = (y + state[x]) % CFS_CIPHER_KEY_SIZE;
271-
temp = state[x];
272-
state[x] = state[y];
273-
state[y] = temp;
274-
}
275-
for (i = 0; i < block_size; i++) {
276-
x = (x + 1) % CFS_CIPHER_KEY_SIZE;
277-
y = (y + state[x]) % CFS_CIPHER_KEY_SIZE;
278-
temp = state[x];
279-
state[x] = state[y];
280-
state[y] = temp;
281-
next_state = (state[x] + state[y]) % CFS_CIPHER_KEY_SIZE;
282-
dst[i] ^= state[next_state];
283-
}
284-
}
285-
286248
/*
287249
* Get env variable PG_CIPHER_KEY and initialize encryption state.
288250
* Unset variable afterward.
289-
* Now implements cf4.
290251
*/
291-
static void cfs_encrypt_init(void)
252+
static void cfs_crypto_init(void)
292253
{
293-
int index1 = 0;
294-
int index2 = 0;
295-
int i;
296-
uint8 temp;
297254
int key_length;
298-
int x = 0, y = 0;
299255
char* cipher_key;
300-
uint8* rc4_init_state = cfs_state->cipher_key;
256+
uint8 aes_key[32] = {0}; /* at most 256 bits */
301257

302258
cipher_key = getenv("PG_CIPHER_KEY");
303259
if (cipher_key == NULL) {
304260
elog(ERROR, "PG_CIPHER_KEY environment variable is not set");
305261
}
306262
unsetenv("PG_CIPHER_KEY"); /* disable inspection of this environment variable */
307263
key_length = strlen(cipher_key);
308-
for (i = 0; i < CFS_CIPHER_KEY_SIZE; ++i) {
309-
rc4_init_state[i] = (uint8)i;
310-
}
311-
for (i = 0; i < CFS_CIPHER_KEY_SIZE; ++i) {
312-
index2 = (cipher_key[index1] + rc4_init_state[i] + index2) % CFS_CIPHER_KEY_SIZE;
313-
temp = rc4_init_state[i];
314-
rc4_init_state[i] = rc4_init_state[index2];
315-
rc4_init_state[index2] = temp;
316-
index1 = (index1 + 1) % key_length;
317-
}
318-
for (i = 0; i < CFS_RC4_DROP_N; i++) {
319-
x = (x + 1) % CFS_CIPHER_KEY_SIZE;
320-
y = (y + rc4_init_state[x]) % CFS_CIPHER_KEY_SIZE;
321-
temp = rc4_init_state[x];
322-
rc4_init_state[x] = rc4_init_state[y];
323-
rc4_init_state[y] = temp;
324-
}
264+
265+
memcpy(&aes_key, cipher_key, key_length > sizeof(aes_key) ? sizeof(aes_key) : key_length);
266+
rijndael_set_key(
267+
&cfs_state->aes_context, /* context */
268+
(u4byte*)&aes_key, /* key */
269+
sizeof(aes_key) * 8 /* key size in bits */,
270+
1 /* for CTR mode we need only encryption */
271+
);
272+
}
273+
274+
/*
275+
* For a file name like 'path/to/16384/16401[.123]' return part1 = 16384, part2 = 16401 and part3 = 123.
276+
* Returns 0 on success and negative value on error.
277+
*/
278+
static int extract_fname_parts(const char* fname, uint32* part1, uint32* part2, uint32* part3)
279+
{
280+
int idx = strlen(fname);
281+
if(idx == 0)
282+
return -1;
283+
idx--;
284+
285+
while(idx >= 0 && isdigit(fname[idx]))
286+
idx--;
287+
288+
if(idx == 0)
289+
return -2;
290+
291+
if(fname[idx] != '.')
292+
{
293+
*part3 = 0;
294+
goto assign_part2;
295+
}
296+
297+
*part3 = atoi(&fname[idx+1]);
298+
299+
idx--;
300+
while(idx >= 0 && isdigit(fname[idx]))
301+
idx--;
302+
303+
if(idx == 0)
304+
return -3;
305+
306+
assign_part2:
307+
*part2 = atoi(&fname[idx+1]);
308+
309+
idx--;
310+
while(idx >= 0 && isdigit(fname[idx]))
311+
idx--;
312+
313+
if(idx == 0)
314+
return -4;
315+
316+
*part1 = atoi(&fname[idx+1]);
317+
return 0;
318+
}
319+
320+
/* Encryption and decryption using AES in CTR mode */
321+
static void cfs_aes_crypt_block(const char* fname, void* block, uint32 offs, uint32 size)
322+
{
323+
/*
324+
#define AES_DEBUG 1
325+
*/
326+
uint32 aes_in[4]; /* 16 bytes, 128 bits */
327+
uint32 aes_out[4];
328+
uint8* plaintext = (uint8*)block;
329+
uint8* gamma = (uint8*)&aes_out;
330+
uint32 i, fname_part1, fname_part2, fname_part3;
331+
332+
if(extract_fname_parts(fname, &fname_part1, &fname_part2, &fname_part3) < 0)
333+
fname_part1 = fname_part2 = fname_part3 = 0;
334+
335+
#ifdef AES_DEBUG
336+
elog(LOG, "cfs_aes_crypt_block, fname = %s, part1 = %d, part2 = %d, part3 = %d, offs = %d, size = %d",
337+
fname, fname_part1, fname_part2, fname_part3, offs, size);
338+
#endif
339+
340+
aes_in[0] = fname_part1;
341+
aes_in[1] = fname_part2;
342+
aes_in[2] = fname_part3;
343+
aes_in[3] = offs & 0xFFFFFFF0;
344+
rijndael_encrypt(&cfs_state->aes_context, (u4byte*)&aes_in, (u4byte*)&aes_out);
345+
346+
#ifdef AES_DEBUG
347+
elog(LOG, "cfs_aes_crypt_block, in = %08X %08X %08X %08X, out = %08X %08X %08X %08X",
348+
aes_in[0], aes_in[1], aes_in[2], aes_in[3],
349+
aes_out[0], aes_out[1], aes_out[2], aes_out[3]);
350+
#endif
351+
352+
for(i = 0; i < size; i++)
353+
{
354+
plaintext[i] ^= gamma[offs & 0xF];
355+
offs++;
356+
if((offs & 0xF) == 0)
357+
{
358+
/* Prepare next gamma part */
359+
aes_in[3] = offs;
360+
rijndael_encrypt(&cfs_state->aes_context, (u4byte*)&aes_in, (u4byte*)&aes_out);
361+
362+
#ifdef AES_DEBUG
363+
elog(LOG, "cfs_aes_crypt_block, in = %08X %08X %08X %08X, out = %08X %08X %08X %08X",
364+
aes_in[0], aes_in[1], aes_in[2], aes_in[3],
365+
aes_out[0], aes_out[1], aes_out[2], aes_out[3]);
366+
#endif
367+
}
368+
}
325369
}
326370

327-
void cfs_encrypt(void* block, uint32 offs, uint32 size)
371+
void cfs_encrypt(const char* fname, void* block, uint32 offs, uint32 size)
328372
{
329373
if (cfs_encryption)
330-
cfs_rc4_encrypt_block(block, offs, size);
374+
{
375+
cfs_aes_crypt_block(fname, block, offs, size);
376+
}
331377
}
332378

333-
void cfs_decrypt(void* block, uint32 offs, uint32 size)
379+
void cfs_decrypt(const char* fname, void* block, uint32 offs, uint32 size)
334380
{
335381
if (cfs_encryption)
336-
cfs_rc4_encrypt_block(block, offs, size);
382+
{
383+
cfs_aes_crypt_block(fname, block, offs, size);
384+
}
337385
}
338386

339387
/* ----------------------------------------------------------------
@@ -351,7 +399,7 @@ void cfs_initialize()
351399
cfs_state->max_iterations = 0;
352400

353401
if (cfs_encryption)
354-
cfs_encrypt_init();
402+
cfs_crypto_init();
355403

356404
elog(LOG, "Start CFS version %s compression algorithm %s encryption %s",
357405
CFS_VERSION, cfs_algorithm(), cfs_encryption ? "enabled" : "disabled");
@@ -827,7 +875,7 @@ static bool cfs_gc_file(char* map_path)
827875
Assert(res == (off_t)CFS_INODE_OFFS(inode));
828876
rc = cfs_read_file(fd, block, size);
829877
Assert(rc);
830-
cfs_decrypt(block, (off_t)i*BLCKSZ, size);
878+
cfs_decrypt(file_bck_path, block, (off_t)i*BLCKSZ, size);
831879
res = cfs_decompress(decomressedBlock, BLCKSZ, block, size);
832880

833881
if (res != BLCKSZ)

src/backend/storage/file/fd.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,7 +1760,7 @@ FileRead(File file, char *buffer, int amount)
17601760
}
17611761
} while (size != 0);
17621762

1763-
cfs_decrypt(compressedBuffer, VfdCache[file].seekPos, amount);
1763+
cfs_decrypt(VfdCache[file].fileName, compressedBuffer, VfdCache[file].seekPos, amount);
17641764

17651765
returnCode = cfs_decompress(buffer, BLCKSZ, compressedBuffer, amount);
17661766
if (returnCode != BLCKSZ)
@@ -1786,9 +1786,10 @@ FileRead(File file, char *buffer, int amount)
17861786
returnCode = read(VfdCache[file].fd, buffer, amount);
17871787
if (returnCode >= 0)
17881788
{
1789-
if (VfdCache[file].fileFlags & PG_COMPRESSION)
1790-
cfs_decrypt(buffer, VfdCache[file].seekPos, amount);
1791-
1789+
if (VfdCache[file].fileFlags & PG_COMPRESSION)
1790+
{
1791+
cfs_decrypt(VfdCache[file].fileName, buffer, VfdCache[file].seekPos, amount);
1792+
}
17921793
VfdCache[file].seekPos += returnCode;
17931794
}
17941795
else
@@ -1901,16 +1902,17 @@ FileWrite(File file, char *buffer, int amount)
19011902
inode = CFS_INODE(compressedSize, pos);
19021903
buffer = compressedBuffer;
19031904
amount = compressedSize;
1905+
19041906
/* cfs_encrypt will check if encryption is actually needed */
1905-
cfs_encrypt(buffer, VfdCache[file].seekPos, amount);
1907+
cfs_encrypt(VfdCache[file].fileName, buffer, VfdCache[file].seekPos, amount);
19061908
}
19071909
else
19081910
{
19091911
if (cfs_encryption) /* we need to use buffer to perform encryption, so check if it is required */
19101912
{
19111913
memcpy(compressedBuffer, buffer, BLCKSZ);
19121914
buffer = compressedBuffer;
1913-
cfs_encrypt(buffer, VfdCache[file].seekPos, amount);
1915+
cfs_encrypt(VfdCache[file].fileName, buffer, VfdCache[file].seekPos, amount);
19141916
}
19151917

19161918
if (CFS_INODE_SIZE(inode) != BLCKSZ)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy