diff options
| -rw-r--r-- | Documentation/MANPAGE.md | 7 | ||||
| -rw-r--r-- | cli_args.go | 3 | ||||
| -rw-r--r-- | init_dir.go | 2 | ||||
| -rw-r--r-- | internal/configfile/config_file.go | 26 | ||||
| -rw-r--r-- | internal/configfile/config_test.go | 13 | ||||
| -rw-r--r-- | tests/cli/cli_test.go | 5 | 
6 files changed, 49 insertions, 7 deletions
| diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index efb8565..d3a6c81 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -51,6 +51,13 @@ be suitable.  #### -d, -debug  Enable debug output +#### -devrandom +Use /dev/random for generating the master key instead of the default Go +implementation. This is especially useful on embedded systems with Go versions +prior to 1.9, which fall back to weak random data when the getrandom syscall +is blocking. Using this option can block indefinitely when the kernel cannot +harvest enough entropy. +  #### -extpass string  Use an external program (like ssh-askpass) for the password prompt.  The program should return the password on stdout, a trailing newline is diff --git a/cli_args.go b/cli_args.go index 71ad6bd..7bde89d 100644 --- a/cli_args.go +++ b/cli_args.go @@ -22,7 +22,7 @@ type argContainer struct {  	plaintextnames, quiet, nosyslog, wpanic,  	longnames, allow_other, ro, reverse, aessiv, nonempty, raw64,  	noprealloc, speed, hkdf, serialize_reads, forcedecode, hh, info, -	sharedstorage bool +	sharedstorage, devrandom bool  	masterkey, mountpoint, cipherdir, cpuprofile, extpass,  	memprofile, ko, passfile, ctlsock, fsname, force_owner, trace string  	// Configuration file name override @@ -132,6 +132,7 @@ func parseCliOpts() (args argContainer) {  	flagSet.BoolVar(&args.hh, "hh", false, "Show this long help text")  	flagSet.BoolVar(&args.info, "info", false, "Display information about CIPHERDIR")  	flagSet.BoolVar(&args.sharedstorage, "sharedstorage", false, "Make concurrent access to a shared CIPHERDIR safer") +	flagSet.BoolVar(&args.devrandom, "devrandom", false, "Use /dev/random for generating master key")  	flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key")  	flagSet.StringVar(&args.cpuprofile, "cpuprofile", "", "Write cpu profile to specified file")  	flagSet.StringVar(&args.memprofile, "memprofile", "", "Write memory profile to specified file") diff --git a/init_dir.go b/init_dir.go index 20c9fd9..f057bf4 100644 --- a/init_dir.go +++ b/init_dir.go @@ -39,7 +39,7 @@ func initDir(args *argContainer) {  	password := readpassword.Twice(args.extpass)  	readpassword.CheckTrailingGarbage()  	creator := tlog.ProgramName + " " + GitVersion -	err = configfile.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn, creator, args.aessiv) +	err = configfile.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn, creator, args.aessiv, args.devrandom)  	if err != nil {  		tlog.Fatal.Println(err)  		os.Exit(exitcodes.WriteConf) diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index fea4a84..67d67f0 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -5,7 +5,9 @@ package configfile  import (  	"encoding/json"  	"fmt" +	"io"  	"io/ioutil" +	"log"  	"github.com/rfjakob/gocryptfs/internal/contentenc"  	"github.com/rfjakob/gocryptfs/internal/cryptocore" @@ -47,10 +49,25 @@ type ConfFile struct {  	filename string  } +// randBytesDevRandom gets "n" random bytes from /dev/random or panics +func randBytesDevRandom(n int) []byte { +	f, err := os.Open("/dev/random") +	if err != nil { +		log.Panic("Failed to open /dev/random: " + err.Error()) +	} +	defer f.Close() +	b := make([]byte, n) +	_, err = io.ReadFull(f, b) +	if err != nil { +		log.Panic("Failed to read random bytes: " + err.Error()) +	} +	return b +} +  // CreateConfFile - create a new config with a random key encrypted with  // "password" and write it to "filename".  // Uses scrypt with cost parameter logN. -func CreateConfFile(filename string, password string, plaintextNames bool, logN int, creator string, aessiv bool) error { +func CreateConfFile(filename string, password string, plaintextNames bool, logN int, creator string, aessiv bool, devrandom bool) error {  	var cf ConfFile  	cf.filename = filename  	cf.Creator = creator @@ -72,7 +89,12 @@ func CreateConfFile(filename string, password string, plaintextNames bool, logN  	}  	// Generate new random master key -	key := cryptocore.RandBytes(cryptocore.KeyLen) +	var key []byte +	if devrandom { +		key = randBytesDevRandom(cryptocore.KeyLen) +	} else { +		key = cryptocore.RandBytes(cryptocore.KeyLen) +	}  	// Encrypt it using the password  	// This sets ScryptObject and EncryptedKey diff --git a/internal/configfile/config_test.go b/internal/configfile/config_test.go index dc796ea..b984a37 100644 --- a/internal/configfile/config_test.go +++ b/internal/configfile/config_test.go @@ -60,7 +60,7 @@ func TestLoadV2StrangeFeature(t *testing.T) {  }  func TestCreateConfDefault(t *testing.T) { -	err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", false) +	err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", false, false)  	if err != nil {  		t.Fatal(err)  	} @@ -80,8 +80,15 @@ func TestCreateConfDefault(t *testing.T) {  	}  } +func TestCreateConfDevRandom(t *testing.T) { +	err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", false, true) +	if err != nil { +		t.Fatal(err) +	} +} +  func TestCreateConfPlaintextnames(t *testing.T) { -	err := CreateConfFile("config_test/tmp.conf", "test", true, 10, "test", false) +	err := CreateConfFile("config_test/tmp.conf", "test", true, 10, "test", false, false)  	if err != nil {  		t.Fatal(err)  	} @@ -102,7 +109,7 @@ func TestCreateConfPlaintextnames(t *testing.T) {  // Reverse mode uses AESSIV  func TestCreateConfFileAESSIV(t *testing.T) { -	err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", true) +	err := CreateConfFile("config_test/tmp.conf", "test", false, 10, "test", true, false)  	if err != nil {  		t.Fatal(err)  	} diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go index 97de8da..c7752f2 100644 --- a/tests/cli/cli_test.go +++ b/tests/cli/cli_test.go @@ -34,6 +34,11 @@ func TestInit(t *testing.T) {  	}  } +// Test -init with -devrandom flag +func TestInitDevRandom(t *testing.T) { +	test_helpers.InitFS(t, "-devrandom") +} +  // Test -init with -aessiv  func TestInitAessiv(t *testing.T) {  	dir := test_helpers.InitFS(t, "-aessiv") | 
