Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
radumarias committed May 4, 2024
2 parents d6ae144 + e228082 commit d9c2ef4
Showing 1 changed file with 44 additions and 4 deletions.
48 changes: 44 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

An encrypted file system that mounts with FUSE on Linux. It can be used to create encrypted directories.

It can then safely backup the encrypted folder on an untrusted server without worrying about the data being exposed.\
You can then safely backup the encrypted folder on an untrusted server without worrying about the data being exposed.\
You can also store it in any cloud storage like Google Drive, Dropbox, etc. and have it synced across multiple devices.

\
Expand All @@ -11,6 +11,31 @@ You can also store it in any cloud storage like Google Drive, Dropbox, etc. and
[![docs.rs](https://img.shields.io/docsrs/rencfs?label=docs.rs)](https://docs.rs/rencfs/)
[![test](https://github.com/radumarias/rencfs/actions/workflows/test.yml/badge.svg)](https://github.com/radumarias/rencfs/actions/workflows/test.yml)


# Functionality

I keeps all encrypted data and master encryption key in a dedicated directory with files structured on inodes (with meta info), files for binary content and directories with files/directories entries. All data, metadata and also filenames are encrypted. For new files it generates inode number randomly in `u64` space so it reduces the chance of conflicts when used offline and synced later.

Password is collected from CLI and can be saved in OS keyring.
Encryption key is also encrypted with another key derived from the password. This gives the ability to change the password without re-encrypting all data, we just re-encrypt the key.

# Implementation

- Safety on process kill (or crash): all writes to encrypted content is done in a tmp file and them using `mv` to move to destination. the `mv` operation is atomic as it's using `rename()` which is atomic as per specs, see [here](https://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html) `That specification requires that the action of the function be atomic.`
- Phantom reads: reading older content from a file, this is not possible. While writing, data is kept in a buffer and tmp file and on flushing that buffer we write the new content to the file (as per above the tmp file is moved into place with `mv`). After that we reset all opened readers so any reads after that will pickup the new content.
- What kind of metadata does it leak: close to none. The filename, actual file size and other file attrs (times, permissions, other flags) are kept encrypted. What it could possible leak is the following
- If a directory has children we keep those children in a directory with name as inode numiber with encrypted names of children as files in it. So we could see how many children a directory has, but we can't identify that actual directory name, we can just see it's inode number (internal representation like an id for each file) and we cannot see the actual filenames or directory or children.
- Each file content is saved in a separate file so we could see the size of the encrypted content, but not the actual filesize.

# Stack

- it's fully async built upon [tokio](https://crates.io/crates/tokio) and [fuse3](https://crates.io/crates/fuse3)
- [ring](https://crates.io/crates/ring) for encryption and [argon2](https://crates.io/crates/argon2) for key derivation function (creating key used to encrypt master encryption key from password)
- [rand_chacha](https://crates.io/crates/rand_chacha) for random generators
- [secrecy](https://crates.io/crates/secrecy) for keeping pass and encryption keys safe in memory and zeroing them when not used. It keeps encryption keys in memory only while being used and when not active it will release and zeroing them from memory
- password can be saved in OS keyring using [keyring](https://crates.io/crates/keyring)
- [tracing](https://crates.io/crates/tracing) for logs

# Usage

You can use it as a command line tool to mount an encrypted file system, or directly using the library to build your own binary (for library, you can follow the [documentation](https://docs.rs/rencfs/latest/rencfs/)).
Expand All @@ -32,8 +57,7 @@ sudo apt-get update && sudo apt-get -y install fuse3

You can install the encrypted file system binary using the following command
```bash
yay -Syu
yay -S rencfs
yay -Syu && yay -S rencfs
```

### Install with cargo
Expand Down Expand Up @@ -175,4 +199,20 @@ cargo build --release
```bash
cargo run -- --mount-point MOUNT_POINT --data-dir DATA_DIR
```
```
# Future
- Plan is to implement it also on macOS and Windows
- A systemd service is being worked on [rencfs-daemon](https://github.com/radumarias/rencfs-daemon)
- A GUI is on the way [rencfs_desktop](https://github.com/radumarias/rencfs_desktop)
- Mobile apps for Android and iOS are on the way
# Contribution
Feel free to fork it, change and use it in any way that you want. If you build something interesting and feel like sharing pull requests are always apporeciated.
# Considerations
It doesn't have any independent review from experts, but if the project gains any traction would think about doing that.
Please note, this project doesn't try to reinvent the wheel or be better than already proven implementations. It started as a learning project of Rust programming language and I feel like keep building more on it. It's a fairly simple and standard implementation that tries to respect all security standards, use safe libs and ciphers in the implementation so that it can be extended from this. Indeed it doesn't have the maturity yet to "fight" other well known implementations but it can be a project from which others can learn or build upon or why not for some to actually use it keeping in mind all the above.

0 comments on commit d9c2ef4

Please sign in to comment.