├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── custom_theme ├── breadcrumbs.html └── versions.html ├── docs ├── comparison.md ├── compile.md ├── contribute.md ├── forward_mode_crypto.md ├── img │ ├── derived-keys.svg │ ├── favicon.ico │ ├── file-content-encryption.svg │ ├── file-name-encryption.svg │ ├── folders-side-by-side.gif │ ├── gocryptfs-logo.paths-black.svg │ ├── gocryptfs-logo.paths-white.svg │ ├── gocryptfs-logo.paths.svg │ ├── gocryptfs-logo.text.svg │ ├── longnames.svg │ ├── master-key.svg │ ├── reverse-derivePathIV.svg │ └── reverse-file-content-encryption.svg ├── index.md ├── mirrors.md ├── quickstart.md ├── releases.md ├── reverse_mode_crypto.md ├── style.css └── threat_model.md ├── htaccess └── mkdocs.yml /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | pull_request: 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - run: pip3 install mkdocs==1.6.1 11 | - run: make 12 | - uses: actions/upload-artifact@v4 13 | with: 14 | name: site 15 | path: site 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /site 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | install: 5 | - pip install mkdocs==0.17.5 6 | script: 7 | - mkdocs -V 8 | - make 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015 Jakob Unterwurzacher 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | LC_ALL=C.UTF-8 LANG=C.UTF-8 mkdocs build --clean --quiet 3 | cp -af htaccess site/.htaccess 4 | 5 | .PHONY: clean 6 | clean: 7 | rm -Rf site 8 | 9 | .PHONY: test 10 | test: 11 | curl -sSf -o /dev/null https://nuetzlich.net/gocryptfs 12 | # These should redirect to the new names 13 | curl -sSf -o /dev/null https://nuetzlich.net/gocryptfs/security 14 | curl -sSf -o /dev/null https://nuetzlich.net/gocryptfs/reverse_mode 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CI](https://github.com/rfjakob/gocryptfs-website/actions/workflows/ci.yml/badge.svg)](https://github.com/rfjakob/gocryptfs-website/actions/workflows/ci.yml) 2 | 3 | This repostitory contains the gocryptfs website that is available at 4 | https://nuetzlich.net/gocryptfs . 5 | 6 | It is generated using mkdocs. Install using 7 | 8 | pip3 install mkdocs==1.6.1 9 | 10 | -------------------------------------------------------------------------------- /custom_theme/breadcrumbs.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfjakob/gocryptfs-website/825f43805c047f4ddaa5628adc417b48458fd489/custom_theme/breadcrumbs.html -------------------------------------------------------------------------------- /custom_theme/versions.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | gocryptfs 6 | 7 | 8 | 9 | gocryptfs-website 10 | 11 | 12 | 13 |
14 | -------------------------------------------------------------------------------- /docs/comparison.md: -------------------------------------------------------------------------------- 1 | Other Projects 2 | ============== 3 | 4 | There are several open-source file encryption solutions for Linux available. In contrast 5 | to disk-encryption software that operate on whole disks (TrueCrypt, dm-crypt etc), file 6 | encryption operates on individual files that can be backed up or synchronised easily. 7 | 8 | This page compares: 9 | 10 | * [gocryptfs](https://nuetzlich.net/gocryptfs/) (this project), aspiring successor of EncFS 11 | * [EncFS](https://github.com/vgough/encfs), mature with known security issues 12 | * [eCryptFS](http://ecryptfs.org/), integrated into the Linux kernel 13 | * [Cryptomator](https://cryptomator.org/), strong cross-platform support through Java, WebDAV and [FUSE](https://github.com/SerCeMan/jnr-fuse). 14 | * [securefs](https://github.com/netheril96/securefs), a cross-platform project implemented in C++. 15 | Older versions stored directories in user-space B-trees 16 | ([filesystem format 1,2,3](https://github.com/netheril96/securefs/blob/2596467d63631aab264cf7a63de38fd69b2fda78/docs/design.md#full-format-format-version-123)). 17 | The new default since v0.7.0 18 | ([filesystem format 4](https://github.com/netheril96/securefs/blob/2596467d63631aab264cf7a63de38fd69b2fda78/docs/design.md#lite-format-format-version-4)) 19 | uses normal directory entries. 20 | * [CryFS](https://www.cryfs.org/), result of a master thesis at the KIT University that uses 21 | chunked storage to obfuscate file sizes. 22 | 23 | If you spot an error or want to see a project added, please 24 | [file a ticket](https://github.com/rfjakob/gocryptfs-website)! See also: [comparison table in the Arch Linux wiki](https://wiki.archlinux.org/title/Data-at-rest_encryption#Comparison_table) 25 | 26 | Overview 27 | -------- 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 |
gocryptfs
v1.7
encfs
v1.9.5
ecryptfs
v4.19.0
cryptomator
v1.4.6
securefs
v0.8.3
CryFS
v0.10.0
First release2015 (ref) 2003 (ref) 2006 (ref) 2014 (ref) 2015 (ref) 2015 (ref)
LanguageGoC++CJavaC++C++
LicenseMIT (ref) LGPLv3 / GPLv3 (ref) GPLv2GPLv3 (ref) MIT (ref) LGPLv3 (ref)
Development hotspotAustriaUSAUSA (RedHat)GermanyChinaGermany
LifecycleActiveMaintenanceActive (ref) ActiveActiveActive
File interfaceFUSEFUSEIn-kernel filesystemFUSE/WebDAVFUSEFUSE
PlatformsLinux, MacOS, 3rd-party Windows port cppcryptfs, 101 | 3rd-party Android port DroidFSLinux, MacOS, 3rd-party Windows portLinuxLinux, MacOS, WindowsLinux, MacOS, WindowsLinux, MacOS, Windows (experimental)
User interfaceCLI, 3rd-party GUI (SiriKali)CLI, 3rd-party GUIIntegrated in login processGUI, 3rd-party CLI (ref) CLI, 3rd-party GUICLI, 3rd-party GUI (SiriKali)
Reverse Modeyes (since v1.1, read-only)yes (limited write support)nononono
127 | 128 | General Security 129 | ---------------- 130 | 131 | | | gocryptfs | encfs default | encfs paranoia | ecryptfs | cryptomator | securefs | CryFS | 132 | | ----------------------- | --------- | ------------- | -------------- | ------------------------------------ | ----------- | -------- | ------- | 133 | | Documentation available | Yes [1] | Yes [2] | Yes [2] | No [4] | Yes [3] | Yes [5] | Yes [6] | 134 | | Password hashing | scrypt | PBKDF2 | PBKDF2 | (none, implemented in external tool) | scrypt | PBKDF2 | scrypt | 135 | 136 | 137 | References: 138 | [[1]](forward_mode_crypto.md) 139 | [[2]](https://github.com/vgough/encfs/blob/439c90e040cc04c036ee0791d830779a6d6bf10e/DESIGN.md) 140 | [[3]](https://cryptomator.org/architecture/) 141 | [[5]](https://github.com/netheril96/securefs/blob/2596467d63631aab264cf7a63de38fd69b2fda78/docs/design.md#lite-format-format-version-4) 142 | [[6]](https://www.cryfs.org/howitworks) 143 | [[4]](http://ecryptfs.org/documentation.html) actually, there is a lot of ecryptfs documentation, but none of 144 | it seems to describe the used crypto. 145 | 146 | File Contents 147 | ------------- 148 | 149 | | | gocryptfs | encfs default | encfs paranoia | ecryptfs | cryptomator | securefs | CryFS | 150 | | --------------------- | --------- | ----------------------- | ----------------------- | --------------------- | ---------------------- | ---------| --------------------- | 151 | | Tested version | v1.7 | v1.9.5 | v1.9.5 | v4.19.0 | v1.4.6 | v0.8.3 | 0.10.0 | 152 | | | | | | | | | | 153 | | Encryption | GCM [1] | CBC; last block CFB [2] | CBC; last block CFB [2] | CBC | CTR with random IV [3] | GCM | GCM | 154 | | Integrity | GCM | none | HMAC | none | HMAC | GCM | GCM | 155 | | File size obfuscation | no | no | no | yes (4 KB increments) | no [4] | no [5] | yes (chunked storage) | 156 | 157 | References: 158 | [[1]](https://github.com/rfjakob/gocryptfs/blob/master/Documentation/file-format.md#file-format) 159 | [[2]](https://github.com/vgough/encfs/issues/9) 160 | [[3]](https://github.com/cryptomator/cryptomator/issues/128#issuecomment-168942517) 161 | [[4]](https://github.com/cryptomator/cryptomator/releases/tag/1.2.0) 162 | [[5]](https://github.com/netheril96/securefs/issues/39) 163 | 164 | File Names 165 | ---------- 166 | 167 | | | gocryptfs | encfs default | encfs paranoia | ecryptfs | cryptomator | securefs | CryFS | 168 | | ------------------------ | --------------------- | -------------------- | -------------------- | -------- | ------------ | ------------------ | ------------------ | 169 | | Tested version | v1.4.1 | v1.9.2 | v1.9.2 | v4.12.5 | v1.5.15 AppImage FUSE | v0.7.3-30-g2596467 | 0.9.7-15-g3d52f6a8 | 170 | | | | | | | | | | 171 | | Encryption | EME [4] | CBC | CBC | CBC | AES-SIV | AES-SIV | GCM (dir DB) | 172 | | Prefix leak | no (EME) | no (HMAC used as IV) | no (HMAC used as IV) | yes [2] | no (AES-SIV) | no (AES-SIV) | no (GCM) | 173 | | Identical names leak | no (per-directory IV) | no (path chaining) | no (path chaining) | yes [1] | no [3] {3} | yes [6] | no (GCM) | 174 | | Maximum name length [5] | 255 (since v0.9) {2} | 175 | 175 | 143 | 1024 | 143 | 1024 | 175 | | Maximum path length [5] | 4095 | | | | 4095 | | | 176 | | Directory flattening {1} | no | no | no | no | yes | yes | yes | 177 | 178 | References: 179 | [[1]](https://gist.github.com/rfjakob/a04364c55b3ee231078d) 180 | [[2]](https://gist.github.com/rfjakob/61a17bf3c7eb9932d791) 181 | [[3]](https://github.com/cryptomator/cryptomator/commit/3b178030c7a6001c1d070ee181aaae71f760d33f) 182 | [[4]](https://github.com/rfjakob/eme) 183 | [[5]](https://github.com/rfjakob/gocryptfs/blob/master/contrib/maxlen.bash) 184 | [[6]](https://gist.github.com/rfjakob/5ff1591db263d85684ac03fc47009b35) 185 | 186 | 187 | Notes: 188 | {1} Is the directory tree flattened in the encrypted storage? This 189 | obfuscates the directory structure but can cause problems when 190 | synchronising via Dropbox and similar. 191 | {2} 255 since gocryptfs v0.9, 175 in v0.8 and earlier 192 | {3} cryptomator dropped the use of a random padding in v1.2.0 due to performance concerns. 193 | 194 | Performance on Linux 195 | -------------------- 196 | 197 | All tests are run on tmpfs rule out any influence of the hard disk. 198 | The exact command lines for running the tests are defined in 199 | [canonical-benchmarks.bash](https://github.com/rfjakob/gocryptfs/blob/f0e29d9b90b63d5fbe4164161ecb0e1035bb4af4/tests/canonical-benchmarks.bash). 200 | The box that was used to running the tests has been 201 | upgraded with a new CPU {2}, and unfortunately not all tests have been re-run. 202 | Which CPU was used is noted in the table header. 203 | 204 | | | gocryptfs {2} | encfs default {2} | encfs paranoia {1} | ecryptfs {2} | cryptomator {2} | securefs {1} | CryFS {1} | 205 | | ------------------------ | ----------------- | ------------- | ------------------ | --------- | ------------- | ------------------ | ------------------- | 206 | | Tested version | v2.3.2-3-g1a866b7 | v1.9.5 | v1.9.2 | v6.2.13 | v1.5.15 AppImage FUSE | v0.7.3-30-g2596467 | v0.9.7-12-gd9634246 | 207 | | | | | | | | | | 208 | | Streaming write | 482 MiB/s | 122 MiB/s | 51 MiB/s | 323 MiB/s | 57 MiB/s | 132 MiB/s | 69 MiB/s | 209 | | Streaming read | 944 MiB/s | 451 MiB/s | 105 MiB/s | 961 MiB/s | 113 MiB/s | 155 MiB/s | 99 MiB/s | 210 | | Extract linux-3.0.tar.gz | 10.9 s | 13 s | 23 s | 3.9 s | 28 s | 14 s | 41 s | 211 | | md5sum linux-3.0 | 5.1 s | 5.7 s | 10 s | 1.2 s | 15 s | 7.7 s | 42 s | 212 | | ls -lR linux-3.0 | 2.0 s | 2.5 s | 2.9 s | 0.5 s | 4.3 s | 1.2 s | 17 s | 213 | | Delete linux-3.0 | 2.4 s | 3.4 s | 4.4 s | 0.7 s | 10 s | 2.2 s | 21 s | 214 | 215 | Notes: 216 | {1} Tested on an Intel Pentium G630 with 2 x 2.7GHz that does NOT have AES instructions
217 | {2} Tested in Intel Core i5-3470 CPU with 4 x 3.20GHz and AES-NI
218 | 219 | Performance on Windows 220 | ---------------------- 221 | 222 | All tests were run on a Toshiba-RD400 M.2/NVMe SSD rated 2.6 GB/s read and 1.6 GB/s write random-access speed. 223 | The operating system used was Windows 7 Professional SP1 running on an Intel Core i7-6700 CPU with 4 x 3.40GHz hyperthreaded and AES-NI. 224 | Tests were run using MSYS-CoreUtils 5.97-3-msys-1.0.13 installed using the MinGW installer. The exact command lines for running the tests are defined in 225 | [canonical-benchmarks.bash](https://github.com/rfjakob/gocryptfs/blob/f0e29d9b90b63d5fbe4164161ecb0e1035bb4af4/tests/canonical-benchmarks.bash) with minor 226 | adjustments required to make the test run in this environment. 227 | 228 | 229 | | | (NTFS) | cppcryptfs | EncFSMP default | EncFS4Win default | cryptomator | securefs | CryFS | 230 | | ------------------------ | --------------- | ------------------------ | ----------------- | ----------------- | ----------------- | ------------- | ----------------- | 231 | | Tested version | v6.1.7601.24382 | v1.4.0.25 | v0.99.1 | v1.10.1-rc14 | v1.4.6 | v0.8.3 | v0.10.0.1201 {1} | 232 | | Based on | - | gocryptfs 1.4 compatible | EncFS 1.9.5 | EncFS 1.9.1 | - | - | - | 233 | | Driver | (Built-in) | Dokany 1.2.2.1000 | PFM 1.0.0.192 {2} | Dokany 1.2.2.1000 | Dokany 1.2.2.1000 | WinFSP 2019.1 | Dokany 1.2.2.1000 | 234 | | User Interface | - | GUI | GUI
(fails to properly display state) | Tray
(very basic) | GUI | No {3} | No {3} | 235 | | | | | | | | | | 236 | | Streaming write | 2100 MiB/s {4} | 621 MiB/s | 58 MiB/s | 68 MiB/s | 67 MiB/s | 289 MiB/s | 51 MiB/s | 237 | | Streaming read | 3400 MiB/s {4} | 797 MiB/s | 251 MiB/s | 107 MiB/s | 115 MiB/s | 542 MiB/s | 130 MiB/s | 238 | | Extract linux-3.0.tar.gz | 26 s | 456 s | 793 s | 2121 s | 2497 s | 332 s | 1124 s | 239 | | md5sum linux-3.0 | 51 s | 364 s | 235 s | 1877 s | 1808 s | 235 s | 1254 s | 240 | | ls -lR linux-3.0 | 18 s | 328 s | 166 s | 1269 s | 1722 s | 183 s | 1057 s | 241 | | Delete linux-3.0 | 18 s | 432 s | (427 s) {5} | 1666 s | 2765 s | 260 s | 1007 s | 242 | 243 | To the extent this was observed at all during the tests, every one of these 244 | filesystem providers was fully CPU-bound during the small-file tests with 245 | observed disk access speeds never going beyond 15 MiB/s. 246 | 247 | Notes: 248 | {1} CryFS considered Windows support “highly experimental” in this version
249 | {2} Closed source component by Pismo Technic Inc
250 | {3} The SiriKali third-part GUI supports CryFS, EncFS4Win and securefs
251 | {4} Yes, these numbers are actually above what the drive is theoretically capable of, so all of these results are likely somewhat skewed
252 | {5} 320 files were not deleted due to *Invalid argument* errors; it is not clear what caused this error, but the logged “Invalid data size, not multiple of block size” messages may indicate corruption 253 | 254 | Disk Space Efficiency 255 | --------------------- 256 | 257 | | | ext4 | gocryptfs | encfs default | encfs paranoia | ecryptfs | cryptomator | securefs | CryFS | 258 | | ------------------------- | --------- | --------- | ------------- | -------------- | --------- | ----------- | ----------------- | ------------------ | 259 | | Tested version | v4.12.5 | v1.4.1 | v1.9.2 | v1.9.2 | v4.12.5 | v1.5.15 AppImage FUSE | 0.7.3-30-g2596467 | 0.9.7-15-g3d52f6a8 | 260 | | | | | | | | | | | 261 | | Empty file {1} | 0 | 0 | 0 | 0 | 8,192 | 88 | 16 | 32,768 | 262 | | 1 byte file {1} | 1 | 51 | 9 | 17 | 12,288 | 137 | 45 | 32,768 | 263 | | 1,000,000 bytes file {1} | 1,000,000 | 1,007,858 | 1,000,008 | 1,007,888 | 1,011,712 | 1,001,576 | 1,006,876 | 1,048,576 {4} | 264 | | linux-3.0 source tree {5} | | | | | | | | | 265 | | ...disk usage {2} | 494 MiB | 512 MiB | 495 MiB | 498 MiB | 784 MiB | 520 MiB | 498 MiB | 1485 MiB | 266 | | ...sum of file sizes {3} | 411 MiB | 416 MiB | 412 MiB | 415 MiB | 784 MiB | 430 MiB | 416 MiB | 1485 MiB | 267 | 268 | Notes: 269 | {1} `ls -l` on the encrypted file
270 | {2} `du -sm` on the ciphertext dir, backing filesystem ext4.
271 | {3} `du -sm --apparent-size`.
272 | {4} Counting all 32 chunks ([ref](https://gist.github.com/rfjakob/bdd0ef2bd8f0e94b09ad14f85cd6daec))
273 | {5} Extracted [linux-3.0.tar.gz](https://cdn.kernel.org/pub/linux/kernel/v3.0/linux-3.0.tar.gz)
274 | 275 | Filesystem Features 276 | ------------------- 277 | 278 | Note: To keep the work of maintaining this table under control, I have only 279 | tested selected projects with respect to filesystem features. 280 | Please file a pull request if you can test the other projects! 281 | 282 | The backing filesystem is assumed to be ext4. 283 | 284 | | | ext4 | gocryptfs | encfs default | encfs paranoia | ecryptfs | CryFS | 285 | | -------------------- | ---- | --------- | ------------- | -------------- | -------- | ----- | 286 | | hard links | yes | yes | yes | no | yes | no | 287 | | extended attributes | yes | yes {1} | yes {2} | yes {2} | ? | ? | 288 | | fallocate | yes | yes | no | no | no | no | 289 | | fallocate KEEP_SIZE | yes | yes | no | no | no | no | 290 | | fallocate PUNCH_HOLE | yes | no | no | no | no | no | 291 | 292 | Notes:
293 | {1} Names and values encrypted
294 | {2} Not encrypted
295 | -------------------------------------------------------------------------------- /docs/compile.md: -------------------------------------------------------------------------------- 1 | Compile gocryptfs from Source 2 | ============================= 3 | 4 | Install Go 1.13 or higher: 5 | 6 | * Debian/Ubuntu: `apt install golang` 7 | * Fedora: `dnf install golang` 8 | 9 | Then, download the source code and compile: 10 | 11 | $ git clone https://github.com/rfjakob/gocryptfs.git 12 | $ cd gocryptfs 13 | $ ./build-without-openssl.bash 14 | 15 | This will compile a static binary that uses the Go stdlib crypto backend. 16 | 17 | If you want to use the OpenSSL crypto backend (faster on 18 | old CPUs lacking AES-NI), you have to install a few dependencies: 19 | 20 | * Debian/Ubuntu: `apt install libssl-dev gcc pkg-config` 21 | * Fedora: `dnf install openssl-devel gcc pkg-config` 22 | 23 | Then, run: 24 | 25 | $ ./build.bash 26 | 27 | See also: [README.md#compile](https://github.com/rfjakob/gocryptfs/blob/master/README.md#compile) 28 | 29 | Test 30 | ---- 31 | 32 | In the gocryptfs source directory, run: 33 | 34 | ./test.bash 35 | 36 | The tests run about 1 minute and should produce the following output: 37 | 38 | ``` 39 | gocryptfs v1.4.3-9-g9f8d0d8 without_openssl; go-fuse v20170619-28-g19acbd2; 2018-02-03 go1.9.2 40 | gocryptfs v1.4.3-9-g9f8d0d8; go-fuse v20170619-28-g19acbd2; 2018-02-03 go1.9.2 41 | ok github.com/rfjakob/gocryptfs 0.003s 42 | ? github.com/rfjakob/gocryptfs/gocryptfs-xray [no test files] 43 | ok github.com/rfjakob/gocryptfs/internal/configfile 0.732s 44 | ok github.com/rfjakob/gocryptfs/internal/contentenc 0.003s 45 | ok github.com/rfjakob/gocryptfs/internal/cryptocore 0.227s 46 | ok github.com/rfjakob/gocryptfs/internal/ctlsock 0.002s 47 | ? github.com/rfjakob/gocryptfs/internal/exitcodes [no test files] 48 | ? github.com/rfjakob/gocryptfs/internal/fusefrontend [no test files] 49 | ? github.com/rfjakob/gocryptfs/internal/fusefrontend_reverse [no test files] 50 | ok github.com/rfjakob/gocryptfs/internal/nametransform 0.003s 51 | ? github.com/rfjakob/gocryptfs/internal/nametransform/dirivcache [no test files] 52 | ? github.com/rfjakob/gocryptfs/internal/openfiletable [no test files] 53 | ok github.com/rfjakob/gocryptfs/internal/pathiv 0.003s 54 | ok github.com/rfjakob/gocryptfs/internal/prefer_openssl 0.003s 55 | ok github.com/rfjakob/gocryptfs/internal/readpassword 0.048s 56 | ? github.com/rfjakob/gocryptfs/internal/serialize_reads [no test files] 57 | ok github.com/rfjakob/gocryptfs/internal/siv_aead 0.005s 58 | ok github.com/rfjakob/gocryptfs/internal/speed 0.002s [no tests to run] 59 | ok github.com/rfjakob/gocryptfs/internal/stupidgcm 1.639s 60 | ok github.com/rfjakob/gocryptfs/internal/syscallcompat 0.027s 61 | ? github.com/rfjakob/gocryptfs/internal/tlog [no test files] 62 | ok github.com/rfjakob/gocryptfs/tests/cli 1.023s 63 | ok github.com/rfjakob/gocryptfs/tests/defaults 0.839s 64 | ok github.com/rfjakob/gocryptfs/tests/example_filesystems 4.076s 65 | ok github.com/rfjakob/gocryptfs/tests/hkdf_sanity 0.137s 66 | ok github.com/rfjakob/gocryptfs/tests/matrix 10.780s 67 | ok github.com/rfjakob/gocryptfs/tests/plaintextnames 0.089s 68 | ok github.com/rfjakob/gocryptfs/tests/reverse 0.854s 69 | ? github.com/rfjakob/gocryptfs/tests/test_helpers [no test files] 70 | ``` 71 | 72 | You can run `./test.bash -v` to see the execution of individual tests. Note that 73 | the tests also check error cases that produce error messages, and this is not 74 | a test failure. 75 | -------------------------------------------------------------------------------- /docs/contribute.md: -------------------------------------------------------------------------------- 1 | Contributing to gocryptfs 2 | ========================= 3 | 4 | If you want to take part in the gocryptfs projects, there are a few 5 | ways you can contribute: 6 | 7 | Code 8 | ---- 9 | 10 | Check out the open [feature requests](https://github.com/rfjakob/gocryptfs/issues) 11 | (and possibly bugs). There is still a few long-hanging fruits and 12 | assistance is available. 13 | 14 | There are no CLAs to sign or anything, just get going and send a pull 15 | request. You'll probably learn more than you ever wanted to know about 16 | low-level filesystem operations ;) 17 | 18 | Money 19 | ----- 20 | 21 | There are no plans to have a way of donating money to the gocryptfs 22 | project directly. 23 | 24 | You can however, set bounties on features you would like to see 25 | implemented. Create a ticket on Github (or choose an existing one) 26 | and post a bounty on [bountysource](https://www.bountysource.com/) 27 | or a similar service. 28 | 29 | Infrastructure 30 | -------------- 31 | 32 | gocryptfs currently does not have a mailing list. What would be needed 33 | are hosting and, maybe more importantly, looking after and maintaining 34 | the list. This includes answering frequent questions. A searchable 35 | archive is needed as well. 36 | 37 | 38 | Documentation 39 | ------------- 40 | 41 | I try to keep the website updated as well as I can, but especially 42 | the [Comparison](comparison) page has a lot of data that can go out of 43 | date. If you can imagine adopting it you are very welcome. So you know 44 | what are getting into, here is the 45 | [source code](https://raw.githubusercontent.com/rfjakob/gocryptfs-website/master/docs/comparison.md) 46 | ;) 47 | 48 | 49 | Also, all comments on other gocryptfs documentation (like the 50 | [man page](https://raw.githubusercontent.com/rfjakob/gocryptfs/master/Documentation/MANPAGE.md) 51 | are welcome. Pull requests that fix typos are encouraged. 52 | -------------------------------------------------------------------------------- /docs/forward_mode_crypto.md: -------------------------------------------------------------------------------- 1 | gocryptfs Cryptography 2 | ====================== 3 | 4 | gocryptfs builts upon well-known cryptographic primitives: scrypt for 5 | key derivation, AES-GCM for file content encryption and, as a world's 6 | first for encrypted filesystems, 7 | EME wide-block encryption for file name encryption. 8 | 9 | This page describes **forward mode**, the default mode of operation, where 10 | the files are stored encrypted on disk and the mounted filesystem provides 11 | a plaintext view. 12 | 13 | Master Key Storage 14 | ------------------ 15 | 16 | The master key is used to perform content and file name encryption. 17 | It is stored in `gocryptfs.conf`, encrypted with AES-256-GCM using the 18 | *Key Encryption Key* (KEK). The KEK is generated from the user password 19 | using `scrypt`. 20 | 21 | When mounting a filesystem, the user is prompted for the password and 22 | the master key is decrypted: 23 | 24 | ![](img/master-key.svg) 25 | 26 | Derived Keys 27 | ------------ 28 | 29 | Since gocryptfs v1.3, separate keys are derived from the master key for 30 | file content and file name encryption. 31 | [HKDF](https://pkg.go.dev/golang.org/x/crypto/hkdf)-SHA256 is used for the 32 | derivation (source code: [ref1](https://github.com/rfjakob/gocryptfs/blob/f0e29d9b90b63d5fbe4164161ecb0e1035bb4af4/internal/cryptocore/hkdf.go) 33 | [ref2](https://github.com/rfjakob/gocryptfs/blob/f0e29d9b90b63d5fbe4164161ecb0e1035bb4af4/internal/cryptocore/cryptocore.go#L66)). 34 | 35 | ![](img/derived-keys.svg) 36 | 37 | File Contents 38 | ------------- 39 | 40 | All file contents are encrypted using AES-256-GCM (Galois/Counter Mode). 41 | 42 | Files are segmented into 4KiB blocks. Each block gets a fresh random 43 | 128 bit *Initialisation Vector* (IV) each time it is modified. A 128-bit authentication tag (GHASH) 44 | protects each block from modifications. 45 | Due to the random IV, AES-256-GCM is *non-deterministic*. 46 | 47 | Each file has a header containing a random 128-bit file ID. The 48 | file ID and the block number are concatenated 49 | (source code [ref](https://github.com/rfjakob/gocryptfs/blob/64e5906ffa1f225a51048b3d0ac6b1a09e2ca170/internal/contentenc/content.go#L124)) 50 | and mixed into the GHASH as 51 | *additional authenticated data*. This prevents blocks from being copied 52 | between or within files. 53 | 54 | ![](img/file-content-encryption.svg) 55 | 56 | To support sparse files, all-zero blocks are accepted and passed through 57 | unchanged. Empty files do not contain a header. 58 | 59 | File Names 60 | ---------- 61 | 62 | Every directory gets a 128-bit directory *Initialisation Vector* (IV) that is stored in each 63 | directory as `gocryptfs.diriv`. 64 | 65 | File names are encrypted using AES-256-EME (ECB-Mix-ECB wide-block encryption, 66 | see [github.com/rfjakob/eme](https://github.com/rfjakob/eme) for details) with the directory IV 67 | as initialization vector. 68 | 69 | Due to the fixed per-directory IV, file name encryption is *deterministic* in each 70 | directory for the lifetime of that directory. File name encryption must be 71 | deterministic to avoid collisions (i.e. multiple encrypted names decrypting to the 72 | same plaintext name). 73 | 74 | Compared to CBC, EME does not have a prefix leak. 75 | 76 | ![](img/file-name-encryption.svg) 77 | 78 | Padding and base64-encoding limit the usable filename length to 175 characters. 79 | Filenames that are longer than that (longer than 255 characters in 80 | Base64-encoded form) use long file name handling, introduced in gocryptfs v0.9. 81 | 82 | Long File Name Handling 83 | ----------------------- 84 | 85 | If the base64-encoded encrypted name is longer than 255 characters, 86 | it cannot be used as the file name on disk, as common Linux filesystems 87 | do not allow names longer than that. 88 | 89 | Instead, the encrypted name is hashed, and the file content is stored in 90 | `gocryptfs.longname.[hash]`. The long file name is stored in a support 91 | file, `gocryptfs.longname.[hash].name`. 92 | 93 | ![](img/longnames.svg) 94 | 95 | Example directory listing containing an 1 MiB encrypted file with a long name: 96 | 97 | ``` 98 | Size Name 99 | 16 gocryptfs.diriv 100 | 1056786 gocryptfs.longname.nONaEDDZOrwtQdXPH1SxSFkPtOc8srIyB82ZuduqG10 101 | 299 gocryptfs.longname.nONaEDDZOrwtQdXPH1SxSFkPtOc8srIyB82ZuduqG10.name 102 | ``` 103 | 104 | This method for storing long file names has zero performance impact 105 | for filenames that are <= 175 characters, incurs no extra disk accesses 106 | for opening a file with a long name, and just one extra file read for each 107 | long-name file on readdir(1). 108 | 109 | Because the hash is only taken from the encrypted file name that is public 110 | anyway, there is no security penalty for using long names. 111 | -------------------------------------------------------------------------------- /docs/img/derived-keys.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 35 | 36 | 44 | 50 | 51 | 59 | 65 | 66 | 74 | 80 | 81 | 89 | 95 | 96 | 104 | 110 | 111 | 119 | 125 | 126 | 134 | 140 | 141 | 149 | 155 | 156 | 164 | 170 | 171 | 179 | 185 | 186 | 194 | 200 | 201 | 209 | 215 | 216 | 224 | 230 | 231 | 239 | 245 | 246 | 254 | 260 | 261 | 269 | 275 | 276 | 284 | 290 | 291 | 299 | 305 | 306 | 307 | 333 | 342 | 347 | 352 | 357 | 362 | 367 | 372 | 373 | 375 | 376 | 378 | image/svg+xml 379 | 381 | 382 | 383 | 384 | 385 | 390 | 398 | HKDF 410 | Master key 422 | 429 | Content key 441 | 448 | File name key 460 | 467 | 475 | HKDF 487 | "AES-GCM file content encryption" 499 | "EME filename encryption" 511 | Infostring 528 | 533 | 538 | 543 | 548 | 553 | 558 | 563 | 568 | 569 | 570 | -------------------------------------------------------------------------------- /docs/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfjakob/gocryptfs-website/825f43805c047f4ddaa5628adc417b48458fd489/docs/img/favicon.ico -------------------------------------------------------------------------------- /docs/img/file-name-encryption.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 38 | 40 | 48 | 53 | 54 | 60 | 65 | 66 | 72 | 77 | 78 | 84 | 89 | 90 | 96 | 101 | 102 | 108 | 113 | 114 | 120 | 125 | 126 | 132 | 137 | 138 | 144 | 149 | 150 | 156 | 161 | 162 | 168 | 173 | 174 | 175 | 177 | 178 | 180 | image/svg+xml 181 | 183 | 184 | 185 | 186 | 187 | 194 | 201 | Directory X 212 | gocryptfs.diriv 223 | 233 | 241 | AES-256-EME 252 | 257 | 262 | 269 | "letter.doc" 280 | 285 | 292 | lrpyui0m-ypX4u0J[...] 303 | File name key 314 | 321 | 326 | 331 | IV 342 | 350 | Base64 361 | 366 | 374 | >255? 385 | 390 | 401 | no 412 | 417 | yes 428 | 436 | long file name handling 447 | 448 | -------------------------------------------------------------------------------- /docs/img/folders-side-by-side.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfjakob/gocryptfs-website/825f43805c047f4ddaa5628adc417b48458fd489/docs/img/folders-side-by-side.gif -------------------------------------------------------------------------------- /docs/img/gocryptfs-logo.paths-black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 48 | 54 | 55 | 57 | 58 | 60 | image/svg+xml 61 | 63 | 64 | 65 | 66 | 67 | 72 | 75 | 79 | 83 | 84 | 87 | 91 | 95 | 99 | 100 | 103 | 107 | 111 | 112 | 115 | 119 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/img/gocryptfs-logo.paths-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 48 | 54 | 55 | 57 | 58 | 60 | image/svg+xml 61 | 63 | 64 | 65 | 66 | 67 | 72 | 75 | 79 | 83 | 84 | 87 | 91 | 95 | 99 | 100 | 103 | 107 | 111 | 112 | 115 | 119 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/img/gocryptfs-logo.paths.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 48 | 52 | 53 | 55 | 56 | 58 | image/svg+xml 59 | 61 | 62 | 63 | 64 | 65 | 70 | 73 | 77 | 81 | 82 | 85 | 89 | 93 | 97 | 101 | 105 | 106 | 109 | 113 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /docs/img/gocryptfs-logo.text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 48 | 54 | 55 | 57 | 58 | 60 | image/svg+xml 61 | 63 | 64 | 65 | 66 | 67 | 72 | go 83 | cry 94 | fs 105 | pt 116 | 117 | 118 | -------------------------------------------------------------------------------- /docs/img/longnames.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 38 | 40 | 46 | 51 | 52 | 58 | 63 | 64 | 70 | 75 | 76 | 82 | 87 | 88 | 94 | 99 | 100 | 106 | 111 | 112 | 118 | 123 | 124 | 130 | 135 | 136 | 142 | 147 | 148 | 154 | 159 | 160 | 161 | 163 | 164 | 166 | image/svg+xml 167 | 169 | 170 | 171 | 172 | 173 | 180 | 187 | Directory X 198 | gocryptfs.longname.[hash].name 209 | 219 | 227 | SHA256 238 | 245 | 253 | Base64 264 | 269 | 274 | lrpyui0m-ypX4u0J[...] 285 | 290 | 295 | long name storedin .name file 310 | [hash] 321 | 328 | gocryptfs.longname.[hash] 339 | file content 350 | 355 | 356 | -------------------------------------------------------------------------------- /docs/img/master-key.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 34 | 35 | 43 | 48 | 49 | 57 | 62 | 63 | 71 | 76 | 77 | 85 | 90 | 91 | 99 | 104 | 105 | 113 | 118 | 119 | 127 | 133 | 134 | 142 | 148 | 149 | 158 | 164 | 165 | 174 | 180 | 181 | 189 | 195 | 196 | 204 | 210 | 211 | 219 | 225 | 226 | 227 | 252 | 261 | 266 | 271 | 272 | 274 | 275 | 277 | image/svg+xml 278 | 280 | 281 | 282 | 283 | 284 | 289 | 296 | 303 | gocryptfs.conf 315 | User password 327 | scrypt parameters 339 | 346 | 354 | scrypt 366 | 374 | AES-256-GCM 386 | Master key 398 | 405 | 411 | 416 | IV 428 | 435 | Encrypted master key 447 | IV 459 | authentication tag 471 | Ciphertext +  488 | 493 | 498 | KEK 510 | 515 | 520 | 525 | 530 | 535 | 536 | 537 | -------------------------------------------------------------------------------- /docs/img/reverse-derivePathIV.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 35 | 36 | 44 | 50 | 51 | 59 | 65 | 66 | 74 | 80 | 81 | 89 | 95 | 96 | 104 | 110 | 111 | 120 | 126 | 127 | 136 | 142 | 143 | 144 | 172 | 181 | 182 | 184 | 185 | 187 | image/svg+xml 188 | 190 | 191 | 192 | 193 | 194 | 199 | 203 | 211 | 219 | 227 | 235 | 243 | 251 | 252 |   263 | SHA256(path + \0 + 275 | Truncateto 128 bits 292 | "DIRIV""FILEID""BLOCK0IV" 314 |   325 | 330 | 335 | 340 | 345 | 350 | 355 | DirIVFileIDBlock0IV 377 |   Plaintext path 401 | 404 | File name encryption 416 | 424 | 425 | 431 | encryptedpath 448 | 453 | ) 465 | 466 | 467 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | gocryptfs - simple. secure. fast. 2 | ================================= 3 | 4 | gocryptfs uses file-based encryption that is implemented as a mountable 5 | FUSE filesystem. 6 | Each file in gocryptfs is stored one corresponding encrypted file on 7 | the hard disk. The 8 | screenshot below shows a mounted gocryptfs filesystem (left) and the 9 | encrypted files (right). 10 | 11 | The encrypted files can be stored in any folder on your hard disk, a USB 12 | stick or even inside the Dropbox folder. One advantage of file-based 13 | encryption as opposed to disk encryption is that encrypted files can 14 | be synchronised efficiently using standard tools like Dropbox or rsync. 15 | Also, the size of the encrypted filesystem is dynamic and only limited 16 | by the available disk space. 17 | 18 | ![](img/folders-side-by-side.gif) 19 | 20 | This project was inspired by EncFS and strives to fix its security 21 | issues while providing good performance, 22 | see the [Comparison](comparison) page for benchmarks. 23 | 24 | The [Cryptography](forward_mode_crypto.md) page details gocryptfs's 25 | cryptographic design. 26 | The highlights are: Scrypt password hashing, GCM encryption for all 27 | file contents, EME wide-block encryption for file names with a per-directory 28 | IV. 29 | 30 | gocryptfs has reached version 1.0 on Jul 17, 2016. It has gone through 31 | hours and hours of stress (fsstress, `tests/stress_tests`) and correctness 32 | testing (xfstests, integrated test suite). 33 | It is now considered ready for general consumption. 34 | 35 | The old principle still applies: Important data should have a backup. 36 | Also, keep a copy of your master key (printed on mount) in a safe place. 37 | This allows you to access the data even if the gocryptfs.conf config 38 | file is damaged or you lose the password. 39 | 40 | Linux is fully supported. Beta-quality MacOS support is available, which 41 | means things usually work fine, but you may hit the odd issue (please 42 | file a ticket if you do!). 43 | 44 | Third-party implementations exist for for 45 | 46 | * Windows: [cppcryptfs](https://github.com/bailey27/cppcryptfs) 47 | * Android: [DroidFS](https://github.com/hardcore-sushi/DroidFS) 48 | * Python: [gocryptfs-inspect](https://github.com/slackner/gocryptfs-inspect) 49 | 50 | gocryptfs is, and always will be, free software. 51 | 52 | News 53 | ---- 54 | 55 | Latest release: [![Latest release](https://img.shields.io/github/release/rfjakob/gocryptfs.svg)](https://github.com/rfjakob/gocryptfs/releases) 56 | 57 | 2025-01-18
58 | Release [gocryptfs v2.5.0](https://github.com/rfjakob/gocryptfs/releases/tag/v2.5.0) 59 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 60 | 61 | 2023-06-10
62 | Release [gocryptfs v2.4.0](https://github.com/rfjakob/gocryptfs/releases/tag/v2.4.0) 63 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 64 | 65 | 2023-04-29
66 | Release [gocryptfs v2.3.2](https://github.com/rfjakob/gocryptfs/releases/tag/v2.3.2) 67 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 68 | 69 | 2023-03-04
70 | Release [gocryptfs v2.3.1](https://github.com/rfjakob/gocryptfs/releases/tag/v2.3.1) 71 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 72 | 73 | 2022-08-28
74 | Release [gocryptfs v2.3](https://github.com/rfjakob/gocryptfs/releases/tag/v2.3) 75 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 76 | 77 | 2021-10-20
78 | Release [gocryptfs v2.2.1](https://github.com/rfjakob/gocryptfs/releases/tag/v2.2.1) 79 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 80 | 81 | 2021-09-25
82 | Release [gocryptfs v2.2.0](https://github.com/rfjakob/gocryptfs/releases/tag/v2.2.0) 83 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 84 | 85 | 2021-08-18
86 | Release [gocryptfs v2.1](https://github.com/rfjakob/gocryptfs/releases/tag/v2.1) 87 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 88 | 89 | 2021-06-07
90 | Release [gocryptfs v2.0.1](https://github.com/rfjakob/gocryptfs/releases/tag/v2.0.1) 91 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 92 | 93 | 2021-06-05
94 | Release [gocryptfs v2.0](https://github.com/rfjakob/gocryptfs/releases/tag/v2.0) 95 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 96 | 97 | 2020-05-09
98 | Release [gocryptfs v1.8.0](https://github.com/rfjakob/gocryptfs/releases/tag/v1.8.0) 99 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 100 | 101 | 2020-05-09
102 | Release [gocryptfs v1.8.0](https://github.com/rfjakob/gocryptfs/releases/tag/v1.8.0) 103 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 104 | 105 | 2019-05-17
106 | Release [gocryptfs v1.7](https://github.com/rfjakob/gocryptfs/releases/tag/v1.7) 107 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 108 | 109 | 2018-12-01
110 | gocryptfs is added to the offical Arch Linux repo 111 | ([commit](https://git.archlinux.org/svntogit/community.git/commit/trunk?h=packages/gocryptfs&id=1714dd305acbe2ada823f34fbaa390af11633086), 112 | [package info](https://www.archlinux.org/packages/community/x86_64/gocryptfs/)) 113 | 114 | 2018-08-18
115 | Release [gocryptfs v1.6](https://github.com/rfjakob/gocryptfs/releases/tag/v1.6) 116 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 117 | 118 | 2019-07-29
119 | gocryptfs is added to Fedora 30 and rawhide: 120 | [package info](https://src.fedoraproject.org/rpms/golang-github-rfjakob-gocryptfs) 121 | 122 | 2018-06-12
123 | Release [gocryptfs v1.5](https://github.com/rfjakob/gocryptfs/releases/tag/v1.5) 124 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 125 | 126 | 2018-04-27
127 | Ubuntu 18.04 LTS is released, including gocryptfs v1.4.3: 128 | [https://packages.ubuntu.com/bionic/gocryptfs](https://packages.ubuntu.com/bionic/gocryptfs) 129 | 130 | 2017-06-20
131 | Release [gocryptfs v1.4](https://github.com/rfjakob/gocryptfs/releases/tag/v1.4) 132 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 133 | 134 | 2017-06-17
135 | Debian 9 "Stretch" is released, including gocryptfs v1.2: 136 | [https://packages.debian.org/stretch/gocryptfs](https://packages.debian.org/stretch/gocryptfs) 137 | 138 | 2017-04-29
139 | Release [gocryptfs v1.3](https://github.com/rfjakob/gocryptfs/releases/tag/v1.3) 140 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 141 | 142 | 2017-03-10
143 | Taylor Hornby of defuse.ca releases a cryptography design audit of gocryptfs: 144 | [announcement](https://twitter.com/DefuseSec/status/840239275740405761), 145 | [audit](https://defuse.ca/audits/gocryptfs.htm) 146 | 147 | 2016-12-04
148 | Release [gocryptfs v1.2](https://github.com/rfjakob/gocryptfs/releases/tag/v1.2) 149 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 150 | 151 | 2016-10-30
152 | Added description of [Reverse Mode](reverse_mode) to the website 153 | 154 | 2016-10-19
155 | Release [gocryptfs v1.1](https://github.com/rfjakob/gocryptfs/releases/tag/v1.1) 156 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 157 | 158 | 2016-07-17
159 | Release [gocryptfs v1.0](https://github.com/rfjakob/gocryptfs/releases/tag/v1.0) 160 | ([changelog](https://github.com/rfjakob/gocryptfs#changelog)) 161 | -------------------------------------------------------------------------------- /docs/mirrors.md: -------------------------------------------------------------------------------- 1 | Source Code Mirrors 2 | =================== 3 | 4 | 1) Github 5 | --------- 6 | 7 | The primary git repository is hosted on Github. Clone using: 8 | 9 | git clone https://github.com/rfjakob/gocryptfs.git 10 | 11 | The webinterface is at 12 | [https://github.com/rfjakob/gocryptfs](https://github.com/rfjakob/gocryptfs) . 13 | 14 | Wiki: [https://github.com/rfjakob/gocryptfs/wiki](https://github.com/rfjakob/gocryptfs/wiki) 15 | 16 | 2) Mirrors on nuetzlich.net 17 | ------------------------- 18 | 19 | I run git mirrors should Github be down at any time. 20 | It is updated every hour. Clone with: 21 | 22 | git clone https://nuetzlich.net/cgit/gocryptfs/ 23 | 24 | The cgit webinterface is available at 25 | [https://nuetzlich.net/cgit/](https://nuetzlich.net/cgit/) . 26 | 27 | Wiki: [https://nuetzlich.net/cgit/gocryptfs.wiki/tree/](https://nuetzlich.net/cgit/gocryptfs.wiki/tree/) 28 | -------------------------------------------------------------------------------- /docs/quickstart.md: -------------------------------------------------------------------------------- 1 | Quickstart 2 | ========== 3 | 4 | Download or Compile gocryptfs 5 | ----------------------------- 6 | 7 | Precompiled binaries that work on **all** x86_64 Linux systems are 8 | available for download from the 9 | [github releases page](https://github.com/rfjakob/gocryptfs/releases). 10 | 11 | On Debian, gocryptfs is available as 12 | [a deb package](https://packages.debian.org/search?keywords=gocryptfs&searchon=names&suite=all§ion=all): 13 | 14 | $ apt install gocryptfs 15 | 16 | On MacOS, [gocryptfs is available on MacPorts](https://ports.macports.org/port/gocryptfs/details/): 17 | 18 | $ port install gocryptfs 19 | 20 | On Fedora, gocryptfs is available as 21 | [an rpm package](https://src.fedoraproject.org/rpms/golang-github-rfjakob-gocryptfs): 22 | 23 | $ sudo dnf install gocryptfs 24 | 25 | gocryptfs is available in many other distributions in the following 26 | versions: 27 | 28 | [![Packaging status](https://repology.org/badge/vertical-allrepos/gocryptfs.svg?columns=4)](https://repology.org/project/gocryptfs/versions) 29 | 30 | [![Packaging status](https://repology.org/badge/vertical-allrepos/go:github-rfjakob-gocryptfs.svg?columns=5&header=Packaging Status II)](https://repology.org/project/go:github-rfjakob-gocryptfs/versions) 31 | 32 | 33 | If you want to compile from source, see the [Compile](compile.md) page for 34 | instructions. 35 | 36 | Once you have gocrypts installed, running 37 | 38 | $ gocryptfs -version 39 | 40 | should print a version string like this: 41 | 42 | gocryptfs v1.4.3; go-fuse v20170619-28-g19acbd2; 2018-02-01 go1.9.2 43 | 44 | Create and Mount Filesystem 45 | --------------------------- 46 | 47 | $ mkdir cipher plain 48 | $ gocryptfs -init cipher 49 | [...] 50 | $ gocryptfs cipher plain 51 | [...] 52 | 53 | You should now have a working gocryptfs that is stored in `cipher` and mounted to `plain`. 54 | You can verify it by creating a test file in the `plain` directory. This file will show 55 | up encrypted in the `cipher` directory. 56 | 57 | $ touch plain/test.txt 58 | $ ls cipher 59 | gocryptfs.conf gocryptfs.diriv ZSuIZVzYDy5-TbhWKY-ciA== 60 | 61 | Cloud Storage 62 | ------------- 63 | 64 | When you want to store your encrypted data on cloud storage (Dropbox in this example), 65 | the `cipher` folder should be inside the `Dropbox` folder but the `plain` folder 66 | should be **outside**! Example: 67 | 68 | $ mkdir ~/Dropbox/cipher 69 | $ mkdir ~/plain 70 | $ gocryptfs -init ~/Dropbox/cipher 71 | $ gocryptfs ~/Dropbox/cipher ~/plain 72 | 73 | This makes sure that Dropbox only syncs the encrypted version of your data. 74 | -------------------------------------------------------------------------------- /docs/releases.md: -------------------------------------------------------------------------------- 1 | gocryptfs Releases 2 | ================== 3 | 4 | gocryptfs is released as 5 | 6 | * source code using signed git tags, please `git clone https://github.com/rfjakob/gocryptfs.git` 7 | * precompiled binaries with .asc gpg signatures, [download at github](https://github.com/rfjakob/gocryptfs/releases) 8 | 9 | Signing Key 10 | ----------- 11 | 12 | Binary and source releases are signed using the *gocryptfs signing key*, key ID 13 | `895F5BC123A02740` (gpg 1.x users only see the second half: `23A02740`). 14 | 15 | The public key can be downloaded [here](https://nuetzlich.net/gocryptfs-signing-key.pub). 16 | To verify signatures, you have to import it into gpg: 17 | 18 | $ wget https://nuetzlich.net/gocryptfs-signing-key.pub 19 | $ gpg --import gocryptfs-signing-key.pub 20 | 21 | Verify Git Tags 22 | --------------- 23 | 24 | Just call `git tag` with the `-v` flag, for example: 25 | 26 | ``` 27 | $ git tag -v v1.4.4 28 | 29 | object 9c86daf499dca8a69b058ec56803d06fbba4fdab 30 | type commit 31 | tag v1.4.4 32 | tagger Jakob Unterwurzacher 1521412204 +0100 33 | 34 | gocryptfs v1.4.4 35 | gpg: Signature made Sun Mar 18 23:30:10 2018 CET 36 | gpg: using RSA key 895F5BC123A02740 37 | gpg: Good signature from "Jakob Unterwurzacher (gocryptfs signing key) " [unknown] 38 | gpg: WARNING: This key is not certified with a trusted signature! 39 | gpg: There is no indication that the signature belongs to the owner. 40 | Primary key fingerprint: FFF3 E014 44FE D7C3 16A3 545A 895F 5BC1 23A0 2740 41 | ``` 42 | 43 | Verify Binaries 44 | --------------- 45 | 46 | Download both the `.tar.gz` and the `.asc` file, then run `gpg --verify gocryptfs_XYZ.asc`, 47 | for example: 48 | ``` 49 | $ gpg --verify gocryptfs_v1.4.4_linux-static_amd64.tar.gz.asc 50 | 51 | gpg: assuming signed data in 'gocryptfs_v1.4.4_linux-static_amd64.tar.gz' 52 | gpg: Signature made Sun Mar 18 23:32:47 2018 CET 53 | gpg: using RSA key 895F5BC123A02740 54 | gpg: Good signature from "Jakob Unterwurzacher (gocryptfs signing key) " [unknown] 55 | gpg: WARNING: This key is not certified with a trusted signature! 56 | gpg: There is no indication that the signature belongs to the owner. 57 | Primary key fingerprint: FFF3 E014 44FE D7C3 16A3 545A 895F 5BC1 23A0 2740 58 | ``` 59 | -------------------------------------------------------------------------------- /docs/reverse_mode_crypto.md: -------------------------------------------------------------------------------- 1 | Reverse Mode 2 | ============ 3 | 4 | In **reverse mode**, gocryptfs provides an encrypted view of a 5 | plain-text directory. The primary use-case are encrypted backups. 6 | 7 | To make reverse mode useful, it uses deterministic encryption using 8 | AES-SIV instead of AES-GCM. 9 | 10 | The differences with respect to the "normal" (forward) mode as detailed 11 | on the [Cryptography](forward_mode_crypto.md) page are listed below. 12 | 13 | Derived Keys 14 | ------------ 15 | 16 | As in forward mode, the file content key is derived from the master key 17 | using HKDF-SHA256. It is 64 bytes wide instead of 32 bytes 18 | (source code [ref](https://github.com/rfjakob/gocryptfs/blob/f0e29d9b90b63d5fbe4164161ecb0e1035bb4af4/internal/cryptocore/cryptocore.go#L111)). 19 | for use with AES-SIV-512. 20 | 21 | Derived IVs 22 | ----------- 23 | 24 | All values that are random in forward mode (Dir IV, File ID, Block IV) 25 | are instead deterministically derived from the encrypted path. 26 | The encrypted path is concatenated with a null byte and a 27 | purpose string (one of "DIRIV", "FILEID", "BLOCK0IV"). The extended string 28 | is hashed with SHA256 and truncated to 128 bits (source code 29 | [ref](https://github.com/rfjakob/gocryptfs/blob/f0e29d9b90b63d5fbe4164161ecb0e1035bb4af4/internal/pathiv/pathiv.go#L26)): 30 | 31 | ![](img/reverse-derivePathIV.svg) 32 | 33 | All derived values are explicitly stored in the ciphertext, 34 | so that decryption requires no knowledge of the derivation 35 | algorithm. 36 | 37 | File Contents 38 | ------------- 39 | 40 | File contents are encrypted using AES-SIV-512 (RFC5297). 41 | The encryption process is shown in the diagram below. 42 | 43 | ![](img/reverse-file-content-encryption.svg) 44 | 45 | Notes: 46 | 47 | 1. The IV is passed to AES-SIV as described in 48 | [RFC5297 section 3](https://tools.ietf.org/html/rfc5297#section-3) 49 | as an additional component of the associated data 50 | (source code [ref](https://github.com/rfjakob/gocryptfs/blob/f0e29d9b90b63d5fbe4164161ecb0e1035bb4af4/internal/siv_aead/siv_aead.go#L60)). 51 | 2. The block number N is mixed into the IV as well as into the AAD. 52 | Either one or the other would suffice, but this construction simplifies 53 | the decryption process by keeping it largely identical to forward mode. 54 | The "duplication" is considered to not have 55 | any security impact because IV and AAD contain 128 bits of 56 | pseudo-random data each (FileID and Block0IV) and S2V 57 | ([RFC5297 section 2.4](https://tools.ietf.org/html/rfc5297#section-2.4)) 58 | hashes the components independently before XORing them together. 59 | 60 | File Names 61 | ---------- 62 | 63 | File name encryption is identical to forward mode, with the exception 64 | that the directory IV (stored in `gocryptfs.diriv`) is not random. 65 | It is deterministically derived from the encrypted 66 | path to the directory. 67 | 68 | Because the encrypted path to the root directory is "" (the empty string), 69 | this means that the directory IV in the root directory is always 70 | `0xa8f7bac432ddc1cb3dc74e684d6ae48b = TRUNCATE(SHA256("\0DIRIV"))`. 71 | -------------------------------------------------------------------------------- /docs/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Get rid of the blue background 3 | begind the logo and kill some blank 4 | space around it 5 | */ 6 | 7 | div.wy-side-nav-search { 8 | background-color: unset; 9 | padding: unset; 10 | margin: unset; 11 | } 12 | 13 | /* 14 | Wide tables are wide. 15 | Default is 800px, which is a waste of screen space. 16 | */ 17 | div.wy-nav-content { 18 | max-width: unset; 19 | } 20 | 21 | .wy-table-responsive table td,.wy-table-responsive table th { 22 | /* 23 | The theme sets it to "nowrap", which means tables become 24 | ultra-wide with horizontal scrollbars. Ugh. 25 | */ 26 | white-space:unset; 27 | } 28 | -------------------------------------------------------------------------------- /docs/threat_model.md: -------------------------------------------------------------------------------- 1 | Threat Model 2 | ============ 3 | 4 | The threat model describes common scenarios and 5 | the security that gocryptfs provides for each. 6 | 7 | Quoting the [[gocryptfs-audit]](#gocryptfs-audit): 8 | 9 | > We suggest writing down an explicit threat model 10 | > and updating the website to better communicate the 11 | > security guarantees that gocryptfs provides. This way, 12 | > users are less likely to rely on it in ways which 13 | > would make them vulnerable. 14 | 15 | The scenarios are ordered according to the strength 16 | of the adversary, weakest to strongest. The adversaries 17 | are the same as those described in 18 | [[gocryptfs-audit]](#gocryptfs-audit). For more details 19 | you are advised to read the audit as well as this 20 | document. 21 | 22 | Eve: Single snapshot of the ciphertext 23 | -------------------------------------- 24 | 25 | Eve gets a complete copy of the ciphertext directory 26 | at a single point in time. Examples are losing a USB stick or 27 | getting your computer stolen. Because you don't get the 28 | stolen USB stick handed back to you, this is effectively 29 | a read-only attack. 30 | 31 | Unless you use a very weak password, it is unlikely that any 32 | file or file name can be decrypted by the adversary, no matter 33 | how much data you have stored. However, it may be possible to 34 | determine if you have a certain directory stored - see below. 35 | 36 | ### File size fingerprinting 37 | 38 | The plaintext file size of each file can be directly 39 | calculated from the ciphertext file size. In other words, 40 | Eve has full information about all file sizes. 41 | 42 | Using the file size information, Eve can try to 43 | identify directories of files *that she already knows*. 44 | 45 | For example, Eve could download all available 46 | music albums from public bittorrent trackers and build a 47 | database of all file sizes in all directories. This 48 | allows her to determine with reasonably good confidence 49 | if one of these music albums is in your ciphertext. 50 | 51 | In summary, gocryptfs does not protect the information 52 | that you have a certain directory of files, if that directory 53 | of files is already known to the adversary. 54 | 55 | ### Possible GCM / EME interaction 56 | 57 | *Same Key Used for Both GCM and EME Modes* as described in 58 | section 2.4 in [[gocryptfs-audit]](#gocryptfs-audit) no 59 | longer applies since gocryptfs v1.3. 60 | 61 | Dragon: Permanent read-write access to the ciphertext 62 | ----------------------------------------------------- 63 | 64 | Dragon (called "Dropbox" in the security audit) 65 | has read-write access to the whole ciphertext 66 | and sees all changes in real time. 67 | 68 | This scenario applies if you synchronize your ciphertext directory 69 | to a cloud service, and Dragon has the cloud service's 70 | servers under his control. 71 | 72 | ### Tracking changed blocks 73 | 74 | Dragon sees what parts of each encrypted file are written 75 | to with 4 kiB granularity. Because each written block gets 76 | a random IV, Dragon does not get any information 77 | about what has changed (or if anything has changed at all) 78 | within a 4 kiB block. 79 | 80 | This can be a problem if the location of writes is in itself 81 | sensitive. 82 | 83 | ### Modifying files 84 | 85 | Dragon can replace 4 kiB blocks of a file with earlier 86 | versions of the block. Blocks are tied to the file header and 87 | to the offset. They cannot be copied between different files 88 | or to a different offset in the file. 89 | 90 | Due to sparse file support, Dragon can also zero out 4 kiB blocks. 91 | 92 | Dragon can truncate files to 4 kiB boundaries. 93 | 94 | Other modifications to files will be caught upon reading the 95 | file, returning an I/O error to the application and logging 96 | a "corrupt block" message to syslog. 97 | 98 | *File ID Poisoning*, as described in section 2.2 of 99 | [[gocryptfs-audit]](#gocryptfs-audit), no longer works since 100 | gocryptfs v1.3. 101 | 102 | ### Deleting files 103 | 104 | Dragon can delete files at will. 105 | 106 | ### Renaming files 107 | 108 | As the file content is not tied to the file name in any way, 109 | Dragon can rename an encrypted file name to another valid 110 | encrypted file name. This effectively means that he can swap files. 111 | 112 | gocryptfs has explicitly chosen not to tie the file content to 113 | the file name to provide fast and reliable renames (renames are 114 | atomic in gocryptfs). 115 | 116 | This can be threat when combined with social engineering: 117 | Asking the user to send an uninteresting file and replacing it 118 | with a sensitive one just before the user sends it out. You 119 | can protect yourself against this attack by copying a file 120 | you want to send outside the cloud-synced directory, checking 121 | that you got the right file, and only then sending it. 122 | 123 | ### Directory IV Poisoning 124 | 125 | In gocryptfs, each directory gets a `gocryptfs.diriv` 126 | file on directory creation. This file contains the random DirIV 127 | for file name encryption for this directory. It makes sure 128 | identical file names generate different ciphertext in each 129 | directory. 130 | 131 | However when a directory is created, Dragon can immediately 132 | replace the `gocryptfs.diriv` file with a copy from another 133 | directory. When the DirIV is identical, identical file names 134 | generated identical ciphertext, so Dragon can see if a file 135 | name exists in both directories. 136 | 137 | Mallory: Read-write access to full ciphertext and a single plaintext folder 138 | --------------------------------------------------------------------------- 139 | 140 | Mallory can read and write the whole ciphertext and additionally is 141 | granted read-write access to a single folder in a mounted gocryptfs 142 | filesystem. This can happen if Mallory is the administrator of the 143 | NFS or SMB file server you store the ciphertext on, and you additionally 144 | export a "public" subdirectory of the mounted (decrypted) gocryptfs filesystem 145 | to Mallory. 146 | 147 | This scenario leads to a complete break of confidentiality as Mallory 148 | can move all ciphertext folders to the "public" directory and copy the 149 | plaintext from there. It is recommended to avoid this scenario by never 150 | exporting any part of a mounted gocryptfs filesystem. 151 | 152 | References 153 | --------------- 154 | 155 | #### [gocryptfs-audit] 156 | *Gocryptfs Security Audit*
157 | Taylor Hornby - Defuse Security, 6 Mar 2017
158 | 159 | -------------------------------------------------------------------------------- /htaccess: -------------------------------------------------------------------------------- 1 | # "security" was renamed to "forward_mode_crypto" on 2017-09-17. Keep old links working. 2 | Redirect "/gocryptfs/security" "/gocryptfs/forward_mode_crypto" 3 | 4 | # "reverse_mode" was renamed to "reverse_mode_crypto" on 2017-09-17. Keep old links working. 5 | Redirect "/gocryptfs/reverse_mode" "/gocryptfs/reverse_mode_crypto" 6 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: gocryptfs 2 | theme: 3 | name: readthedocs 4 | # https://www.mkdocs.org/user-guide/customizing-your-theme/#using-the-theme-custom_dir 5 | custom_dir: custom_theme 6 | highlightjs: False 7 | logo: img/gocryptfs-logo.paths-white.svg 8 | navigation_depth: 1 9 | extra_css: 10 | - style.css 11 | plugins: [] 12 | nav: 13 | - Home: index.md 14 | - Quickstart: quickstart.md 15 | - Compile from Source: compile.md 16 | - Cryptography: forward_mode_crypto.md 17 | - Reverse Mode Cryptography: reverse_mode_crypto.md 18 | - Threat Model: threat_model.md 19 | - Comparison with Other Projects: comparison.md 20 | - Signed Releases: releases.md 21 | - Source Code Mirrors: mirrors.md 22 | - Contribute: contribute.md 23 | - 'Download Binaries ➚': 'https://github.com/rfjakob/gocryptfs/releases' 24 | - 'Changelog ➚': 'https://github.com/rfjakob/gocryptfs#changelog' 25 | - 'Man Page ➚': 'https://github.com/rfjakob/gocryptfs/blob/master/Documentation/MANPAGE.md' 26 | - 'Wiki ➚': 'https://github.com/rfjakob/gocryptfs/wiki' 27 | --------------------------------------------------------------------------------