Skip to content

Latest commit

 

History

History
349 lines (229 loc) · 9.03 KB

File metadata and controls

349 lines (229 loc) · 9.03 KB

Objective

This assignment aims to deepen understanding of file system operations and encryption mechanisms by building a simple in-memory file system using the FUSE (Filesystem in Userspace) framework, followed by integrating AES-256 encryption to ensure data security.

Resources:

  1. Less Simple, Yet Stupid Filesystem (Using FUSE)
  2. In Storage Filesystem (ISFS) Using FUSE

Assignment: Link

Part 1

Setting Up FUSE environment

sudo apt-get install fuse libfuse-dev

image

image

Part 2

Building a Basic In-Memory File System with FUSE: Using the FUSE framework, create a simple in-memory file system. This file system should support basic operations such as:

  • Create, read, and write files.
  • Open and close files.
  • Create and remove directories.
  • List directory contents.

memfs

memfs/
├── Makefile           
├── main.c             # 主程式,包含Initlize 和 FUSE 的入口點
├── node.c             # 節點操作(如Create, LookUP)相關操作
├── node.h             # header file of node.c
├── encryption.c       # 與資料加密和解密相關操作
├── encryption.h       # header file of encryption.c`
├── operations.c       # FUSE 各種函數的實現(如: read, write, mkdir)
├── operations.h       # headre file of operations.c
└── memfs.h            # global header file,定義核心結構、global vaviable,root等


Makefile

CC = gcc
CFLAGS = `pkg-config fuse3 --cflags` -Wall -g
LDFLAGS = `pkg-config fuse3 --libs` -lssl -lcrypto

SOURCES = main.c node.c encryption.c operations.c
OBJECTS = $(SOURCES:.c=.o)
HEADERS = memfs.h node.h encryption.h operations.h

all: memfs

memfs: $(OBJECTS)
	$(CC) $(CFLAGS) -o memfs $(OBJECTS) $(LDFLAGS)

%.o: %.c $(HEADERS)
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f memfs $(OBJECTS)

Makefile 說明:
執行 make 時,會先找到 allall 依賴於 memfs,所以去執行memfsmemfs 依賴於 $(OBJECTS),所以實際上會先去檢查所有的.o檔是否存在,

  • 如果.o file 不在,就先把對應的.c檔編譯成.o file
  • 如果.o file 存在,就直接執行 memfs 的生成

pkg-config fuse3 --cflagspkg-config fuse3 --libs 表示 provide the compiler the proper arguments to include “fuse3” library.
-Wall 表示啟用所有常用的編譯器警告

編譯成功後會出現一個可執行檔 memfs

image

memfs 掛載到 /tmp/memfs

./memfs -f -d /tmp/memfs

-f : 表示讓process在foreground運作。主要目的是在terminal中看到程式的输出,類似於 dmesg (查看kernel 內的訊息)。

-d : Debug模式,可以用來查看更詳細的運作訊息,包含每個指令實際執行到的function、nodeid、pid、error message等等

結束後,在另一個terminal 中輸入:

cd /tmp/memfs

即可開始對file system進行各種操作。


創建新directory

mkdir testdir

在Foreground中會出現:
image

可以發現,mkdir 實際上會先去LOOKUP /testdir,得到 error: NO such file or directory,
接下來會真正執行MKDIR 產生 testdir 這個目錄


建立新檔案

touch testfile

在Foreground中會出現:

image

可以發現創立檔案的流程:

  • LOOKUP /testfile 得到 error: NO such file or directory
  • CREATE /testfile 在nodeid 為 1(root directory)下創建testfile
  • SETATTR 對testfile設定一些屬性(如: atimes, mtimes),
  • RELEASE 關閉testfile,得到success。

寫入檔案

echo "Hello" > testfile

在Foreground中會出現:

image

可以發現共寫入6個bytes,"Hello\n" 共6bytes。


讀取檔案

cat testfile

image

在Foreground中會出現:
image


列出directory內容

ls -l

image

在Foreground中會出現:
image


delete file

rm testfile

在Foreground中會出現:
image


delete directory

rmdir testdir

在Foreground中會出現:
image

若 directory不存在會出現:
image

Part 3, 4, 5

  • Integrating AES-256 Encryption
  • Encrypted with a different key
  • Ensure all file operations (read, write, etc.) handle encrypted data correctly
  • Testing and Validation

AES-256 Encryption如何運作?

  • EVP_CIPHER_CTX_new() : returns a pointer to a newly created EVP_CIPHER_CTX for success and NULL for failure.
  • EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)
  • EVP_EncryptUpdate(ctx, *ciphertext, &len, plaintext, plaintext_len)
  • EVP_EncryptFinal_ex(...)
  • EVP_CIPHER_CTX_free(ctx)

Implement a mechanism for managing encryption keys, ensuring that each file can be encrypted with a different key. Design the system so that the encryption key must be supplied to open a file.

寫入時加密: 可以在mount 上資料夾之前,先設幾個斷點,到時候方便檢查是否確實加密

  • memfs mount 上 /tmp/memfs
gdb --args ./memfs -f -d /tmp/memfs
  • gdb 寫入斷點:
break memfs.c:545    // before ending memfs_write()
break memfs.c:456    // before ending memfs_read()
  • gdb 執行程式:
run

在另一邊的terminal 打入:

echo "123456789123456789" > testfile

可以看到自動生成的AES key(32-bits)及IV(16-bits),
image

停在中斷點後,在 gdb中打入指令,查看memory中的加密資料內容:

x/32bx encrypted_data

image

和我們直接印出資料內容: image 得到一樣的內容

可以看到這串資料使用了AES-256加密演算法,且加密資料 encrypted_data 的內容與原始寫入資料: 123456789123456789\n 沒有任何關係

讀取時解密: 若要查看解密資料是否正確

  • 先打:
cat testfile
  • 停在中斷點後,在 gdb 打入指令,查看memory中的解密資料內容:
x/32bx decrypted_data

image

這次可以看到,解密的資料為正確資料,因為根據ASCII-Table:

  • 10x31
  • 20x32
  • ...
  • 90x39
  • \n0x0a

可以得到結論,寫入的資料經過AES-256加密過後,在未解密的情況下讀取,確實會是一串和原始資料不相關的資料,證實有正確實現加密檔案的動作,
而解密過後的資料decrypted_data 資料為: 123456789123456789\n,確實為寫入資料,因此驗證AES-256在寫入時有正確加密,不夠的位元也有做padding,而在讀取資料時才做解密的動作,且解密資料為寫入資料正確無誤。

測試多個檔案生成不同的key

touch testfile_2

image

touch testfile_3

image

Part 6

Testing and Validation

測試: 若給予錯誤的AES key,是否能解密資料

更改memfs_read() 為:

// Use wrong key to decrypted data
int memfs_read(const char *path, char *buf, size_t size, off_t offset,
               struct fuse_file_info *fi) {
    
    // ...
    
    // 定義錯誤的 AES 金鑰(與正確金鑰不同)
    unsigned char wrong_key[AES_KEY_SIZE] = "wrongkey12345678901234567890abcd";

    // 使用錯誤的金鑰進行解密
    int decrypted_size = decrypt_data((unsigned char *)node->data, node->size,
                                      wrong_key, node->aes_iv, &decrypted_data);

    
    // ...

這個memfs_read()內預設了錯誤的AES key,在讀取時會使用到錯誤的key,
並且return -EIO,所以在command line 會看到 Input/output error

執行結果:

image

image

可以看到,使用錯誤的AES key讀取已經加密的資料,無法讀取

卸载file system

fusermount -u /tmp/memfs    

Problems