diff options
| author | Jakob Unterwurzacher | 2018-06-25 22:27:15 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2018-07-01 20:56:22 +0200 | 
| commit | 9a15dfa494c76b5fcadcd32e2e46cbee84218a87 (patch) | |
| tree | 5dcb84d222f355750d1b0773660b891b509dadb1 | |
| parent | 91de77943fba3cb993aad4e9756e159c4514764a (diff) | |
trezor: add TrezorPayload
TrezorPayload stores 32 random bytes used for unlocking
the master key using a Trezor security module. The randomness makes sure
that a unique unlock value is used for each gocryptfs filesystem.
| -rw-r--r-- | init_dir.go | 7 | ||||
| -rw-r--r-- | internal/configfile/config_file.go | 9 | ||||
| -rw-r--r-- | internal/configfile/config_test.go | 8 | ||||
| -rw-r--r-- | internal/readpassword/trezor.go | 13 | ||||
| -rw-r--r-- | main.go | 2 | ||||
| -rw-r--r-- | tests/trezor/trezor_test.go | 3 | 
6 files changed, 31 insertions, 11 deletions
| diff --git a/init_dir.go b/init_dir.go index 0cd2957..e264cf0 100644 --- a/init_dir.go +++ b/init_dir.go @@ -8,6 +8,7 @@ import (  	"strings"  	"github.com/rfjakob/gocryptfs/internal/configfile" +	"github.com/rfjakob/gocryptfs/internal/cryptocore"  	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/nametransform"  	"github.com/rfjakob/gocryptfs/internal/readpassword" @@ -70,9 +71,11 @@ func initDir(args *argContainer) {  	}  	{  		var password []byte +		var trezorPayload []byte  		if args.trezor { +			trezorPayload = cryptocore.RandBytes(readpassword.TrezorPayloadLen)  			// Get binary data from from Trezor -			password = readpassword.Trezor() +			password = readpassword.Trezor(trezorPayload)  		} else {  			// Normal password entry  			password = readpassword.Twice(args.extpass) @@ -80,7 +83,7 @@ func initDir(args *argContainer) {  		}  		creator := tlog.ProgramName + " " + GitVersion  		err = configfile.Create(args.config, password, args.plaintextnames, -			args.scryptn, creator, args.aessiv, args.devrandom, args.trezor) +			args.scryptn, creator, args.aessiv, args.devrandom, trezorPayload)  		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 a70a511..c856ad0 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -45,6 +45,10 @@ type ConfFile struct {  	// mounting. This mechanism is analogous to the ext4 feature flags that are  	// stored in the superblock.  	FeatureFlags []string +	// TrezorPayload stores 32 random bytes used for unlocking the master key using +	// a Trezor security module. The randomness makes sure that a unique unlock +	// value is used for each gocryptfs filesystem. +	TrezorPayload []byte `json:",omitempty"`  	// Filename is the name of the config file. Not exported to JSON.  	filename string  } @@ -68,7 +72,7 @@ func randBytesDevRandom(n int) []byte {  // "password" and write it to "filename".  // Uses scrypt with cost parameter logN.  func Create(filename string, password []byte, plaintextNames bool, -	logN int, creator string, aessiv bool, devrandom bool, trezor bool) error { +	logN int, creator string, aessiv bool, devrandom bool, trezorPayload []byte) error {  	var cf ConfFile  	cf.filename = filename  	cf.Creator = creator @@ -88,8 +92,9 @@ func Create(filename string, password []byte, plaintextNames bool,  	if aessiv {  		cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagAESSIV])  	} -	if trezor { +	if len(trezorPayload) > 0 {  		cf.FeatureFlags = append(cf.FeatureFlags, knownFlags[FlagTrezor]) +		cf.TrezorPayload = trezorPayload  	}  	{  		// Generate new random master key diff --git a/internal/configfile/config_test.go b/internal/configfile/config_test.go index e130cfa..b8ee150 100644 --- a/internal/configfile/config_test.go +++ b/internal/configfile/config_test.go @@ -62,7 +62,7 @@ func TestLoadV2StrangeFeature(t *testing.T) {  }  func TestCreateConfDefault(t *testing.T) { -	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, false, false) +	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, false, nil)  	if err != nil {  		t.Fatal(err)  	} @@ -83,14 +83,14 @@ func TestCreateConfDefault(t *testing.T) {  }  func TestCreateConfDevRandom(t *testing.T) { -	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, true, false) +	err := Create("config_test/tmp.conf", testPw, false, 10, "test", false, true, nil)  	if err != nil {  		t.Fatal(err)  	}  }  func TestCreateConfPlaintextnames(t *testing.T) { -	err := Create("config_test/tmp.conf", testPw, true, 10, "test", false, false, false) +	err := Create("config_test/tmp.conf", testPw, true, 10, "test", false, false, nil)  	if err != nil {  		t.Fatal(err)  	} @@ -111,7 +111,7 @@ func TestCreateConfPlaintextnames(t *testing.T) {  // Reverse mode uses AESSIV  func TestCreateConfFileAESSIV(t *testing.T) { -	err := Create("config_test/tmp.conf", testPw, false, 10, "test", true, false, false) +	err := Create("config_test/tmp.conf", testPw, false, 10, "test", true, false, nil)  	if err != nil {  		t.Fatal(err)  	} diff --git a/internal/readpassword/trezor.go b/internal/readpassword/trezor.go index 37dde79..45edfd8 100644 --- a/internal/readpassword/trezor.go +++ b/internal/readpassword/trezor.go @@ -7,12 +7,22 @@ import (  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) +const ( +	// TrezorPayloadLen is the length of the payload data passed to Trezor's +	// CipherKeyValue function. +	TrezorPayloadLen = 32 +) +  // Trezor reads 16 deterministically derived bytes from a  // SatoshiLabs Trezor USB security module.  // The bytes are pseudorandom binary data and may contain null bytes.  // This function either succeeds and returns 16 bytes or calls os.Exit to end  // the application. -func Trezor() []byte { +func Trezor(payload []byte) []byte { +	if len(payload) != TrezorPayloadLen { +		tlog.Fatal.Printf("Invalid TrezorPayload length: wanted %d, got %d bytes\n", TrezorPayloadLen, len(payload)) +		os.Exit(exitcodes.LoadConf) +	}  	var err error  	// TODO try to read bytes here....  	// Handle errors @@ -20,7 +30,6 @@ func Trezor() []byte {  		tlog.Fatal.Printf("xxx some error was encountered...")  		os.Exit(exitcodes.TrezorError)  	} -  	tlog.Warn.Println("XXX readpassword.Trezor(): not implemented yet - returning hardcoded dummy bytes XXX")  	return []byte("1234567890123456")  } @@ -49,7 +49,7 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.Conf  	var pw []byte  	if cf1.IsFeatureFlagSet(configfile.FlagTrezor) {  		// Get binary data from from Trezor -		pw = readpassword.Trezor() +		pw = readpassword.Trezor(cf1.TrezorPayload)  	} else {  		// Normal password entry  		pw = readpassword.Once(args.extpass, "") diff --git a/tests/trezor/trezor_test.go b/tests/trezor/trezor_test.go index 5db56e2..59e10cb 100644 --- a/tests/trezor/trezor_test.go +++ b/tests/trezor/trezor_test.go @@ -42,6 +42,9 @@ func TestInitTrezor(t *testing.T) {  	if !c.IsFeatureFlagSet(configfile.FlagTrezor) {  		t.Error("Trezor flag should be set but is not")  	} +	if len(c.TrezorPayload) != 32 { +		t.Errorf("TrezorPayload has wrong length: %d", len(c.TrezorPayload)) +	}  }  // Test using -trezor together with -extpass. Should fail with code 1 (usage error). | 
