Skip to content

codeamt/encrypted-vfs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

encrypted-vfs

encrypted-vfs is an experimental Rust crate that explores page-level encryption for a file-backed virtual storage layer, inspired by how SQLite’s VFS operates.

The current implementation focuses on:

  • AES‑GCM–based encryption for file contents.
  • Page-level encryption with a fixed page size.
  • A simple Rust API for opening an encrypted file and reading/writing pages.

This is work in progress, not a production-ready library. It is intended as an educational/portfolio project to demonstrate systems-level Rust, encryption, and storage abstractions.


Features (current)

  • AES‑256‑GCM encryption

    • Uses aes-gcm with a 32-byte key.
    • Authenticated encryption (ciphertext includes an authentication tag).
  • Page-level layout

    • PAGE_SIZE is fixed at 4096 bytes.
    • Each page is encrypted with its own per-page nonce derived from:
      • The encryption key.
      • The page number.
    • On disk, each page is stored as PAGE_SIZE + TAG_SIZE bytes.
  • Deterministic nonces

    • Per-file nonce is derived from (key, path) for the basic write_at/read_at API.
    • Per-page nonces are derived from (key, page_number) for write_page/read_page.
  • Minimal, focused API

    • EncryptedFile::open to create/open an encrypted file.
    • write_page / read_page for page-level I/O.
    • write_at / read_at as a simple, non-page-aware encrypted I/O layer.

Status

This crate currently provides:

  • A compiling demo showing page-level encrypted I/O.
  • A clean separation between:
    • Core encrypted file abstraction (EncryptedFile).
    • Demo code (in src/main.rs).

There is no full SQLite VFS integration yet. The code is structured so that a future VFS adapter can be built on top of the existing page-level API.


Usage

Add to your project (local crate example)

If you’re using this repository directly:

[dependencies]
encrypted-vfs = { path = "./encrypted-vfs" }

Opening an encrypted file

use encrypted_vfs::EncryptedFile;
use std::{path::Path, sync::Arc};

fn main() -> std::io::Result<()> {
    // 32-byte AES-256 key.
    // In real applications, derive this from a passphrase or key management system.
    let key = [0u8; 32];
    let path = Path::new("encrypted_demo.bin");

    let mut file = EncryptedFile::open(path, Arc::new(key))?;

    // Basic byte-level write/read (non-page-aware)
    let data = b"hello encrypted world";
    file.write_at(0, data)?;

    let mut buf = vec![0u8; data.len()];
    file.read_at(0, &mut buf)?;

    assert_eq!(&buf, data);

    Ok(())
}

Page-level API

The primary abstraction is page-level I/O.

use encrypted_vfs::{EncryptedFile, PAGE_SIZE};
use std::{path::Path, sync::Arc};

fn main() -> std::io::Result<()> {
    let key = [0u8; 32];
    let path = Path::new("encrypted_pages.bin");

    let mut file = EncryptedFile::open(path, Arc::new(key))?;

    // Prepare a single page with some application data at the start
    let mut page = [0u8; PAGE_SIZE];
    let msg = b"hello encrypted page";
    page[..msg.len()].copy_from_slice(msg);

    // Page-level write and read
    file.write_page(0, &page)?;

    let mut read_back = [0u8; PAGE_SIZE];
    file.read_page(0, &mut read_back)?;

    assert_eq!(&read_back[..msg.len()], msg);

    Ok(())
}

Under the hood:

  • write_page(page_no, data):

    • Derives a per-page nonce from (key, page_no).
    • Encrypts data with AES‑GCM.
    • Writes PAGE_SIZE + TAG_SIZE bytes to the underlying file at the calculated offset.
  • read_page(page_no, buf):

    • Reads PAGE_SIZE + TAG_SIZE bytes from the underlying file.
    • Decrypts using the same per-page nonce.
    • Copies the resulting plaintext into buf.

Security Notes

This crate is not production-ready. Some important caveats:

  • Key management is intentionally simplified:
    • Keys are currently passed as raw [u8; 32].
    • There is no KDF (e.g., PBKDF2, scrypt, Argon2) or integration with AWS KMS, HashiCorp Vault, etc.
  • Nonce derivation is deterministic:
    • Useful for page-based schemes, but must be carefully audited for uniqueness and security properties in real deployments.
  • Threat model and side channels:
    • The implementation does not attempt to handle side-channel attacks, secure key erasure, or multi-tenant isolation.

Treat this as a learning tool and prototype, not as a drop-in encryption layer for sensitive data.


Building and Running

From the repository root:

cargo build
cargo run

The demo (src/main.rs) will:

  1. Open an encrypted file.
  2. Write a page at page 0.
  3. Read that page back.
  4. Assert that the plaintext matches.

License

This project is licensed under the Apache-2.0 License. See LICENSE for details.

About

An example encrypted virtual file system backed by mmap for efficient I/O.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages