Skip to content

Commit 3ccd8cf

Browse files
committed
Implemented the support of Trezor devices.
1 parent f02fa5c commit 3ccd8cf

File tree

1 file changed

+72
-8
lines changed

1 file changed

+72
-8
lines changed

internal/readpassword/trezor.go

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,86 @@ import (
55

66
"github.com/rfjakob/gocryptfs/internal/exitcodes"
77
"github.com/rfjakob/gocryptfs/internal/tlog"
8+
9+
"github.com/xaionaro-go/cryptoWallet"
10+
"github.com/xaionaro-go/cryptoWallet/vendors"
811
)
912

10-
// Trezor reads 16 deterministically derived bytes from a
13+
// It's required initial values to be constant to get the resulting key to
14+
// be deterministic (see the comment above and within function "Trezor()").
15+
// This values could be just a bunch of zeros, but it seems to be a little
16+
// degenerate case that may add risks, so random values were used.
17+
//
18+
// This values were generated using command:
19+
// dd if=/dev/random of=/dev/stdout bs=48 count=1 2>/dev/null | hexdump -e '8/1 "0x%02x, " "\n"'
20+
var (
21+
TREZOR_DUMMYKEY = []byte{
22+
0xfc, 0x3b, 0xe3, 0xa6, 0xe6, 0x61, 0x32, 0xbc,
23+
0x95, 0x86, 0x79, 0x06, 0x70, 0xf9, 0x7c, 0x0a,
24+
0xab, 0x05, 0x3b, 0x12, 0xff, 0x4e, 0xa8, 0x8b,
25+
0x5b, 0x58, 0x0a, 0x8e, 0x42, 0xcf, 0x5e, 0x20,
26+
}
27+
TREZOR_NONCE = []byte{
28+
0xc9, 0xf1, 0x6d, 0xab, 0xba, 0x16, 0x68, 0xc9,
29+
0xcc, 0xb6, 0xb2, 0xcd, 0xbc, 0x4a, 0xb6, 0xcb,
30+
}
31+
TREZOR_KEY_NAME = "gocryptfs"
32+
TREZOR_KEY_DERIVATION_PATH = `m/10019'/0'/0'/0'`
33+
)
34+
35+
func trezorGetPin(title, description, ok, cancel string) ([]byte, error) {
36+
return Once("", title), nil
37+
}
38+
func trezorGetConfirm(title, description, ok, cancel string) (bool, error) {
39+
return false, nil // do not retry on connection failure
40+
}
41+
42+
// Trezor reads 32 deterministically derived bytes from a
1143
// SatoshiLabs Trezor USB security module.
1244
// The bytes are pseudorandom binary data and may contain null bytes.
13-
// This function either succeeds and returns 16 bytes or calls os.Exit to end
45+
// This function either succeeds and returns 32 bytes or calls os.Exit to end
1446
// the application.
1547
func Trezor() []byte {
16-
var err error
17-
// TODO try to read bytes here....
18-
// Handle errors
48+
trezor := cryptoWallet.Find(cryptoWallet.Filter{
49+
VendorId: &[]uint16{vendors.GetVendorId("satoshilabs")}[0],
50+
ProductIds: []uint16{1 /* Trezor One */},
51+
})
52+
53+
if trezor == nil {
54+
tlog.Fatal.Printf("Trezor device is not found. Check the connection.")
55+
os.Exit(exitcodes.TrezorError)
56+
}
57+
58+
// Trezor may ask for PIN or Passphrase. Setting the handler for this case.
59+
trezor.SetGetPinFunc(trezorGetPin)
60+
61+
// In some cases (like lost connection to the Trezor device and cannot
62+
// reconnect) it's required to get a confirmation from the user to
63+
// retry to reconnect. Setting the handler for this case.
64+
trezor.SetGetConfirmFunc(trezorGetConfirm)
65+
66+
// To generate a deterministic the key we trying to decrypt our
67+
// predefined constant key using the Trezor device. The resulting key
68+
// will depend on next variables:
69+
// * the Trezor master key;
70+
// * the passphrase (passed to the Trezor).
71+
//
72+
// The right key will be received only if both values (mentioned
73+
// above) are correct.
74+
//
75+
// Note:
76+
// Also the resulting key depends on this values (that we defined as
77+
// constants above):
78+
// * the key derivation path;
79+
// * the "encrypted" key;
80+
// * the nonce;
81+
// * the key name.
82+
key, err := trezor.DecryptKey(TREZOR_KEY_DERIVATION_PATH, TREZOR_DUMMYKEY, TREZOR_NONCE, TREZOR_KEY_NAME)
1983
if err != nil {
20-
tlog.Fatal.Printf("xxx some error was encountered...")
84+
tlog.Fatal.Printf("Cannot get the key from the Trezor device. Error description:\n\t%v", err.Error())
2185
os.Exit(exitcodes.TrezorError)
2286
}
2387

24-
tlog.Warn.Println("XXX readpassword.Trezor(): not implemented yet - returning hardcoded dummy bytes XXX")
25-
return []byte("1234567890123456")
88+
// Everything ok
89+
return key
2690
}

0 commit comments

Comments
 (0)