raspberry pi 3: out of memory when decrypting the master key
acavalin opened this issue · 10 comments
Hello,
thank you for this wonderful software :)
I encountered a problem using it on a raspberry pi 3: using a password 68 characters long with 23 unique characters, gocryptfs goes out of memory when decrypting the master key, it wants to allocate 1GiB but the rpi3 has not enough memory.
I tried adding a big swapfile but it still fails to allocate the memory. :'(
Is it possible to workaround this problem or the only solution left is shortening the length of the password?
# gocryptfs --version
gocryptfs v1.7; go-fuse v1.0.0-12-g0074c95; 2019-05-10 go1.7.4
# gocryptfs -passfile pass -reverse plain enc
passfile: reading from file "pass"
Decrypting master key
runtime: out of memory: cannot allocate 1073741824-byte block (1048576 in use)
fatal error: out of memory
runtime stack:
runtime.throw(0x245099, 0xd)
/usr/lib/go-1.7/src/runtime/panic.go:566 +0x78
runtime.largeAlloc(0x40000000, 0x1066e001, 0x83aa0)
/usr/lib/go-1.7/src/runtime/malloc.go:776 +0xc8
runtime.mallocgc.func1()
/usr/lib/go-1.7/src/runtime/malloc.go:669 +0x34
runtime.systemstack(0x336100)
/usr/lib/go-1.7/src/runtime/asm_arm.s:247 +0x80
runtime.mstart()
/usr/lib/go-1.7/src/runtime/proc.go:1079
goroutine 1 [running]:
runtime.systemstack_switch()
/usr/lib/go-1.7/src/runtime/asm_arm.s:192 +0x4 fp=0x1064d83c sp=0x1064d838
runtime.mallocgc(0x40000000, 0x213c98, 0xdcb01, 0x1068f000)
/usr/lib/go-1.7/src/runtime/malloc.go:670 +0xe58 fp=0x1064d8dc sp=0x1064d83c
runtime.makeslice(0x213c98, 0x10000000, 0x0, 0x10000000, 0x0, 0x0, 0x0, 0x0)
/usr/lib/go-1.7/src/runtime/slice.go:57 +0x130 fp=0x1064d904 sp=0x1064d8dc
golang.org/x/crypto/scrypt.Key(0x106ae000, 0x45, 0x802, 0x10673680, 0x20, 0x21, 0x100000, 0x8, 0x1, 0x20, ...)
golang.org/x/crypto/scrypt/scrypt.go:236 +0x194 fp=0x1064d990 sp=0x1064d904
github.com/rfjakob/gocryptfs/internal/configfile.(*ScryptKDF).DeriveKey(0x106a6074, 0x106ae000, 0x45, 0x802, 0x0, 0x0, 0x0)
github.com/rfjakob/gocryptfs/internal/configfile/scrypt.go:67 +0x94 fp=0x1064d9fc sp=0x1064d990
github.com/rfjakob/gocryptfs/internal/configfile.(*ConfFile).DecryptMasterKey(0x106a6060, 0x106ae000, 0x45, 0x802, 0x0, 0x0, 0x0, 0x0, 0x0)
github.com/rfjakob/gocryptfs/internal/configfile/config_file.go:218 +0x74 fp=0x1064da74 sp=0x1064d9fc
main.loadConfig(0x106a4000, 0x0, 0x0, 0x0, 0x106a6060, 0x0, 0x0)
github.com/rfjakob/gocryptfs/main.go:59 +0x2a0 fp=0x1064dad4 sp=0x1064da74
main.getMasterKey(0x106a4000, 0x0, 0x0, 0x0, 0x10678cd0)
github.com/rfjakob/gocryptfs/masterkey.go:64 +0x2a4 fp=0x1064db28 sp=0x1064dad4
main.initFuseFrontend(0x106a4000, 0x0, 0x0, 0x1064dcd0)
github.com/rfjakob/gocryptfs/mount.go:218 +0x48 fp=0x1064dc08 sp=0x1064db28
main.doMount(0x106a4000)
github.com/rfjakob/gocryptfs/mount.go:101 +0x824 fp=0x1064dd3c sp=0x1064dc08
main.main()
github.com/rfjakob/gocryptfs/main.go:297 +0xd04 fp=0x1064df9c sp=0x1064dd3c
runtime.main()
/usr/lib/go-1.7/src/runtime/proc.go:183 +0x264 fp=0x1064dfc4 sp=0x1064df9c
runtime.goexit()
/usr/lib/go-1.7/src/runtime/asm_arm.s:998 +0x4 fp=0x1064dfc4 sp=0x1064dfc4
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/lib/go-1.7/src/runtime/asm_arm.s:998 +0x4
goroutine 20 [chan send]:
github.com/rfjakob/gocryptfs/internal/cryptocore.(*randPrefetcherT).refillWorker(0x335fc8)
github.com/rfjakob/gocryptfs/internal/cryptocore/randprefetch.go:51 +0x54
created by github.com/rfjakob/gocryptfs/internal/cryptocore.init.1
github.com/rfjakob/gocryptfs/internal/cryptocore/randprefetch.go:16 +0x64
goroutine 21 [syscall]:
os/signal.signal_recv(0x0)
/usr/lib/go-1.7/src/runtime/sigqueue.go:116 +0x190
os/signal.loop()
/usr/lib/go-1.7/src/os/signal/signal_unix.go:22 +0x14
created by os/signal.init.1
/usr/lib/go-1.7/src/os/signal/signal_unix.go:28 +0x30
Hi, that's interesting. Master key decryption should only use 64MB of RAM, regardless of password length. Does a shorter password really fix this?
One more idea: you have compiled with a pretty old Go version, go1.7.4, can you try again with this, compiled with go1.12 ? gocryptfs_v1.7-33_arm.zip
Thank you for the more recent build, it runs without errors but it does not mount anything:
# ./gocryptfs -passfile pass -reverse plain enc
passfile: reading from file "pass"
Decrypting master key
# ls -l enc
total 0
I noticed that if re-initializing the folder on the rpi3 with the same password then everything goes well, but if I try to mount it using the original config file created on a x64 linux PC then it goes OOM... so it seems the problem is config related.
So I initialized some folders on the rpi3 and checked the differences versus the x64 config file, I discovered (ignoring EncryptedKey
and Salt
keys) that each file is identical except for the N
key: in particular every config file created on the rpi3 has an N
value of 65536
while the x64 one has 1048576
.
I think the higher N
value is the culprit 🤔
Yes, the N value explains it. So the question is: where does 1048576 come from?
What is your gocryptfs version on x64?
At that time I initialized the folder with gocryptfs v1.6.1.
What should I do now? Have I to reinitialize all folders?
It will be a pain to re-upload everything to my online drive but I will do it if necessary 😢
When you created it on x64, did you pass
-scryptn 20
? 2^20 = 1048576, so this is how you would get that value.
Grab the latest version from git (commit 991adfc ), then change your password like this:
gocryptfs -passwd -scryptn=16 CIPHERDIR
You can use the same password again. This will set scryptn=16, which is the default value, and then it will use 64MB.
Interesting riddle ;)