summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2018-06-25 22:27:15 +0200
committerJakob Unterwurzacher2018-07-01 20:56:22 +0200
commit9a15dfa494c76b5fcadcd32e2e46cbee84218a87 (patch)
tree5dcb84d222f355750d1b0773660b891b509dadb1
parent91de77943fba3cb993aad4e9756e159c4514764a (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.go7
-rw-r--r--internal/configfile/config_file.go9
-rw-r--r--internal/configfile/config_test.go8
-rw-r--r--internal/readpassword/trezor.go13
-rw-r--r--main.go2
-rw-r--r--tests/trezor/trezor_test.go3
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")
}
diff --git a/main.go b/main.go
index da5360b..404a95b 100644
--- a/main.go
+++ b/main.go
@@ -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).