Today we are excited to release oramfs, a simple, flexible, Free Software ORAM implementation for Linux written in Rust. It is designed to support different ORAM schemes and encryption ciphers. It is storage- and cloud provider agnostic and supports any UNIX filesystem without requiring specific plugins or server-side support.
When looking at privacy of storage solutions, encryption alone is not sufficient to prevent access pattern leakage. Unlike traditional solutions such as LUKS or Bitlocker, an ORAM scheme prevents an attacker from knowing whether read or write operations are performed and which parts of the filesystem are accessed. This level of privacy is achieved by making extra access requests than necessary, shuffling the blocks composing the storage layer, and writing and re-encrypting data back and forth every time, even when just a read operation is performed. This obviously comes with a loss of performance, but brings additional security compared to other solutions.
Our solution: oramfs
With oramfs users can enjoy total privacy while storing their files on untrusted local or remote storage, such as a public cloud. Our solution is resizable, so there is no need to re-initialize a larger ORAM when space becomes a problem. With oramfs, a whole filesystem is encrypted and read/write access patterns are hidden from the remote server. Our initial release supports a simple implementation of Path ORAM, one of the first modern, tree-based ORAM schemes, but the design supports arbitrary schemes and we plan of releasing more optimized ones soon.
To setup the ORAM, two inputs are required: a public directory and a private directory.
The public directory can be any locally mounted directory, including remote volumes mounted as a local directory. This could be a remote FTP directory, or a remote cloud storage mounted locally. Just mount the remote storage (or use a local storage if you want) and you’re good to go. For example, Rclone supports mounting a variety of cloud storage providers as local directories.
The private directory is the local mount point for a virtual storage that is presented to the user after entering the right secret passphrase, and is used to access files stored in the ORAM. Any operation performed on the private directory has an impact on the public directory. And if that public directory is a mounted remote storage, then it is safely and transparently synchronized to the remote server whenever an operation is performed on the private directory.
In order to be fully storage agnostic, oramfs is file-based: the ORAM structure is split into blocks (or nodes of blocks) and every block or node is saved to the public directory as a separate file. FUSE is then used to recombine these files into a single virtual loop device that is eventually accessed through the ORAM scheme itself. All this is completely transparent for the user.
Let’s go through an example where we setup an ORAM that transparently synchronizes data to a remote FTP server. This would also work with any other remote storage supported by Rclone, such as SSH, Google Drive or S3.
We assume that a remote directory has already been mounted at the local mount point
public/ and also an empty directory
private/ has been created.
We initialize a new ORAM called
myoram, by answering the interactive questions. This will automatically format the underlying filesystem with EXT4 but this option can be overridden if wished.
$ oramfs add myoram public/ private/ Please enter desired ORAM total size in bytes, or press enter to use default [default: 16000000 (16 MB)]: Adjusting ORAM size to closest valid value: 16711680 bytes Please enter path to client data directory to use, or press enter to use default [default: /home/foobar/.config/oramfs/myoram]: Please enter path to mountpoint directory to use, or press enter to use default [default: /tmp/oramfs_myoram]: Successfully added ORAM myoram.
Finally, we mount the ORAM (will prompt the user for the password) and write a file to it:
$ oramfs mount myoram It looks like this ORAM is mounting for the first time. Initializing it first... Please enter an encryption passphrase to secure your ORAM: **** Please type it a second time to confirm: **** Starting ORAM... Running as a daemon... Mounting filesystem to private directory... Formatting EXT4 filesystem... mke2fs 1.46.2 (28-Feb-2021) Creating filesystem with 16320 1k blocks and 4080 inodes Filesystem UUID: 7de4f86e-adb8-4587-bf68-814267ef5ab6 Superblock backups stored on blocks: 8193 Allocating group tables: done Writing inode tables: done Creating journal (1024 blocks): done Writing superblocks and filesystem accounting information: done Mounting directory... [sudo] password for foobar: Setting private directory owner... [sudo] password for foobar: Setup complete! ORAM filesystem mounted to private directory at: /home/foobar/git/oramfs/private $ echo hello world > private/somefile
When finished, we can unmount it:
$ oramfs umount myoram
That’s it! Files written/read to/from the private directory are encrypted and access patterns are hidden from the FTP server.
Head over to Github to get started with oramfs.
By the way, we will be presenting oramfs on Wednesday July 7th at 4:10pm CEST at Pass the SALT.