# EncFS encrypts files one by one, and the Rust rewrite is still beta

> The Rust rewrite of a FUSE filesystem first released in 2003 still reads 1.9.x volumes and adds Argon2id with authenticated blocks, yet it calls itself beta, leaves filenames on the legacy modes, and its own text points new setups at GoCryptFS instead.

**vgough/encfs** — EncFS: an Encrypted Filesystem for FUSE.

- Repository: https://github.com/vgough/encfs
- Website: https://vgough.github.io/encfs/
- Stars: 2,160 · Forks: 282
- Language: Rust
- License: LGPL-3.0
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/vgough-encfs

## Encrypted files one by one, not a whole-disk image

EncFS presents a directory of encrypted files as an ordinary directory of plaintext, so an application opens a document and never learns that the bytes on disk differ. There is no container image and no fixed-size volume to provision. Each file is encrypted on its own, and a filesystem running in userspace on top of FUSE translates every request aimed at the virtual tree into the equivalent encrypted operation on the raw tree underneath. That granularity is why adding one file to an existing volume does not rewrite everything around it.

The audience today is narrower than a 2003 launch promised. The project began as a CFS replacement written for its author when the available Linux kernel modules kept breaking on every kernel upgrade, which makes it one of the earlier FUSE filesystems. More than two decades later the project's own text points new setups at GoCryptFS, or at full-disk encryption when possible. So the defensible adoption case is a volume that already exists and has to stay readable, not a fresh decision about how to protect a disk.

## Blocks, 16-byte tags, and a 12-byte per-file header

Under the current default, file contents are split into 4080-byte blocks out of a 4096-byte unit, and every block carries a 16-byte AES-256-GCM-SIV authentication tag. That tag is the whole integrity story for the data, and it replaces the older arrangement of a separate cipher plus an optional per-block MAC of at most 8 bytes, where integrity was optional and truncated to 64 bits. Here every block is authenticated, and the mode is described as misuse-resistant.

Headers sit in front of the payload. With per-file IVs enabled, a new filesystem writes a 96-bit IV into a 12-byte file header, where the legacy format stored a 64-bit IV in an 8-byte header, and `encfsctl new --legacy-file-iv` opts back into the shorter form for interoperation with older tooling. Above the file layer, the volume key is wrapped with a 32-byte key derived by Argon2id. Names are encrypted either in stream mode using CFB across multiple passes or in block mode with an IV taken from an HMAC of the name, and the long-form design write-up sits in docs/DESIGN.md.

## Argon2id, 64 MiB, and a config file that detects tampering

A fresh volume uses the V7 config, `.encfs7`, which is authenticated and carries a `config_hash`, so an edit to the config file does not pass unnoticed. Legacy volumes use `.encfs6.xml`, `.encfs5` or `.encfs4`, all unsigned, where tampering is undetected. That single difference matters more than it first appears: on an old volume, a config pointing somewhere else is a file edit, while on a V7 volume the config has a checksum over it.

Password stretching changes with the format. Argon2id is the default at 64 MiB of memory, 3 iterations and 4 lanes, chosen to be memory-hard and resistant to GPU and ASIC attack, where the 1.9.x era used PBKDF2-HMAC-SHA1 with a configurable iteration count. The dependency list keeps argon2, pbkdf2, blowfish, cbc, aes-gcm-siv and zeroize in one manifest, which is the practical fingerprint of a program that must keep reading volumes written by an earlier design while writing new ones.

## Upgrading changes the key derivation, not the ciphertext

An existing legacy volume can be moved to the new config format and the new password hashing without recreating anything:

```bash
encfsctl passwd --upgrade <rootdir>
```

You are prompted for the current password and then a new one, the volume must not be mounted while it runs, and the tool writes a new `.encfs7` file while leaving the old config in place for you to delete after verification.

Read that last point carefully, because it is the sharpest trap here. The upgrade switches the config format and the key derivation function, and nothing else: the file data encryption mode of an existing filesystem is not changed by it. A volume you upgraded still holds CBC ciphertext with the old short MAC per block. Getting existing data onto AES-GCM-SIV means creating a new filesystem and copying the data across, an offline operation with a full copy of the volume sitting in between.

## Creating a V7 volume and mounting it in two steps

Everything begins in the directory that will hold the encrypted files, where `encfsctl new` writes a V7 config and prompts for a password:

```bash
mkdir -p ~/encrypted
encfsctl new ~/encrypted
```

Mounting is a separate step, with the encrypted root as the first argument and the mount point where plaintext appears as the second:

```bash
mkdir -p ~/mount
encfs ~/encrypted ~/mount
```

From there, reading and writing under the mount point lands the bytes encrypted in the root. Detaching takes one of two commands depending on the platform:

```bash
fusermount -u ~/mount   # Linux
# or: umount ~/mount    # macOS / FreeBSD
```

For scripted or non-interactive setups the same two tools take the password from somewhere else: `encfsctl new --stdinpass` or `--extpass <program>` when creating the config, and `encfs -S` or `--extpass` when mounting.

## encfsr reverses the direction and demands its own config

Most people meet reverse mode only when they want an encrypted copy of local data sitting somewhere they do not trust. In `encfsr` the arrangement inverts: plaintext files live on disk in a source directory, and the binary mounts a read-only view of that directory showing the encrypted form. That is what makes an encrypted backup or sync into cloud storage possible without storing plaintext there. Ordinary `encfs` runs the other way, taking an encrypted directory on disk and exposing a read/write plaintext view at the mount point.

The requirements are not negotiable. Reverse mode needs a V7 config such as `.encfs7`, and older config formats are not supported. It also needs per-file IV headers switched off, which means the config has to be created with `encfsctl new --no-unique-iv` rather than with the default settings. The reverse workflow and the per-file IV header are therefore mutually exclusive choices on the same volume, and the mount is read-only by default.

## Filenames still ride the old stream and block modes

Here is the part a fresh V7 volume does not fix. The comparison table draws a line under data encryption and leaves filenames alone, marking them unchanged, still using the legacy stream and block modes for compatibility, with the IV still derived from an HMAC of the name. A brand-new volume with Argon2id, AES-GCM-SIV blocks and an authenticated config therefore still hides its names with the pre-V7 scheme, and the project concedes in the same place that protocol-level weaknesses of the legacy design remain for compatibility.

This also survives the full migration route. Since reaching AES-GCM-SIV on existing data requires creating a new filesystem and copying the data into it, the copied names arrive under the same name encryption as before, so even a complete migration does not produce a wholly modern volume. The interoperability switch cuts both ways as well: `encfsctl new --legacy-file-iv` buys an 8-byte header for older tooling at the cost of the 96-bit IV the new default uses.

## Building pulls protoc and a git dependency, not just crates

The rewrite moved the build into Cargo, and the manifest pins edition 2024 while building two binaries, `encfsctl` from `src/encfsctl.rs` and `encfsr` from `src/encfsr.rs`, plus a filesystem benchmark with the harness turned off. The workspace excludes the `fuzz` directory. Build dependencies are protobuf-first, pairing prost-build with protoc-bin-vendored so a protocol compiler is vendored rather than assumed present. One dependency does not come from a registry at all: typed-fuse is pinned to a git URL under the author's account, so a source build depends on that repository being reachable.

The version story rewards a close reading. `Cargo.toml` says `2.0.0-beta.6`, the newest tagged build on record is v2.0.0-beta1 dated 2026-06-16, and the last push was on 2026-08-13, so beta 6 is something you build from a branch rather than fetch from a tag. Internationalisation is thinner than the word support conveys: locales cover en, fr and de, and the project's own status list leaves translations beyond the auto-generated FR and DE strings unchecked.

The code is published under LGPL-3.0 with the full text in `COPYING.LGPL`, so anyone shipping it inside another product has to work out how the copyleft terms apply to that binary instead of assuming permissive terms.

## Conclusion

Adopt EncFS if you already own a 1.9.x volume that has to keep opening; build from the branch, not from a tag, and keep a separate copy of the data the way the project itself advises. Do not adopt it to protect a new disk: the author points new setups at GoCryptFS or full-disk encryption, and a V7 volume still encrypts filenames with the pre-V7 stream and block modes. Before anything else, copy the volume and try `encfsctl passwd --upgrade` on that copy, then work out whether you actually need AES-GCM-SIV blocks, since the upgrade does not hand them to you.

## FAQ

### Can EncFS 2.0 open a filesystem created by EncFS 1.9.x?

Yes. This implementation reads and writes legacy filesystems created with EncFS 1.9.x in config formats V4, V5 and V6, while newly created filesystems use the V7 config.

### Does `encfsctl passwd --upgrade` change how my existing files are encrypted?

No. It converts an existing filesystem to the V7 config and the Argon2id key derivation function, and the file data encryption mode of an existing filesystem is not changed by it. Full migration to AES-GCM-SIV block encryption requires creating a new filesystem and copying the data.

### Can encfsr mount an old EncFS 1.9 config?

No. Reverse mode requires a V7 config such as `.encfs7`, and older configs are not supported. It also expects the config to be created without per-file IV headers.

### How do I mount EncFS without typing a password on the command line?

For scripted or non-interactive setup the project documents `encfsctl new --stdinpass` or `--extpass <program>` for creating a config, and `encfs -S` or `--extpass` for mounting.

### Is the Rust rewrite of EncFS finished?

Read operations, basic write operations and truncate with holes are all marked done, along with reverse encryption mode and an Argon2id key derivation function. Translations beyond the auto-generated FR and DE strings are not done, and the status text still calls the implementation a beta for which a separate backup is stated practice.

## Sources

- [License: LGPL-3.0](https://github.com/vgough/encfs/blob/master/LICENSE)
- [Project website](https://vgough.github.io/encfs/)
- [README](https://github.com/vgough/encfs/blob/master/README.md)
- [Releases](https://github.com/vgough/encfs/releases)
- [vgough/encfs on GitHub](https://github.com/vgough/encfs)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vgough-encfs
