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 |
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 | 
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 | 
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 | 
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 | 
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 | 
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 |
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 |
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 |
126 |
--------------------------------------------------------------------------------
/docs/img/gocryptfs-logo.paths-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
126 |
--------------------------------------------------------------------------------
/docs/img/gocryptfs-logo.paths.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
120 |
--------------------------------------------------------------------------------
/docs/img/gocryptfs-logo.text.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
118 |
--------------------------------------------------------------------------------
/docs/img/longnames.svg:
--------------------------------------------------------------------------------
1 |
2 |
356 |
--------------------------------------------------------------------------------
/docs/img/master-key.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
537 |
--------------------------------------------------------------------------------
/docs/img/reverse-derivePathIV.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
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 | 
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: [](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 | [](https://repology.org/project/gocryptfs/versions)
29 |
30 | [](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 | 
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 | 
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 |
--------------------------------------------------------------------------------