gocryptfs Documentation

Encrypted overlay filesystem written in Go

4,635 stars Go Go 13 files ยท ~23,449 tokens #encryption#filesystem#fuse#gcm#golang
RAW Doc

Technical Documentation: rfjakob/gocryptfs

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (`README.md`)






An encrypted overlay filesystem written in Go.
Official website: https://nuetzlich.net/gocryptfs (markdown source).

[!WARNING]
The website "gocryptfs.com" is not affiliated with the gocryptfs project!

gocryptfs is built on top the excellent
go-fuse FUSE library.
This project was inspired by EncFS and strives to fix its security
issues while providing good performance
(benchmarks).
For details on the security of gocryptfs see the
Security design document.

All tags from v0.4 onward are signed by the gocryptfs signing key.
Please check Signed Releases
for details.

Current Status

gocryptfs has reached version 1.0 on July 17, 2016. It has gone through
hours and hours of stress (fsstress, extractloop.bash) and correctness
testing (xfstests). It is now considered ready for general consumption.

The old principle still applies: Important data should have a backup.
Also, keep a copy of your master key (printed at init) in a safe place.
This allows you to access the data even if the gocryptfs.conf config
file is damaged or you lose the password.

The security of gocryptfs has been audited in March 3, 2017. The audit
is available here (defuse.ca).

Platforms

Linux is gocryptfs' native platform.

Beta-quality macOS support is available, which means most things work
fine but you may hit an occasional problem. Check out
ticket #15 for the history
of macOS support but please create a new ticket if you hit a problem.

For Windows, an independent C++ reimplementation can be found here:
cppcryptfs

Standalone tools:

gocryptfs-inspect
is Python tool that can decrypt files & file names without
using FUSE.

gocryptfs-create-folder
is a Python tool can encrypt a directory without using FUSE.

Installation

Precompiled binaries that work on all x86_64 Linux systems are available
for download from the github releases page. The fuse package from your
distribution must be installed for mounting to work.

gocryptfs is also available as a package in most distributions. Examples:

  • Debian, Ubuntu: apt install gocryptfs
  • Arch: pacman -S gocryptfs
  • MacPorts: port install gocryptfs

See the Quickstart page for more info.

Testing

gocryptfs comes with is own test suite that is constantly expanded as features are
added. Run it using ./test.bash. It takes about 1 minute and requires FUSE
as it mounts several test filesystems.

The stress_tests directory contains stress tests that run indefinitely.

In addition, I have ported xfstests to FUSE, the result is the
fuse-xfstests project. gocryptfs
passes the "generic" tests with one exception, results: XFSTESTS.md

A lot of work has gone into this. The testing has found bugs in gocryptfs
as well as in the go-fuse library.

Compile

Install Go 1.13 or higher:

  • Debian/Ubuntu: apt install golang
  • Fedora: dnf install golang

Then, download the source code and compile:

text
$ git clone https://github.com/rfjakob/gocryptfs.git
$ cd gocryptfs
$ ./build-without-openssl.bash

This will compile a static binary that uses the Go stdlib crypto backend.

If you want to use the OpenSSL crypto backend (faster on
old CPUs lacking AES-NI), you have to install a few dependencies:

  • Debian/Ubuntu: apt install libssl-dev gcc pkg-config
  • Fedora: dnf install openssl-devel gcc pkg-config

Then, run:

text
$ ./build.bash

Use

text
$ mkdir cipher plain
$ ./gocryptfs -init cipher
$ ./gocryptfs cipher plain

See the Quickstart page for more info.

The MANPAGE.md describes all available command-line options.

Use: Reverse Mode

text
$ mkdir cipher plain
$ ./gocryptfs -reverse -init plain
$ ./gocryptfs -reverse plain cipher

Graphical Interface

The SiriKali project supports
gocryptfs and runs on Linux and OSX.

cppcryptfs on Windows provides
its own GUI.

Stable CLI ABI

If you want to call gocryptfs from your app or script, see
CLI_ABI.md for the official stable
ABI. This ABI is regression-tested by the test suite.

Storage Overhead

  • Empty files take 0 bytes on disk
  • 18 byte file header for non-empty files (2 bytes version, 16 bytes random file id)
  • 32 bytes of storage overhead per 4kB block (16 byte nonce, 16 bytes auth tag)

file-format.md contains a more detailed description.

Performance

Since version 0.7.2, gocryptfs is as fast as EncFS in the default mode,
and significantly faster than EncFS' "paranoia" mode that provides
a security level comparable to gocryptfs.

On CPUs without AES-NI, gocryptfs uses OpenSSL through a thin wrapper called stupidgcm.
This provides a 4x speedup compared to Go's builtin AES-GCM
implementation. See CPU-Benchmarks
for details, or run gocryptfs -speed to see the encryption performance of your CPU.
Example for a CPU with AES-NI:

text
$ ./gocryptfs -speed
gocryptfs v2.2.0-beta1-5-g52b0444-dirty; go-fuse v2.1.1-0.20210825171523-3ab5d95a30ae; 2021-09-14 go1.17.1 linux/amd64
cpu: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz; with AES acceleration
AES-GCM-256-OpenSSL              862.79 MB/s
AES-GCM-256-Go                   997.71 MB/s    (selected in auto mode)
AES-SIV-512-Go                   159.58 MB/s
XChaCha20-Poly1305-OpenSSL   729.65 MB/s
XChaCha20-Poly1305-Go            843.97 MB/s    (selected in auto mode)

You can run ./benchmark.bash to run gocryptfs' canonical set of
benchmarks that include streaming write, extracting a linux kernel
tarball, recursively listing and finally deleting it. The output will
look like this:

text
$ ./benchmark.bash
Testing gocryptfs at /tmp/benchmark.bash.xFD: gocryptfs v2.0; go-fuse v2.1.1-0.20210508151621-62c5aa1919a7; 2021-06-06 go1.16.5 linux/amd64
WRITE: 262144000 bytes (262 MB, 250 MiB) copied, 0,698174 s, 375 MB/s
READ:  262144000 bytes (262 MB, 250 MiB) copied, 0,268916 s, 975 MB/s
UNTAR: 8,970
MD5:   4,846
LS:    1,851
RM:    2,367

Changelog

v2.6.1, 2025-08-10

  • Fix warnings cipherSize X: incomplete last block (Y bytes), padding to Z bytes
    (harmless but annoying, #951)
  • MacOS: Fix GUI apps reporting failure to save files #914
  • MacOS: Fix test-without-openssl.bash trying to build tests with openssl enabled
    (2ebd0d754b8ee4)

v2.6.0, 2025-07-14

v2.5.4, 2025-04-13

  • Drop GOAMD64=v2 from build.bash, there's user(s) still running GOAMD64=v1 CPUs
    (#908,
    commit)

v2.5.3, 2025-04-05

  • Fix go install failing with g: malformed file path "tests/fsck/malleable_base64/27AG8t-XZH7G9ou2OSD_z\ng": invalid char '\n'
    (c80558)
  • Fix panic when go-fuse is newer than specified in go.mod (#897)

v2.5.2, 2025-03-19

  • Use our own syscallcompat.Setreuid (and friends) wrappers
    (6b1ba584)
  • Upgrade golang.org/x/sys again
  • Provide arm64 binaries in releases in addition to amd64

v2.5.1, 2025-01-23

  • Downgrade golang.org/x/sys to unbreak unix.Setreuid and -allow_other
    (6d342f3,
    #893, #892)

v2.5.0, 2025-01-18

  • Important fixes for -reverse mode affecting the virtual gocryptfs.diriv and
    gocryptfs.longname.*.name files.
    The bug can cause file names to become
    undecryptable. To make sure that sync tools like rsync copy new, good copies,
    gocryptfs v2.5.0 and later advance ctime and mtime for these files by 10 seconds.
    • Fix -reverse mode sometimes (triggered by inode number reuse) returning stale
      data for gocryptfs.diriv (#802)
    • Fix -reverse mode hardlinking gocryptfs.longname.*.name files of hardlinked
      files together (#802)
  • Fix -reverse mode ignoring -force-owner (#809)
  • Add workaround for excessive file fragementation on btrfs (#811)
  • -ctlsock: automatically delete orphaned colliding socket file (#776)
  • MacOS: Fix XTIMES panic on startup (#823)
    • Fixed by updating the go-fuse library to v2.5.0
  • MacOS: merge kernel options before passing them on (#854, #557)
  • Add -fido2-assert-option (#807)
  • -init now accepts -masterkey
  • -passwd now ignores -extpass and -passfile for the new password (#287, #882)

v2.4.0, 2023-06-10

  • Try the mount(2) syscall before falling back to fusermount(1). This means we
    don't need fusermount(1) at all if running as root or in a root-like namespace
    (#697)
  • Fix -extpass mis-parsing commas (#730)
  • Fix rm -R mis-reporting write-protected directory on gocryptfs on sshfs
    (commit)

v2.3.2, 2023-04-29

  • Fix incorrect file size reported after hard link creation
    (#724)

v2.3.1, 2023-03-04

  • Optimize NFS streaming write performance (#712,
    commit).
    You should see about a 4x performance increase.
  • Use debug.ReadBuildInfo() to provide some
    version information even when not built with build.bash (#701) .
  • Fix bug that caused the logger process to be killed when started from xfce4-terminal,
    and that terminal window was closed (#660,
    commit).
  • MacOS: Fix reverse mount failing with read-only file system (#690)
  • Make gocryptfs compile on riscv64 by switching from jacobsa/crypto
    to maintained fork aperturerobotics/jacobsa-crypto
    (#674)

v2.3.0, 2022-10-21

  • Identical to v2.3, just tagged once more in full semver x.y.z format. This make Go's fetching logic happy,
    which ignores v2.3 (without the third digit) completely.
    Fixes #694, #688.

v2.3, 2022-08-28

  • Add -longnamemax flag to -init (#499).
    Can be used to work around file or path length restrictions on online storage.
    See the man page
    for details.
  • Support for NO_COLOR env variable (#617)
  • Fix -force_owner not not affecting socket files (#629
  • MacOS: fix inaccessible gocryptfs.conf in reverse mode (commit)
  • Raise ctlsock operation timeout from 1 to 10 seconds (#683)

v2.2.1, 2021-10-20

  • Fix -force_owner only taking effect after 2 seconds (#609).
    This was a regression introduced in v2.0.
  • MacOS: Fix build.bash failure with error date: illegal option -- - when SOURCE_DATE_EPOCH is set
    (#570)
  • -init: suggest xchacha on CPUs without AES acceleration (commit)
  • -info: add contentEncryption to output

v2.2.0, 2021-09-25

  • -deterministic-names: new option for -init, both for reverse and forward mode.
    Disables file name randomisation & gocryptfs.diriv files
    (#151, #402, #592)
    • New feature flag! You need gocryptfs v2.2 or higher to mount a filesystem that uses this flag.
  • -xchacha: new option for -init (forward mode only). Selects XChaCha20-Poly1305 for content encryption.
    Gives much better performance on CPUs without AES acceleration
    (#452).
    • New feature flag! You need gocryptfs v2.2 or higher to mount a filesystem that uses this flag.
    • Test with gocryptfs -speed what is fastest for your CPU, or read here
  • Rewrite OpenSSL backend
    for better performance on AES-GCM-256-OpenSSL and XChaCha20-Poly1305-OpenSSL
  • -serialize_reads: get rid of delay logic by taking advantage of the kernel flag
    FUSE_CAP_ASYNC_READ
    (go-fuse commit,
    gocryptfs commit)
  • Make obsolete -devrandom flag a no-op (commit)
  • Make -forcedecode flag a no-op (commit)
  • Fix reverse mode sometimes remapping most inode numbers to >281474976710656 (commit)
  • This version will be called v2.2.0 (instead of v2.2) to comply with
    the Go module versioning convention.
    Later releases will also follow the convention.

v2.1, 2021-08-18

  • -fido2: do not request PIN on gocryptfs -init fixing FIDO_ERR_UNSUPPORTED_OPTION with YubiKey
    (#571)
  • -sharedstorage: present stable inode numbers, fixing getcwd failures
    (#584)
  • -badname: make it possible to access content of invalid file names (#568).
    Thanks @DerDonut!
  • Implement recursive gocryptfs.diriv caching to fix exponential runtime with deep directories
    (commit])
  • Implements fsync on directories (#587)
  • -reverse: implement -one-file-system (#475)
  • -reverse: allow exclude-all-but (#588)
    • Example: gocryptfs -reverse -exclude-wildcard '*' -exclude-wildcard '!/my-important-files' /home/user /mnt/user.encrypted
  • macOS: Fix panic: using reserved ID 1 on ExFAT (#585)
  • Switch to pflag cli parsing library to support flags and arguments in any order
    (#590)
  • Drop support for Go 1.11 & Go 1.12 (commit)
    • You must have Go 1.13 or newer now

v2.0.1, 2021-06-07

  • Fix symlink creation reporting the wrong size, causing git to report it as modified
    (#574)

v2.0, 2021-06-05

v2.0-beta4, 2021-05-15

v2.0-beta3, 2021-04-24

  • MANPAGE: Split options into sections acc. to where they apply (#517)
  • -idle: count cwd inside the mount as busy (#533)
  • Make gocryptfs.diriv and gocryptfs.xxx.name files world-readable to make encrypted backups easier
    when mounting via /etc/fstab (#539)
  • Make it work with MacFUSE v4.x (#524)
  • Disable ACL encryption, it causes a lot of problems (#543,
    #536)
    • Old encrypted ACLs are reported by gocryptfs -fsck but otherwise ignored
    • This fixes inheritance, but does not yet enforce them correctly
  • Include gocryptfs-xray in binary releases (#496)
  • go-fuse: track most recent parent. This improves robustness when the filesystem is modified behind
    the back of gocryptfs. Helps both with -sharedstorage and also without.
    (commit 1,
    commit 2,
    #549)
  • Add directory fd caching for 2x - 3x speed boost in small file ops compared to v2.0-beta2
    (performance numbers)

v2.0-beta2, 2020-11-14

v2.0-beta1, 2020-10-15

  • Switch to the improved go-fuse v2 API
    • This is a big change, a lot of code has been reorganized or rewritten
      to fit the v2 API model.
    • Please test & report bugs
    • No changes to the on-disk format
    • File descriptor caching is not yet implemented,
      causing a slowdown. Caching will be implemented for v2.0 final.
  • Add support for FIDO2 tokens (-fido2, #505)
  • Add -encrypt-paths / -decrypt-paths functionality to gocryptfs-xray
    (#416)
  • Accept multiple -passfiles
    (#288)
  • Make -masterkey=stdin work together with -passwd
    (#461)
  • Fix Unknown opcode 2016 crash on Google Cloud
    (go-fuse #276,
    gocryptfs commit ec74d1d)

v1.8.0, 2020-05-09

  • Enable ACL support (#453)
    • Warning 2021-02-07: This feature is incomplete! Do not use ACLs before gocryptfs v2.0 final!
      Reading and writing ACLs works, but they are not enforced or inherited (#542)
  • Ignore .nfsXXX temporary files
    (#367)
  • Handle inode number collisions from multiple devices
    (#435)
  • Drop -nonempty for fusermount3
    (#440)
  • Reverse mode: improve inode number mapping and max=1000000000000000000 limitation
    (#457)
  • Enable --buildmode=pie (#460)
  • Migrate from dep to Go Modules
    (commit cad711993)
  • go mod: update dependencies
    (commit b23f77c)
  • gocryptfs -speed: add XChaCha20-Poly1305-Go
    (#452)
  • Respect GOMAXPROCS environment variable
    (commit ff210a06f
  • Completely remove Trezor-related code (commit 1364b44ae356da31e24e5605fe73a307e9d6fb03)
    • Has been disabled since v1.7 due to issues a third-party module.
    • Please use FIDO2 instead (gocryptfs v2.0)

v1.7.1, 2019-10-06

  • Support wild cards in reverse mode via --exclude-wildcard
    (#367). Thanks @ekalin!
  • Create gocryptfs.diriv files with 0440 permissions to make it easier to
    share an encrypted folder via a network drive
    (#387).
    Note: as a security precaution, the owner must still manually
    chmod gocryptfs.conf 0440 to allow mounting.
  • Allow the nofail option in /etc/fstab
  • -passwd can now change the -scryptn parameter for existing filesystems
    (#400)
  • Fix -idle unmounting the filesystem despite recent activity
    (#421)
  • Fix a race condition related to inode number reuse
    (#363)
    .
    It could be triggered by concurrently creating and deleting files and can lead to data loss
    in the affected file. This bug was found by the automated tests on Travis
    and was very hard to trigger locally.
  • tests: use /var/tmp instead of /tmp by default
    (commit 8c4429)

v1.7, 2019-03-17

  • Fix possible symlink race attacks in forward mode when using allow_other + plaintextnames
    • If you use both -allow_other and -plaintextnames, you should upgrade.
      Malicious users could trick gocryptfs into modifying files outside of CIPHERDIR,
      or reading files inside CIPHERDIR that they should not have access to.
    • If you do not use -plaintextnames (disabled per default), these attacks do
      not work as symlinks are encrypted.
    • Forward mode has been reworked to use the "*at" family of system calls everywhere
      (Openat/Unlinkat/Symlinkat/...).
    • As a result, gocryptfs may run slightly slower, as the caching logic has been
      replaced and is very simple at the moment.
    • The possibility for such attacks was found during an internal code review.
  • Reverse mode: fix excluded, unaccessible files showing up in directory listings
    (#285,
    #286)
  • gocryptfs-xray: add -aessiv flag for correctly parsing AES-SIV format files
    (#299)
  • Ensure that standard fds 0,1,2 are always initialized
    (#320).
    Prevents trouble in the unlikely case that gocryptfs is called with
    stdin,stdout and/or stderr closed.
  • -extpass now can be specified multiple times to support arguments containing spaces
    (#289)
  • Drop Fstatat, Mkdirat, Syslinkat, Fchownat, Unlinkat, Renameat, Openat emulation of MacOS
    and instead use native functions (thanks @slackner !)
  • Use Setreuid to robustly set the owner with allow_other (@slackner,
    (commit))
  • Pack the rendered man page into the source code archive for user convenience
    (issue 355)
  • Disable Trezor support again (commit 16fac26c57ba303bf60266d24c17f5243e5ea376)
    • Trezor support has been broken since Sept 2018 due to issues
      in a third-party module (#261)

v1.6.1, 2018-12-12

  • Fix "Operation not supported" chmod errors on Go 1.11
    (#271)

v1.6, 2018-08-18

  • Add -e / -exclude option for reverse mode
    (#235,
    commit)
  • Add support for the Trezor One HSM PR#247, thanks @xaionaro!
    • Use ./build.bash -tags enable_trezor to compile with Trezor support
    • Then, use gocryptfs -init -trezor to create a filesystem locked with a physical Trezor device.
    • Note 2021-01-31: Support was removed again in gocryptfs v1.7. Please use -fido2 in gocryptfs v2.0.
  • Only print master key once, on init
    (#76,
    commit)
  • Fall back to buffered IO even when passed O_DIRECT
    (commit)

v1.5, 2018-06-12

  • Support extended attributes (xattr) in forward mode
    (#217). Older gocryptfs versions
    will ignore the extended attributes.
  • Add -fsck function
    (#191)
  • Fix clobbered timestamps on MacOS High Sierra
    (#229)
  • Add -masterkey=stdin functionality
    (#218)
  • Accept -dev/-nodev, suid/nosuid, -exec/-noexec,
    -ro/-rw flags to make mounting via /etc/fstab possible.
    Thanks @mahkoh! (#233,
    commit,
    commit)
  • Fix a logger path issue on SuSE
    #225
  • Stop printing the help text on a "flag provided but not defined"
    error (commit)

v1.4.4, 2018-03-18

  • Overwrite secrets in memory with zeros as soon as possible
    (#211)
  • Fix Getdents problems on i386 and mips64le
    (#197,
    #200)
  • Make building with gccgo work
    (#201)
  • MacOS: fix osxfuse: vnode changed generation / Error code -36 issue in go-fuse
    (#213,
    commit)
  • Fix various test issues on MacOS

v1.4.3, 2018-01-21

  • Fix several symlink race attacks in connection with reverse mode
    and allow_other. Thanks to @slackner for reporting and helping to fix
    the issues:
    • Fix symlink races in reverse mode
      (issue #165)
    • Fix symlink races in connection with -allow_other
      (issue #177)
  • Fix problems with special names when using -plaintextnames
    (issue #174)
  • Add -devrandom command-line option
    (commit)
  • Add -sharedstorage command-line option
    (commit,
    issue #156)
  • MacOS: let OSXFuse create the mountpoint if it does not exist
    (issue #194)

v1.4.2, 2017-11-01

  • Add Gopkg.toml file for dep vendoring and reproducible builds
    (issue #142)
  • MacOS: deal with .DS_Store files inside CIPHERDIR
    (issue #140)
  • Reverse mode: fix ENOENT error affecting names exactly 176 bytes long
    (issue #143)
  • Support kernels compiled with > 128 kiB FUSE request size (Synology NAS)
    (issue #145,
    commit)
  • Fix a startup hang when $PATH contains the mountpoint
    (issue #146)

v1.4.1, 2017-08-21

  • Use memory pools for buffer handling (
    3c6fe98,
    b2a23e9,
    12c0101)
    • On my machine, this doubles the streaming read speed
      (see performance.txt)
  • Implement and use the getdents(2) syscall for a more efficient
    OpenDir implementation
    (e50a6a5)
  • Purge masterkey from memory as soon as possible
    (issue #137)
  • Reverse mode: fix inode number collision between .name and .diriv
    files
    (d12aa57)
  • Prevent the logger from holding stdout open
    (issue #130)
  • MacOS: make testing without openssl work properly
    (ccf1a84)
  • MacOS: specify a volume name
    (9f8e19b)
  • Enable writing to write-only files
    (issue #125)

v1.4, 2017-06-20

  • Switch to static binary releases
    • From gocryptfs v1.4, I will only release statically-built binaries.
      These support all Linux distributions but cannot use OpenSSL.
    • OpenSSL is still supported - just compile from source!
  • Add -force_owner option to allow files to be presented as owned by a
    different user or group from the user running gocryptfs. Please see caveats
    and guidance in the man page before using this functionality.
  • Increase open file limit to 4096 (#82).
  • Implement path decryption via ctlsock (#84).
    Previously, decryption was only implemented for reverse mode. Now both
    normal and reverse mode support both decryption and encryption of
    paths via ctlsock.
  • Add more specific exit codes for the most common failure modes,
    documented in CLI_ABI.md
  • Reverse mode: make sure hard-linked files always return the same
    ciphertext
    (commit 9ecf2d1a)
  • Display a shorter, friendlier help text by default.
  • Parallelize file content encryption by splitting data blocks into two
    threads (ticket#116)
  • Prefetch random nonces in the background
    (commit 80516ed)
  • Add -info option to pretty-print infos about a filesystem.

v1.3, 2017-04-29

  • Use HKDF to derive separate keys for GCM and EME
    • New feature flag: HKDF (enabled by default)
    • This is a forwards-compatible change. gocryptfs v1.3 can mount
      filesystems created by earlier versions but not the other way round.
  • Enable Raw64 filename encoding by default (gets rid of trailing == characters)
    • This is a forwards-compatible change. gocryptfs v1.3 can mount
      filesystems created by earlier versions but not the other way round.
  • Drop Go 1.4 compatibility. You now need Go 1.5 (released 2015-08-19)
    or higher to build gocryptfs.
  • Add -serialize_reads command-line option
    • This can greatly improve performance on storage
      that is very slow for concurrent out-of-order reads. Example:
      Amazon Cloud Drive (#92)
  • Reject file-header-only files
    (#90 2.2,
    commit)
  • Increase max password size to 2048 bytes (#93)
  • Use stable 64-bit inode numbers in reverse mode
    • This may cause problems for very old 32-bit applications
      that were compiled without Large File Support.
  • Passing "--" now also blocks "-o" parsing

v1.2.1, 2017-02-26

  • Add an integrated speed test, gocryptfs -speed
  • Limit password size to 1000 bytes and reject trailing garbage after the newline
  • Make the test suite work on Mac OS X
  • Handle additional corner cases in -ctlsock path sanitization
  • Use dedicated exit code 12 on "password incorrect"

v1.2, 2016-12-04

  • Add a control socket interface. Allows to encrypt and decrypt filenames.
    For details see backintime#644.
    • New command-line option: -ctlsock
  • Under certain circumstances, concurrent truncate and read could return
    an I/O error. This is fixed by introducing a global open file table
    that stores the file IDs
    (commit).
  • Coalesce 4kB ciphertext block writes up to the size requested through
    the write FUSE call
    (commit with benchmarks)
  • Add -noprealloc command-line option
    • Greatly speeds up writes on Btrfs
      (#63)
      at the cost of reduced out-of-space robustness.
    • This is a workaround for Btrfs' slow fallocate(2)
  • Preserve owner for symlinks an device files (fixes bug #64)
  • Include rendered man page gocryptfs.1 in the release tarball

v1.1.1, 2016-10-30

  • Fix a panic on setting file timestamps (go-fuse#131)
  • Work around an issue in tmpfs that caused a panic in xfstests generic/075
    (gocryptfs#56)
  • Optimize NFS streaming writes
    (commit)

v1.1, 2016-10-19

  • Add reverse mode (#19)
    • AES-SIV (RFC5297) encryption to implement deterministic encryption
      securely. Uses the excellent
      jacobsa/crypto library.
      The corresponding feature flag is called AESSIV.
    • New command-line options: -reverse, -aessiv
    • Filesystems using reverse mode can only be mounted with gocryptfs v1.1
      and later.
    • The default, forward mode, stays fully compatible with older versions.
      Forward mode will keep using GCM because it is much faster.
  • Accept -o foo,bar,baz-style options that are passed at the end of
    the command-line, like mount(1) does. All other options must still
    precede the passed paths.
    • This allows mounting from /etc/fstab. See
      #45 for details.
    • Mounting on login using pam_mount works as well. It is
      described in the wiki.
  • To prevent confusion, the old -o option had to be renamed. It is now
    called -ko. Arguments to -ko are passed directly to the kernel.
  • New -passfile command-line option. Provides an easier way to read
    the password from a file. Internally, this is equivalent to
    -extpass "/bin/cat FILE".
  • Enable changing the password when you only know the master key
    (#28)

v1.0, 2016-07-17

  • Deprecate very old filesystems, stage 3/3
    • Filesystems created by v0.6 can no longer be mounted
    • Drop command-line options -gcmiv128, -emenames, -diriv. These
      are now always enabled.
  • Add fallocate(2) support
  • New command-line option -o
    • Allows to pass mount options directly to the kernel
  • Add support for device files and suid binaries
    • Only works when running as root
    • Must be explicitly enabled by passing "-o dev" or "-o suid" or "-o suid,dev"
  • Experimental Mac OS X support. See
    ticket #15 for details.

v0.12, 2016-06-19

  • Deprecate very old filesystems, stage 2/3
    • Filesystems created by v0.6 and older can only be mounted read-only
    • A message
      explaining the situation is printed as well
  • New command line option: -ro
    • Mounts the filesystem read-only
  • Accept password from stdin as well (ticket #30)

v0.11, 2016-06-10

  • Deprecate very old filesystems, stage 1/3
    • Filesystems created by v0.6 and older can still be mounted but a
      warning
      is printed
    • See ticket #29 for details and
      join the discussion
  • Add rsync stress test "pingpong-rsync.bash"
    • Fix chown and utimens failures that caused rsync to complain
  • Build release binaries with Go 1.6.2
    • Big speedup for CPUs with AES-NI, see ticket #23

v0.10, 2016-05-30

  • Replace spacemonkeygo/openssl with stupidgcm
    • gocryptfs now has its own thin wrapper to OpenSSL's GCM implementation
      called stupidgcm.
    • This should fix the compile issues
      people are seeing with spacemonkeygo/openssl. It also gets us
      a 20% performance boost for streaming writes.
  • Automatically choose between OpenSSL and Go crypto issue #23
    • Go 1.6 added an optimized GCM implementation in amd64 assembly that uses AES-NI.
      This is faster than OpenSSL and is used if available. In all other
      cases OpenSSL is much faster and is used instead.
    • -openssl=auto is the new default
    • Passing -openssl=true/false overrides the autodetection.
  • Warn but continue anyway if fallocate(2) is not supported by the
    underlying filesystem, see issue #22
    • Enables to use gocryptfs on ZFS and ext3, albeit with reduced out-of-space safety.
  • Fix statfs, by @lxp
  • Fix a fsstress failure
    in the go-fuse library.

v0.9, 2016-04-10

  • Long file name support
    • gocryptfs now supports file names up to 255 characters.
    • This is a forwards-compatible change. gocryptfs v0.9 can mount filesystems
      created by earlier versions but not the other way round.
  • Refactor gocryptfs into multiple "internal" packages
  • New command-line options:
    • -longnames: Enable long file name support (default true)
    • -nosyslog: Print messages to stdout and stderr instead of syslog (default false)
    • -wpanic: Make warning messages fatal (used for testing)
    • -d: Alias for -debug
    • -q: Alias for -quiet

v0.8, 2016-01-23

  • Redirect output to syslog when running in the background
  • New command-line option:
    • -memprofile: Write a memory allocation debugging profile the specified
      file

v0.7.2, 2016-01-19

  • Fix performance issue in small file creation
    • This brings performance on-par with EncFS paranoia mode, with streaming writes
      significantly faster
    • The actual fix
      is in the go-fuse library. There are no code changes in gocryptfs.

v0.7.1, 2016-01-09

  • Make the build.bash script compatible with Go 1.3
  • Disable fallocate on OSX (system call not available)
  • Introduce pre-built binaries for Fedora 23 and Debian 8

v0.7, 2015-12-20

  • Extend GCM IV size to 128 bit from Go's default of 96 bit
    • This pushes back the birthday bound to make IV collisions virtually
      impossible
    • This is a forwards-compatible change. gocryptfs v0.7 can mount filesystems
      created by earlier versions but not the other way round.
  • New command-line option:
    • -gcmiv128: Use 128-bit GCM IVs (default true)

v0.6, 2015-12-08

  • Wide-block filename encryption using EME + DirIV
    • EME (ECB-Mix-ECB) provides even better security than CBC as it fixes
      the prefix leak. The used Go EME implementation is
      https://github.com/rfjakob/eme which is, as far as I know, the first
      implementation of EME in Go.
    • This is a forwards-compatible change. gocryptfs v0.6 can mount filesystems
      created by earlier versions but not the other way round.
  • New command-line option:
    • -emenames: Enable EME filename encryption (default true)

v0.5.1, 2015-12-06

  • Fix a rename regression caused by DirIV and add test case
  • Use fallocate to guard against out-of-space errors

v0.5, 2015-12-04

  • Stronger filename encryption: DirIV
    • Each directory gets a random 128 bit file name IV on creation,
      stored in gocryptfs.diriv
    • This makes it impossible to identify identically-named files across
      directories
    • A single-entry IV cache brings the performance cost of DirIV close to
      zero for common operations (see performance.txt)
    • This is a forwards-compatible change. gocryptfs v0.5 can mount filesystems
      created by earlier versions but not the other way round.
  • New command-line option:
    • -diriv: Use the new per-directory IV file name encryption (default true)
    • -scryptn: allows to set the scrypt cost parameter N. This option
      can be used for faster mounting at the cost of lower brute-force
      resistance. It was mainly added to speed up the automated tests.

v0.4, 2015-11-15

  • New command-line options:
    • -plaintextnames: disables filename encryption, added on user request
    • -extpass: calls an external program for prompting for the password
    • -config: allows to specify a custom gocryptfs.conf path
  • Add FeatureFlags gocryptfs.conf parameter
    • This is a config format change, hence the on-disk format is incremented
    • Used for ext4-style filesystem feature flags. This should help avoid future
      format changes. The first user is -plaintextnames.
  • On-disk format 2

v0.3, 2015-11-01

  • Add a random 128 bit file header to authenticate file->block ownership
    • This is an on-disk-format change
  • On-disk format 1

v0.2, 2015-10-11

  • Replace bash daemonization wrapper with native Go implementation
  • Better user feedback on mount failures

v0.1, 2015-10-07

  • First release
  • On-disk format 0

Documentation CLI ABI (`Documentation/CLI_ABI.md`)

Stable CLI ABI

If you want to call gocryptfs from your script or app, this is the
stable ABI.

General

  1. A password is piped into gocryptfs with an optional terminating
    newline. Any unexpected data after the final newline will
    cause gocryptfs to abort.
  2. Always pass "--" after the options. This prevents a CIPERDIR that
    starts with a dash ("-") to wreak havoc.
  3. Use "-q" to get rid of all informational messages. Only error
    messages (if any) will be printed to stderr (capture it!).
  4. Check the exit code of gocryptfs. 0 is success, anything else is an
    error and details about that error will have been printed to stderr.

Initialize Filesystem

Bash example

text
$ cat mypassword.txt | gocryptfs -init -q -- CIPHERDIR

Content of "mypassword.txt":

text
mypassword1234

What you have to pipe to gocryptfs

  1. Password
  2. Optional newline

Notes

  1. The CIPHERDIR directory must exist and be empty

Exit Codes

  • 0 = success
  • 6 = CIPHERDIR is invalid: not an empty directory
  • 22 = password is empty
  • 24 = could not create gocryptfs.conf
  • other = please inspect the message

Mount

Bash example

text
$ cat mypassword.txt | gocryptfs -q -- CIPHERDIR MOUNTPOINT

What you have to pipe to gocryptfs

Same as for "Initialize Filesystem".

Notes

  1. The MOUNTPOINT directory must exist and be empty.

Exit Codes

  • 0 = success
  • 10 = MOUNTPOINT is not an empty directory or contains CIPHERDIR
  • 12 = password incorrect
  • 23 = gocryptfs.conf could not be opened (does not exist, is unreadable, ...)
  • other = please inspect the message

Change Password

Bash example

text
$ cat change.txt | gocryptfs -passwd -q -- CIPHERDIR

Content of "change.txt":

text
mypassword1234
newpassword9876

What you have to pipe to gocryptfs

  1. Old password
  2. Newline
  3. New password
  4. Optional newline

Exit Codes

  • 0 = success
  • 12 = password incorrect
  • 23 = gocryptfs.conf could not be opened for reading
  • 24 = could not write the updated gocryptfs.conf
  • other = please inspect the message

Further Reading

Additional exit codes that are unlikely to occur are defined in
exitcodes.go.


Documentation MANPAGE STATFS (`Documentation/MANPAGE-STATFS.md`)

% STATFS(1)
% github.com/rfjakob
% Sep 2019

NAME

statfs - dump the statfs(2) information for PATH to console in JSON format.

SYNOPSIS

statfs PATH

DESCRIPTION

The statfs(2) system call returns information about a mounted filesystem
in a statfs_t structure. This tool dumps this information in JSON format.
It is developed as part of gocryptfs and written in Go.

The statfs_t structure is architecture-dependent. On amd64 it looks like this:

text
type Statfs_t struct {
	Type   int64
	Bsize  int64
	Blocks uint64
	Bfree  uint64
	Bavail uint64
	Files  uint64
	Ffree  uint64
	Fsid   struct {
		Val [2]int32
	}
	Namelen int64
	Frsize  int64
	Flags   int64
	Spare   [4]int64
}

See the statfs(2) man page for the meaning of these fields, and note
that the field names here are acc. to the Go golang.org/x/sys/unix
naming convention, and slightly different than in C.

EXAMPLES

Get the statfs(2) information for /tmp:

text
$ statfs /tmp
{
	"Type": 16914836,
	"Bsize": 4096,
	"Blocks": 3067428,
	"Bfree": 3067411,
	"Bavail": 3067411,
	"Files": 3067428,
	"Ffree": 3067381,
	"Fsid": {
		"Val": [
			0,
			0
		]
	},
	"Namelen": 255,
	"Frsize": 4096,
	"Flags": 38,
	"Spare": [
		0,
		0,
		0,
		0
	]
}

SEE ALSO

statfs(2) gocryptfs(1)


Documentation MANPAGE XRAY (`Documentation/MANPAGE-XRAY.md`)

% GOCRYPTFS-XRAY(1)
% github.com/rfjakob
% Jan 2018

NAME

gocryptfs-xray - examine gocryptfs-related data

SYNOPSIS

Examine encrypted file/directory

gocryptfs-xray CIPHERDIR/ENCRYPTED-FILE-OR-DIR

Decrypt and show master key

gocryptfs-xray -dumpmasterkey CIPHERDIR/gocryptfs.conf

Encrypt paths

gocryptfs-xray -encrypt-paths SOCKET

DESCRIPTION

Available options are listed below.

-0

Use \0 instead of \n as separator for -decrypt-paths and -encrypt-paths.

-aessiv

Assume AES-SIV mode instead of AES-GCM when examining an encrypted file.
Is not needed and has no effect in -dumpmasterkey mode.

-decrypt-paths

Decrypt file paths using gocryptfs control socket. Reads from stdin.
See -ctlsock in gocryptfs(1).

-dumpmasterkey

Decrypts and shows the master key.

-encrypt-paths

Encrypt file paths using gocryptfs control socket. Reads from stdin.
See -ctlsock in gocryptfs(1).

EXAMPLES

Examine an encrypted file:

text
gocryptfs-xray myfs/mCXnISiv7nEmyc0glGuhTQ

Print the master key:

text
gocryptfs-xray -dumpmasterkey myfs/gocryptfs.conf

Mount gocryptfs with control socket and use gocryptfs-xray to
encrypt some paths:

text
gocryptfs -ctlsock myfs.sock myfs myfs.mnt
echo -e "foo\nbar" | gocryptfs-xray -encrypt-paths myfs.sock

SEE ALSO

gocryptfs(1) fuse(8)


Documentation MANPAGE (`Documentation/MANPAGE.md`)

% GOCRYPTFS(1)
% github.com/rfjakob
% Aug 2017

NAME

gocryptfs - create or mount an encrypted filesystem

SYNOPSIS

Initialize new encrypted filesystem

gocryptfs -init [OPTIONS] CIPHERDIR

Mount

gocryptfs [OPTIONS] CIPHERDIR MOUNTPOINT [-o COMMA-SEPARATED-OPTIONS]

Unmount

fusermount -u MOUNTPOINT

Change password

gocryptfs -passwd [OPTIONS] CIPHERDIR

Check consistency

gocryptfs -fsck [OPTIONS] CIPHERDIR

Show filesystem information

gocryptfs -info [OPTIONS] CIPHERDIR

DESCRIPTION

gocryptfs is an encrypted overlay filesystem written in Go.
Encrypted files are stored in CIPHERDIR, and a plain-text
view can be presented by mounting the filesystem at MOUNTPOINT.

gocryptfs was inspired by encfs(1) and strives to fix its
security issues while providing good performance.

ACTION FLAGS

Unless one of the following action flags is passed, the default
action is to mount a filesystem (see SYNOPSIS).

-fsck

Check CIPHERDIR for consistency. If corruption is found, the
exit code is 26.

-h, -help

Print a short help text that shows the more-often used options.

-hh

Long help text, shows all available options.

-info

Pretty-print the contents of the config file in CIPHERDIR for
human consumption, stripping out sensitive data.

Example:

text
$ gocryptfs -info my_cipherdir
Creator:      gocryptfs v2.0-beta2
FeatureFlags: GCMIV128 HKDF DirIV EMENames LongNames Raw64
EncryptedKey: 64B
ScryptObject: Salt=32B N=65536 R=8 P=1 KeyLen=32

-init

Initialize encrypted directory.

-passwd

Change the password. Will ask for the old password, check if it is
correct, and ask for a new one.

This can be used together with -masterkey if
you forgot the password but know the master key. Note that without the
old password, gocryptfs cannot tell if the master key is correct and will
overwrite the old one without mercy. It will, however, create a backup copy
of the old config file as gocryptfs.conf.bak. Delete it after
you have verified that you can access your files with the
new password.

-speed

Run crypto speed test. Benchmark Go's built-in GCM against OpenSSL
(if available). The library that will be selected on "-openssl=auto"
(the default) is marked as such.

-version

Print version and exit. The output contains three fields separated by ";".
Example: "gocryptfs v1.1.1-5-g75b776c; go-fuse 6b801d3; 2016-11-01 go1.7.3".
Field 1 is the gocryptfs version, field 2 is the version of the go-fuse
library, field 3 is the compile date and the Go version that was
used.

INIT OPTIONS

Available options for -init are listed below. Usually, you don't need any.
Defaults are fine.

-aessiv

Use the AES-SIV encryption mode. This is slower than AES-GCM but is
secure with deterministic nonces as used in "-reverse" mode.

Run gocryptfs -speed to find out if and how much slower.

-deterministic-names

Disable file name randomisation and creation of gocryptfs.diriv files.
This can prevent sync conflicts when synchronising files, but
leaks information about identical file names across directories
("Identical names leak" in https://nuetzlich.net/gocryptfs/comparison/#file-names ).

The resulting gocryptfs.conf has "DirIV" missing from "FeatureFlags".

-devrandom

Obsolete and ignored on gocryptfs v2.2 and later.

See https://github.com/rfjakob/gocryptfs/commit/f3c777d5eaa682d878c638192311e52f9c204294
and https://github.com/rfjakob/gocryptfs/issues/596 for background info.

-hkdf

Use HKDF to derive separate keys for content and name encryption from
the master key. Default true.

-longnamemax

text
integer value, allowed range 62...255

Hash file names that (in encrypted form) exceed this length. The default
is 255, which aligns with the usual name length limit on Linux and
provides best performance.

However, online storage may impose lower limits on file name and/or
path length. In this case, setting -longnamemax to a lower value
can be helpful.

The lower the value, the more extra .name files
must be created, which slows down directory listings.

Values below 62 are not allowed as then the hashed name
would be longer than the original name.

Example:

text
-longnamemax 100

-plaintextnames

Do not encrypt file names and symlink targets.

-raw64

Use unpadded base64 encoding for file names. This gets rid of the
trailing "\=\=". A filesystem created with this option can only be
mounted using gocryptfs v1.2 and higher. Default true.

-reverse

Reverse mode shows a read-only encrypted view of a plaintext
directory. Implies -aessiv.

If you want to mount the encrypted view using -masterkey, you must
specify -aessiv.

-xchacha

Use XChaCha20-Poly1305 file content encryption. This should be much faster
than AES-GCM on CPUs that lack AES acceleration.

Run gocryptfs -speed to find out if and how much faster.

MOUNT OPTIONS

Available options for mounting are listed below. Usually, you don't need any.
Defaults are fine.

-acl

Enable ACL enforcement. When you want to use ACLs, you must enable this
option.

-allow_other

By default, the Linux kernel prevents any other user (even root) to
access a mounted FUSE filesystem. Settings this option allows access for
other users, subject to file permission checking. Only works if
user_allow_other is set in /etc/fuse.conf. This option is equivalent to
"allow_other" plus "default_permissions" described in fuse(8).

-badname string

When gocryptfs encounters a "bad" file name (cannot be decrypted or decrypts
to garbage), a warning is logged and the file is hidden from the
plaintext view.

With the -badname option, you can select "bad" file names that should
still be shown in the plaintext view instead of hiding them. Bad files
will get GOCRYPTFS_BAD_NAME appended to their name.

Glob pattern. Can be passed multiple times for multiple patterns.

Examples:

Dropbox sync conflicts:

text
-badname '*conflicted copy*'

Syncthing sync conflicts:

text
-badname '*.sync-conflict*'

Show all invalid filenames:

text
-badname '*'

-context string

Set the SELinux context. See mount(8) for details.

This option was added for compatibility with xfstests which sets
this option via -o context="system_u:object_r:root_t:s0".

Only works when mounting as root, otherwise you get this error from fusermount3:

text
fusermount3: unknown option 'context="system_u:object_r:root_t:s0"'

-ctlsock string

Create a control socket at the specified location. The socket can be
used to decrypt and encrypt paths inside the filesystem. When using
this option, make sure that the directory you place the socket in is
not world-accessible. For example, /run/user/UID/my.socket would
be suitable.

-dev, -nodev

Enable (-dev) or disable (-nodev) device files in a gocryptfs mount
(default: -nodev). If both are specified, -nodev takes precedence.
You need root permissions to use -dev.

-e PATH, -exclude PATH

Only for reverse mode: exclude relative plaintext path from the encrypted
view, matching only from root of mounted filesystem. Can be passed multiple
times.

Example that excludes the directories "Music" and "Movies" from the root
directory:

text
gocryptfs -reverse -exclude Music -exclude Movies /home/user /mnt/user.encrypted

See also -exclude-wildcard, -exclude-from and the EXCLUDING FILES section.

-ew GITIGNORE-PATTERN, -exclude-wildcard GITIGNORE-PATTERN

Only for reverse mode: exclude paths from the encrypted view in gitignore(5) syntax,
wildcards supported. Pass multiple times for multiple patterns.

Example to exclude all .mp3 files in any directory:

text
gocryptfs -reverse -exclude-wildcard '*.mp3' /home/user /mnt/user.encrypted

Example to to exclude everything but the directory 'important' in the root dir:

text
gocryptfs -reverse -exclude-wildcard '*' -exclude-wildcard '!/important' /home/user /mnt/user.encrypted

See also -exclude-from and the EXCLUDING FILES section.

-exclude-from FILE

Only for reverse mode: reads gitignore patterns
from a file. Can be passed multiple times. Example:

text
gocryptfs -reverse -exclude-from ~/crypt-exclusions /home/user /mnt/user.encrypted

See also -exclude, -exclude-wildcard and the EXCLUDING FILES section.

-exec, -noexec

Enable (-exec) or disable (-noexec) executables in a gocryptfs mount
(default: -exec). If both are specified, -noexec takes precedence.

-fg, -f

Stay in the foreground instead of forking away.
For compatibility, "-f" is also accepted, but "-fg" is preferred.

Unless -notifypid is also passed, the logs go to stdout and stderr
instead of syslog.

-force_owner string

If given a string of the form "uid:gid" (where both "uid" and "gid" are
substituted with positive integers), presents all files as owned by the given
uid and gid, regardless of their actual ownership. Implies "allow_other".

This is rarely desired behavior: One should usually run gocryptfs as the
account which owns the backing-store files, which should usually be one and
the same with the account intended to access the decrypted content. An example
of a case where this may be useful is a situation where content is stored on a
filesystem that doesn't properly support UNIX ownership and permissions.

-forcedecode

Obsolete and ignored on gocryptfs v2.2 and later.

See https://github.com/rfjakob/gocryptfs/commit/d023cd6c95fcbc6b5056ba1f425d2ac3df4abc5a
for what it was and why it was dropped.

-fsname string

Override the filesystem name (first column in df -T). Can also be
passed as "-o fsname=" and is equivalent to libfuse's option of the
same name. By default, CIPHERDIR is used.

-fusedebug

Enable fuse library debug output.

-i duration, -idle duration

Only for forward mode: automatically unmount the filesystem if it has been idle
for the specified duration. Durations can be specified like "500s" or "2h45m".
0 (the default) means stay mounted indefinitely.

When a process has open files or its working directory in the mount,
this will keep it not idle indefinitely.

-kernel_cache

Enable the kernel_cache option of the FUSE filesystem, see fuse(8) for details.

-ko

Pass additional mount options to the kernel (comma-separated list).
FUSE filesystems are mounted with "nodev,nosuid" by default. If gocryptfs
runs as root, you can enable device files by passing the opposite mount option,
"dev", and if you want to enable suid-binaries, pass "suid".
"ro" (equivalent to passing the "-ro" option) and "noexec" may also be
interesting. For a complete list see the section
FILESYSTEM-INDEPENDENT MOUNT OPTIONS in mount(8). On MacOS, "local" enables volume-based trash
if you have .Trashes folder in the root of your volume (might need to be manually created)
note, though, that "local" is marked as "experimental" in osxfuse;
"noapplexattr", "noappledouble" may also be interesting.

Note that unlike "-o", "-ko" is a regular option and must be passed BEFORE
the directories. Example:

text
gocryptfs -ko noexec /tmp/foo /tmp/bar

-longnames

Store names that are longer than 175 bytes in extra files (default true).

This flag is only useful when recovering very old gocryptfs filesystems (gocryptfs v0.8 and earlier)
using "-masterkey". It is ignored (stays at the default) otherwise.

-nodev

See -dev, -nodev.

-noexec

See -exec, -noexec.

-nofail

Having the nofail option in /etc/fstab instructs systemd to continue
booting normally even if the mount fails (see man systemd.fstab).

The option is ignored by gocryptfs itself and has no effect outside /etc/fstab.

-nonempty

Allow mounting over non-empty directories. FUSE by default disallows
this to prevent accidental shadowing of files.

-noprealloc

Disable preallocation before writing. By default, gocryptfs
preallocates the space the next write will take using fallocate(2)
in mode FALLOC_FL_KEEP_SIZE. The preallocation makes sure it cannot
run out of space in the middle of the write, which would cause the
last 4kB block to be corrupt and unreadable.

On ext4, preallocation is fast and does not cause a
noticeable performance hit. Unfortunately, on Btrfs, preallocation
is very slow, especially on rotational HDDs. The "-noprealloc"
option gives users the choice to trade robustness against
out-of-space errors for a massive speedup.

For benchmarks and more details of the issue see
https://github.com/rfjakob/gocryptfs/issues/63 .

-nosuid

See -suid, -nosuid.

-nosyslog

Diagnostic messages are normally redirected to syslog once gocryptfs
daemonizes. This option disables the redirection and messages will
continue be printed to stdout and stderr.

-notifypid int

Send USR1 to the specified process after successful mount. This is
used internally for daemonization.

-one-file-system

Don't cross filesystem boundaries (like rsync's --one-file-system).
Mountpoints will appear as empty directories.

Only applicable to reverse mode.

Limitation: Mounted single files (yes this is possible) are NOT hidden.

-readdirplus

Enable FUSE READDIRPLUS on Linux. It is disabled by default, so
attributes are fetched only when an application requests them.

READDIRPLUS requests attributes for every entry during a directory
listing. This can improve metadata-heavy workloads such as ls -l,
but adds unnecessary work to names-only listings. With the default
cache timeouts (without -sharedstorage), enabling READDIRPLUS made
metadata-heavy listings 1.36x faster in a local 100,000-file directory
and 1.82x faster in a single run over a 1,000,000-file NFS directory.
It made names-only listings 6.5x and 18.2x slower respectively.

The default also applies to reverse mode. Backup and synchronization
tools that inspect metadata for most entries may benefit from
-readdirplus.

This option can also be combined with -sharedstorage. Because that
mode disables kernel attribute caching, whether READDIRPLUS helps
depends on the workload and backing storage.

On platforms other than Linux, this option is accepted but has no
effect.

For benchmarks and more details, see
https://github.com/rfjakob/gocryptfs/issues/1026 .

-rw, -ro

Mount the filesystem read-write (-rw, default) or read-only (-ro).
If both are specified, -ro takes precedence.

-reverse

See the -reverse section in INIT OPTIONS. You need to specify the
-reverse option both at -init and at mount.

-serialize_reads

The kernel usually submits multiple concurrent reads to service
userspace requests and kernel readahead. gocryptfs serves them
concurrently and in arbitrary order. On backing storage that performs
poorly for concurrent or out-of-order reads (like Amazon Cloud Drive),
this behavior can cause very slow read speeds.

The -serialize_reads
option does two things: (1) reads will be submitted one-by-one (no
concurrency) and (2) gocryptfs tries to order the reads by file
offset order.

The ordering requires gocryptfs to wait a certain time before
submitting a read. The serialization introduces extra locking.
These factors will limit throughput to below 70MB/s.

For more details visit https://github.com/rfjakob/gocryptfs/issues/92 .

-sharedstorage

Enable work-arounds so gocryptfs works better when the backing
storage directory is concurrently accessed by multiple gocryptfs
instances.

At the moment, it does two things:

  1. Disable stat() caching so changes to the backing storage show up
    immediately.
  2. Disable hard link tracking, as the inode numbers on the backing
    storage are not stable when files are deleted and re-created behind
    our back. This would otherwise produce strange "file does not exist"
    and other errors.

When "-sharedstorage" is active, performance is reduced and hard
links cannot be created.

Even with this flag set, you may hit occasional problems. Running
gocryptfs on shared storage does not receive as much testing as the
usual (exclusive) use-case. Please test your workload in advance
and report any problems you may hit.

More info: https://github.com/rfjakob/gocryptfs/issues/156

-suid, -nosuid

Enable (-suid) or disable (-nosuid) suid and sgid executables in a gocryptfs
mount (default: -nosuid). If both are specified, -nosuid takes precedence.
You need root permissions to use -suid.

-zerokey

Use all-zero dummy master key. This options is only intended for
automated testing as it does not provide any security.

COMMON OPTIONS

Options that apply to more than one action are listed below.
Each options lists where it is applicable. Again, usually you
don't need any.

-config string

Use specified config file instead of CIPHERDIR/gocryptfs.conf.

Applies to: all actions that use a config file: mount, -fsck, -passwd, -info, -init.

In -reverse mode, this also changes what the encrypted view contains: by
default the config is exposed there as a virtual gocryptfs.conf (so a backup
of the encrypted view is self-contained), but with -config no gocryptfs.conf
is presented. Make sure to back up the config file (or the master key) from its
custom location separately, otherwise the encrypted data cannot be decrypted.
If the custom config file is located inside CIPHERDIR, it is hidden from the
encrypted view rather than exposed in encrypted form.

-cpuprofile string

Write cpu profile to specified file.

Applies to: all actions.

-d, -debug

Enable debug output.

Applies to: all actions.

-extpass CMD [-extpass ARG1 ...]

Use an external program (like ssh-askpass) for the password prompt.
The program should return the password on stdout, a trailing newline is
stripped by gocryptfs. If you just want to read from a password file, see -passfile.

When -extpass is specified once, the string argument will be split on spaces.
For example, -extpass "md5sum my password.txt" will be executed as
"md5sum" "my" "password.txt", which is NOT what you want.

Specify -extpass twice or more to use the string arguments as-is.
For example, you DO want to call md5sum like this:
-extpass "md5sum" -extpass "my password.txt".

If you want to prevent splitting on spaces but don't want to pass arguments
to your program, use "--", which is accepted by most programs:
-extpass "my program" -extpass "--"

Applies to: all actions that ask for a password.

BUG: In -extpass -X, the -X will be interpreted as --X. Please use
-extpass=-X to prevent that. See Dash duplication in the BUGS section
for details.

-fido2 DEVICE_PATH

Use a FIDO2 token to initialize and unlock the filesystem.
Use fido2-token -L to obtain the FIDO2 token device path.
For linux, fido2-tools package is needed.

Applies to: all actions that ask for a password.

-fido2-assert-option OPTION

Options passed to fido2-assert with -t option.
This option may be specified multiple times, each time it will add two
arguements -t OPTION to fido2-assert.
See man fido2-assert to check supported options.

Examples:

Creating a filesystem with no pin verification:

text
gocryptfs -init -fido2 DEVICE_PATH -fido2-assert-option pin=false CIPHERDIR

Creating a filesystem with both user verification and pin verification:

text
gocryptfs -init -fido2 DEVICE_PATH -fido2-assert-option uv=true -fido2-assert-option pin=true CIPHERDIR

Creating a filesystem with both user presence and user verification:

text
gocryptfs -init -fido2 DEVICE_PATH -fido2-assert-option up=true -fido2-assert-option uv=true CIPHERDIR

-masterkey string

Use an explicit master key specified on the command line or, if the special
value "stdin" is used, read the masterkey from stdin, instead of reading
the config file and asking for the decryption password.

Note that the command line, and with it the master key, is visible to
anybody on the machine who can execute "ps -auxwww". Use "-masterkey=stdin"
to avoid that risk.

The masterkey option is meant as a recovery option for emergencies, such as
if you have forgotten the password or lost the config file.

Even if a config file exists, it will not be used. All non-standard
settings have to be passed on the command line: -aessiv when you
mount a filesystem that was created using reverse mode, or
-plaintextnames for a filesystem that was created with that option.

Example 1: Mount a filesystem that was created using default options:

text
gocryptfs -masterkey=6f717d8b-6b5f8e8a-fd0aa206-778ec093-62c5669b-abd229cd-241e00cd-b4d6713d cipher mnt
gocryptfs -masterkey=stdin cipher mnt

Example 2: Mount a gocryptfs -reverse filesystem (note that you must specify -aessiv):

text
gocryptfs -masterkey=stdin -aessiv cipher mnt

Applies to: all actions that ask for a password.

-memprofile string

Write memory profile to the specified file. This is useful when debugging
memory usage of gocryptfs.

Applies to: all actions.

-o COMMA-SEPARATED-OPTIONS

For compatibility with mount(1), options are also accepted as
"-o COMMA-SEPARATED-OPTIONS" at the end of the command line.
For example, "-o q,zerokey" is equivalent to passing "-q -zerokey".

Note that you can only use options that are understood by gocryptfs
with "-o". If you want to pass special flags to the kernel, you should
use "-ko" (kernel option). This is different in libfuse-based
filesystems, that automatically pass any "-o" options they do not
understand along to the kernel.

Example:

text
gocryptfs /tmp/foo /tmp/bar -o q,zerokey

Applies to: all actions.

-openssl bool/"auto"

Use OpenSSL instead of built-in Go crypto (default "auto"). Using
built-in crypto is 4x slower unless your CPU has AES instructions and
you are using Go 1.6+. In mode "auto", gocrypts chooses the faster
option.

Applies to: all actions.

-passfile FILE [-passfile FILE2 ...]

Read password from the specified plain text file. The file should contain exactly
one line (do not use binary files!).
A warning will be printed if there is more than one line, and only
the first line will be used. A single
trailing newline is allowed and does not cause a warning.

Pass this option multiple times to read the first line from multiple
files. They are concatenated for the effective password.

Example:

text
echo hello > hello.txt
echo world > world.txt
gocryptfs -passfile hello.txt -passfile world.txt

The effective password will be "helloworld".

Applies to: all actions that ask for a password.

-q, -quiet

Quiet - silence informational messages.

Applies to: all actions.

-scryptn int

gocryptfs uses scrypt for hashing the password when mounting,
which protects from brute-force attacks.

-scryptn controls the scrypt cost parameter "N" expressed as scryptn=log2(N).
Possible values are -scryptn=10 to -scryptn=28, representing N=2^10 to N=2^28.

Setting this to a lower
value speeds up mounting and reduces its memory needs, but makes
the password susceptible to brute-force attacks. The default is 16.

The memory usage for scrypt during mounting is as follows:

text
scryptn     Memory Usage  
=======     ============
10          1   MiB
11          2 
12          4 
13          8 
14          16  
15          32  
16          64  
17          128 
18          256 
19          512 
20          1   GiB
21          2 
22          4 
23          8 
24          16  
25          32  
26          64  
27          128 
28          256

Applies to: -init, -passwd

See also: the benchmarks in the gocryptfs source code in internal/configfile.

-trace string

Write execution trace to file. View the trace using "go tool trace FILE".

Applies to: all actions.

-wpanic

When encountering a warning, panic and exit immediately. This is
useful in regression testing.

Applies to: all actions.

\-\-

Stop option parsing. Helpful when CIPHERDIR may start with a
dash "-".

Applies to: all actions.

EXCLUDING FILES

In reverse mode, it is possible to exclude files from the encrypted view, using
the -exclude, -exclude-wildcard and -exclude-from options.

-exclude matches complete paths, so -exclude file.txt only excludes a file
named file.txt in the root of the mounted filesystem; files named file.txt
in subdirectories are still visible. Wildcards are NOT supported.
This option is kept for compatibility with the behavior up to version 1.6.x.
New users should use -exclude-wildcard instead.

-exclude-wildcard uses gitignore syntax and matches files anywhere, so -exclude-wildcard file.txt
excludes files named file.txt in any directory. If you want to match complete
paths, you can prefix the filename with a /: -exclude-wildcard /file.txt
excludes only file.txt in the root of the mounted filesystem.

If there are many exclusions, you can use -exclude-from to read gitignore
patterns from a file. As with -exclude-wildcard, use a
leading / to match complete paths.

The rules for exclusion are that of gitignore.
In short:

  1. A blank line matches no files, so it can serve as a separator
    for readability.
  2. A line starting with # serves as a comment. Put a backslash (\)
    in front of the first hash for patterns that begin with a hash.
  3. Trailing spaces are ignored unless they are quoted with backslash (\).
  4. An optional prefix ! negates the pattern; any matching file
    excluded by a previous pattern will become included again. It is not
    possible to re-include a file if a parent directory of that file is
    excluded. Put a backslash (\) in front of the first ! for
    patterns that begin with a literal !, for example, \!important!.txt.
  5. If the pattern ends with a slash, it is removed for the purpose of the
    following description, but it would only find a match with a directory.
    In other words, foo/ will match a directory foo and paths underneath it,
    but will not match a regular file or a symbolic link foo.
  6. If the pattern does not contain a slash /, it is treated as a shell glob
    pattern and checked for a match against the pathname relative to the
    root of the mounted filesystem.
  7. Otherwise, the pattern is treated as a shell glob suitable for
    consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the
    pattern will not match a / in the pathname. For example,
    Documentation/*.html matches Documentation/git.html but not
    Documentation/ppc/ppc.html or tools/perf/Documentation/perf.html.
  8. A leading slash matches the beginning of the pathname. For example,
    /*.c matches cat-file.c but not mozilla-sha1/sha1.c.
  9. Two consecutive asterisks (**) in patterns matched against full
    pathname may have special meaning:
    i. A leading ** followed by a slash means match in all directories.
    For example, **/foo matches file or directory foo anywhere,
    the same as pattern foo. **/foo/bar matches file or directory
    bar anywhere that is directly under directory foo.

    ii. A trailing /** matches everything inside. For example, abc/**
    matches all files inside directory abc, with infinite depth.

    iii. A slash followed by two consecutive asterisks then a slash matches
    zero or more directories. For example, a/**/b matches a/b,
    a/x/b, a/x/y/b and so on.

    iv. Other consecutive asterisks are considered invalid.

EXAMPLES

Init

Create an encrypted filesystem in directory "mydir.crypt", mount it on "mydir":

text
mkdir mydir.crypt mydir
gocryptfs -init mydir.crypt
gocryptfs mydir.crypt mydir

Mount

Mount an encrypted view of joe's home directory using reverse mode:

text
mkdir /home/joe.crypt
gocryptfs -init -reverse /home/joe
gocryptfs -reverse /home/joe /home/joe.crypt

fstab

Adding this line to /etc/fstab will mount /tmp/cipher to /tmp/plain on boot, using the
password in /tmp/passfile. Use sudo mount -av to test the line without having
to reboot. Adjust the gocryptfs path acc. to the output of the command which gocryptfs.
Do use the nofail option to prevent an unbootable system if the gocryptfs mount fails (see
the -nofail option for details).

text
/tmp/cipher /tmp/plain fuse./usr/local/bin/gocryptfs nofail,allow_other,passfile=/tmp/password 0 0

ENVIRONMENT VARIABLES

NO_COLOR

If NO_COLOR is set (regardless of value), colored output is disabled (see https://no-color.org/).

EXIT CODES

0: success
6: CIPHERDIR is not an empty directory (on "-init")
10: MOUNTPOINT is not an empty directory
12: password incorrect
22: password is empty (on "-init")
23: could not read gocryptfs.conf
24: could not write gocryptfs.conf (on "-init" or "-password")
26: fsck found errors
other: please check the error message

See also: https://github.com/rfjakob/gocryptfs/blob/master/internal/exitcodes/exitcodes.go

BUGS

Dash duplication

gocryptfs v2.1 switched to the pflag library for command-line parsing
to support flags and positional arguments in any order. To stay compatible
with single-dash long options like -extpass, an ugly hack was added:
The command line is preprocessed, and all single-dash options are converted to
double-dash.

Unfortunately, this means that in

text
gocryptfs -extpass myapp -extpass -X

gocryptfs transforms the -X to --X, and it will call myapp --X as the extpass program.

Please use

text
gocryptfs -extpass myapp -extpass=-X

to work around this bug.

SEE ALSO

mount(2) fuse(8) fallocate(2) encfs(1) gitignore(5)


Documentation SECURITY (`Documentation/SECURITY.md`)

This page has been moved to https://nuetzlich.net/gocryptfs/security/ .


Documentation XFSTESTS (`Documentation/XFSTESTS.md`)

xfstests results

Results of running fuse-xfstests
against gocryptfs.

Failures

generic/035

Known issue in the
go-fuse library. Unlikely to have real-world impact.

generic/062

Only user.\* xattrs are supported, others are rejected.

generic/093

security.\* xattrs are not supported.

generic/097

trusted.\* xattrs are not supported.

generic/228

ulimit -f is not implemented in gocryptfs.

generic/273

Needs further analysis:

text
_porter 28 not complete
cp: cannot create regular file '/var/tmp/check-gocryptfs/scratchdir/sub_28/origin/file_548': No such file or directory

generic/403

trusted.\* xattrs are not supported.

generic/426, generic/467, generic/477

Needs further analysis.

Failure related to the new system call open_by_handle_at(2)
(lwn article).

generic/466

Harmless output caused by the fact that gocryptfs is not backed by
a block device.

generic/484

Needs further analysis: record lock is not preserved across execve(2)

generic/488

Needs further analysis: Too many open files

Full Test Output

text
/* Detailed source-code truncated for AI context efficiency. */

Documentation Duplicate Inodes (`Documentation/duplicate-inodes.txt`)

ls: cannot access foo: No such file or directory
ls: cannot access foo: No such file or directory
ls: cannot access foo: No such file or directory
ls: cannot access foo: No such file or directory
36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo
36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo
36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo
36962337 -rwxrwxrwx 1 u1026 users 0 Nov 11 18:00 foo

u1026@d8min:/mnt/synology/public/tmp/g1$ strace -e lstat -p 8899 -f
Process 8899 attached with 10 threads
2017/11/11 18:12:21 Dispatch 238: LOOKUP, NodeId: 1. names: [foo] 4 bytes
[pid 10539] lstat("/mnt/synology/public/tmp/g1/a/4DZNVle_txclugO7n_FRIg", 0xc4241adbe8) = -1 ENOENT (No such file or directory)
2017/11/11 18:12:21 Serialize 238: LOOKUP code: OK value: {NodeId: 0 Generation=0 EntryValid=1.000 AttrValid=0.000 Attr={M00 SZ=0 L=0 0:0 B00 i0:0 A 0.000000000 M 0.000000000 C 0.000000000}}
2017/11/11 18:12:22 Dispatch 239: LOOKUP, NodeId: 1. names: [foo] 4 bytes
[pid 8903] lstat("/mnt/synology/public/tmp/g1/a/Xsy8mhdcIh0u9aiI7-iLiw", {st_mode=S_IFREG|0777, st_size=0, ...}) = 0
2017/11/11 18:12:22 Serialize 239: LOOKUP code: OK value: {NodeId: 3 Generation=4 EntryValid=1.000 AttrValid=1.000 Attr={M0100777 SZ=0 L=1 1026:100 B0
16384 i0:36962337 A 1510419642.457639700 M 1510419642.457639700 C 1510419702.353712800}}

Call Trace:

nodefs/fsops.go (c *rawBridge) Lookup
nodefs/fsops.go (c *FileSystemConnector) internalLookup
nodefs/inode.go (n *Inode) GetChild
pathfs/pathfs.go (n *pathInode) GetAttr
pathfs/pathfs.go (n *pathInode) GetPath
nodefs/inode.go (n *Inode) Parent()
pathfs/loopback.go (fs *loopbackFileSystem) GetAttr

Call Trace 2 (new child):

nodefs/fsops.go (c *rawBridge) Lookup
nodefs/fsops.go (c *FileSystemConnector) internalLookup
pathfs/pathfs.go (n *pathInode) Lookup
pathfs/pathfs.go (n *pathInode) findChild


Documentation Extractloop (`Documentation/extractloop.md`)

extractloop.bash results

Memory usage stabilises at 141MiB, we do not run out of fds,
and the iteration time is stable around 38 seconds:

What the extractloop stress test does is (top comment in tests/stress_tests/extractloop.bash):

text
# Mount a gocryptfs filesystem somewhere on /tmp, then run two parallel
# infinite loops inside that do the following:
# 1) Extract linux-3.0.tar.gz
# 2) Verify the md5sums
# 3) Delete, go to (1)
#
# This test is good at discovering inode-related memory leaks because it creates
# huge numbers of files.

Test output (trimmed for brevity):

text
/* Detailed source-code truncated for AI context efficiency. */

Documentation File Format (`Documentation/file-format.md`)

File Format

Empty files are stored as empty files.

Non-empty files contain a Header and one or more Data blocks.

text
2 bytes header version (big endian uint16, currently 2)
16 bytes file id

Data block, default AES-GCM mode

text
16 bytes GCM IV (nonce)
1-4096 bytes encrypted data
16 bytes GHASH

Overhead = (16+16)/4096 = 1/128 = 0.78125 %

Data block, AES-SIV mode

AES-SIV is used in reverse mode, or when explicitly enabled with -init -aessiv.

text
16 bytes nonce
16 bytes SIV
1-4096 bytes encrypted data

Overhead = (16+16)/4096 = 1/128 = 0.78125 %

Data block, XChaCha20-Poly1305

Enabled via -init -xchacha

text
24 bytes nonce
1-4096 bytes encrypted data
16 bytes Poly1305 tag

Overhead = (24+16)/4096 = 0.98 %

Examples

0-byte file (all modes)

text
(empty)

Total: 0 bytes

1-byte file, AES-GCM and AES-SIV mode

text
Header     18 bytes
Data block 33 bytes

Total: 51 bytes

5000-byte file, , AES-GCM and AES-SIV mode

text
Header       18 bytes
Data block 4128 bytes
Data block  936 bytes

Total: 5082 bytes

1-byte file, XChaCha20-Poly1305 mode

text
Header     18 bytes
Data block 41 bytes

Total: 59 bytes

5000-byte file, XChaCha20-Poly1305 mode

text
Header       18 bytes
Data block 4136 bytes
Data block  944 bytes

Total: 5098 bytes

See Also

https://nuetzlich.net/gocryptfs/forward_mode_crypto/ / https://github.com/rfjakob/gocryptfs-website/blob/master/docs/forward_mode_crypto.md


Documentation Performance Reverse (`Documentation/performance-reverse.txt`)

Results from benchmark-reverse.bash

VERSION LS CAT ENV


v1.3 2.1 19.9 go1.9.2
v1.4 2.1 18.2
v1.5 3.4 19.6 go1.10.3, Linux 4.17.12
v1.6 3.6 19.9 go1.10.3, Linux 4.17.12

(seconds)


Documentation Performance (`Documentation/performance.txt`)

Tests of gocryptfs v1.7 and later are run on an
Intel Core i5-3470 CPU (quad-core Ivy Bridge, AES-NI supported).
Earlier tests on a Pentium G630 (Dual-core Sandy Bridge, no AES-NI).

The working directory is on tmpfs.
The untar test uses https://cdn.kernel.org/pub/linux/kernel/v3.0/linux-3.0.tar.gz .
The archive is placed on tmpfs as well.

WRITE: dd if=/dev/zero of=zero bs=131072 count=2000
READ: dd if=zero of=/dev/null bs=131072 count=2000
UNTAR: time tar xzf ../linux-3.0.tar.gz
MD5: time md5sum --quiet -c linux-3.0.md5sums
LS: time ls -lR linux-3.0 > /dev/null
RM: time rm -Rf linux-3.0

(or just run benchmark.bash)

VERSION WRITE READ UNTAR MD5 LS RM ENV CHANGE? COMMIT MSG


  • CPU = Pentium G630 *

v0.4 48 1.5 5
v0.5-rc1 56 7 19
v0.5-rc1-1 54 4.1 9
v0.5-rc1-2 45 1.7 3.4
v0.6 47 1.8 4.3
v0.7 43 1.7 4.3
v0.7.2 26 1.8 4.3
v0.8 23 1.8 4.3
v0.9-rc2 94 24 1.8 4.5
v0.9 94 24 1.8 4.5
v0.11 104 22 1.7 4.5
v1.1 104 20 1.5 3.4 go1.7.1
v1.1.1-34 112 22 1.5 3.6 go1.7.3
v1.2.1-33 112 21 12 1.6 4.4 go1.8
-serialize_reads 116 21 39 1.5 4.4 (v1.2.1-33 with -serialize_reads)
v1.3-27 113 20 11 1.4 4.2
v1.3-53-gf44902a 119 19 12 1.6 4.1
v1.3-64-g80516ed 123 19 11 1.3 4.2
v1.3-67-g9837cb0 125 19 11 1.4 4.2 go1.8.3, Linux 4.10
v1.3-69-ge52594d 145 19.0 11.6 1.4 4.1
v1.4-1-g3c6fe98 154 17.2 11.7 1.4 4.1
v1.4-5-g0cc6f53 182 144 16.7 11.1 1.3 3.3
v1.4-8-g80676c6 178 148 16.1 11.0 1.3 4.0
v1.4-14-g9f4bd76 182 286 15.4 7.5 1.3 4.1
v1.4-45-gd5671b7 183 282 14.9 7.3 1.1 2.9
v1.4-45-gd5671b7 252 285 15.5 7.2 1.1 2.9 go1.8.3, Linux 4.11
v1.4.1 253 285 16.0 7.4 1.3 3.0 go1.9, Linux 4.12.5
v1.4.1-6-g276567e 258 289 16.1 7.5 1.3 3.0
v1.5 228 292 17.6 9.3 1.5 3.5 go1.10.2, Linux 4.16.8
v1.6 250 289 17.7 8.0 1.3 3.2 go1.10.3, Linux 4.17.12
v1.7-beta1 229 278 17.1 8.8 1.7 3.2 go1.11.4, Linux 4.19.12
v1.7-rc1 226 289 17.6 8.9 1.7 2.9


  • CPU = Core i5-3470, governor = powersave *

v1.7 232 698 12.2 9.4 1.7 4.3 go1.12.9, Linux 5.2.17
v1.7.1 450 697 11.5 9.5 1.5 3.6


  • CPU = Core i5-3470, governor = performance *

v1.7.1 556 1000 9.0 4.2 0.9 2.0 go1.13.6, Linux 5.4.17
v1.7.1 577 1100 8.3 4.2 0.9 2.0 go1.14.2, Linux 5.6.7
v1.7.1-60-gb23f77c 472 1100 12.7 4.2 0.8 2.0
v1.8.0 410 1000 17.5 6.7 5.4 7.8 go1.15.3, Linux 5.8.13
v2.0-beta1 387 1100 36.2 14.4 12.8 19.3
v2.0-beta1-5-gc943ed3 417 1000 30.4 12.7 9.9 16.4
v2.0-beta1-6 529 1100 17.5 9.0 3.6 9.0
v2.0-beta1-9-g029e44d 477 1000 15.5 8.7 2.8 7.6
v2.0-beta2-16-geaca820 542 997 15.9 8.8 6.2 7.8 go1.16.2, Linux 5.11.10 fusefrontend: do not encrypt ACLs
v2.0-beta2-36-g6aae2aa 505 1000 16.1 8.2 6.3 7.7
v2.0-beta2-37-g24d5d39 558 1000 12.3 6.4 4.4 2.8 fs: add initial dirfd caching
v2.0-beta2-42-g4a07d65 549 1000 8.2 4.7 1.8 2.4 fusefrontend: make dirCache work for "node itself"
v2.0 420 1000 8.5 4.5 1.8 2.3 go1.16.5, Linux 5.11.21
v2.0.1-28-g49507ea 471 991 8.6 4.5 1.7 2.2
v2.0.1-28-g49507ea 335 951 10.2 5.4 4.1 2.0 go1.25.4, Linux 6.18.6
v2.6.1-22-gbc94538 432 950 10.0 5.4 3.8 2.0
v2.6.1-24-gb239d51 426 941 9.9 5.5 3.7 2.0 go-fuse v2.9.0
v2.6.1-26-g700432e 461 962 9.8 5.4 2.0 2.0
v2.6.1-71-g5b2881e7 449 964 10.5 5.6 2.4 2.6 use READDIR by default

Results for EncFS for comparison (benchmark.bash -encfs):

VERSION WRITE READ UNTAR MD5 LS RM


  • CPU = Pentium G630 *

encfs v1.9.1 95 20 8 2.8 3.8


  • CPU = Core i5-3470, governor = performance *

encfs v1.9.5 138 459 12.2 5.1 2.2 3.0


Documentation Pjdfstest (`Documentation/pjdfstest.md`)

How to run

text
$ sudo gocryptfs --allow_other a b 
$ cd b
$ sudo prove -r /home/jakob/code/pjdfstest/test

Version Info

https://github.com/pjd/pjdfstest @ 8a2adf0

text
$ gocryptfs --version
gocryptfs v2.6.1-46-gf76f8a2a; go-fuse v2.9.0; 2026-07-15 go1.25.4 linux/amd64

Results

text
/* Detailed source-code truncated for AI context efficiency. */

Failure Details

text
/* Detailed source-code truncated for AI context efficiency. */
text
root@brikett:/var/tmp/g/b# prove -v /home/jakob/code/pjdfstest/tests/utimensat/05.t
/home/jakob/code/pjdfstest/tests/utimensat/05.t .. 
1..16
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
not ok 7 - tried 'lstat pjdfstest_f1cd2b8794f82da55def3ffa9af7556f atime', expected 1960000000, got 1784144798
ok 8
ok 9
ok 10
ok 11
ok 12
ok 13
ok 14
ok 15
ok 16
Failed 1/16 subtests 

Test Summary Report
-------------------
/home/jakob/code/pjdfstest/tests/utimensat/05.t (Wstat: 0 Tests: 16 Failed: 1)
  Failed test:  7
Files=1, Tests=16,  0 wallclock secs ( 0.03 usr  0.00 sys +  0.04 cusr  0.07 csys =  0.14 CPU)
Result: FAIL

--- METRICS ---