-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support of (open)hardware cryptographic module "Trezor One". The second try. #247
Changes from 1 commit
3ccd8cf
a2e2e38
ce37f8f
06e92a9
17c90e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,22 +5,86 @@ import ( | |
|
||
"github.com/rfjakob/gocryptfs/internal/exitcodes" | ||
"github.com/rfjakob/gocryptfs/internal/tlog" | ||
|
||
"github.com/xaionaro-go/cryptoWallet" | ||
"github.com/xaionaro-go/cryptoWallet/vendors" | ||
) | ||
|
||
// Trezor reads 16 deterministically derived bytes from a | ||
// It's required initial values to be constant to get the resulting key to | ||
// be deterministic (see the comment above and within function "Trezor()"). | ||
// This values could be just a bunch of zeros, but it seems to be a little | ||
// degenerate case that may add risks, so random values were used. | ||
// | ||
// This values were generated using command: | ||
// dd if=/dev/random of=/dev/stdout bs=48 count=1 2>/dev/null | hexdump -e '8/1 "0x%02x, " "\n"' | ||
var ( | ||
TREZOR_DUMMYKEY = []byte{ | ||
0xfc, 0x3b, 0xe3, 0xa6, 0xe6, 0x61, 0x32, 0xbc, | ||
0x95, 0x86, 0x79, 0x06, 0x70, 0xf9, 0x7c, 0x0a, | ||
0xab, 0x05, 0x3b, 0x12, 0xff, 0x4e, 0xa8, 0x8b, | ||
0x5b, 0x58, 0x0a, 0x8e, 0x42, 0xcf, 0x5e, 0x20, | ||
} | ||
TREZOR_NONCE = []byte{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to slip-0011.md, the IV is optional, and I don't see that it adds security - let's skip it. |
||
0xc9, 0xf1, 0x6d, 0xab, 0xba, 0x16, 0x68, 0xc9, | ||
0xcc, 0xb6, 0xb2, 0xcd, 0xbc, 0x4a, 0xb6, 0xcb, | ||
} | ||
TREZOR_KEY_NAME = "gocryptfs" | ||
TREZOR_KEY_DERIVATION_PATH = `m/10019'/0'/0'/0'` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These can be There are a few places in gocryptfs that use this style, like As you suggested, let's use |
||
) | ||
|
||
func trezorGetPin(title, description, ok, cancel string) ([]byte, error) { | ||
return Once("", title), nil | ||
} | ||
func trezorGetConfirm(title, description, ok, cancel string) (bool, error) { | ||
return false, nil // do not retry on connection failure | ||
} | ||
|
||
// Trezor reads 32 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 | ||
// This function either succeeds and returns 32 bytes or calls os.Exit to end | ||
// the application. | ||
func Trezor() []byte { | ||
var err error | ||
// TODO try to read bytes here.... | ||
// Handle errors | ||
trezor := cryptoWallet.Find(cryptoWallet.Filter{ | ||
VendorId: &[]uint16{vendors.GetVendorId("satoshilabs")}[0], | ||
ProductIds: []uint16{1 /* Trezor One */}, | ||
}) | ||
|
||
if trezor == nil { | ||
tlog.Fatal.Printf("Trezor device is not found. Check the connection.") | ||
os.Exit(exitcodes.TrezorError) | ||
} | ||
|
||
// Trezor may ask for PIN or Passphrase. Setting the handler for this case. | ||
trezor.SetGetPinFunc(trezorGetPin) | ||
|
||
// In some cases (like lost connection to the Trezor device and cannot | ||
// reconnect) it's required to get a confirmation from the user to | ||
// retry to reconnect. Setting the handler for this case. | ||
trezor.SetGetConfirmFunc(trezorGetConfirm) | ||
|
||
// To generate a deterministic the key we trying to decrypt our | ||
// predefined constant key using the Trezor device. The resulting key | ||
// will depend on next variables: | ||
// * the Trezor master key; | ||
// * the passphrase (passed to the Trezor). | ||
// | ||
// The right key will be received only if both values (mentioned | ||
// above) are correct. | ||
// | ||
// Note: | ||
// Also the resulting key depends on this values (that we defined as | ||
// constants above): | ||
// * the key derivation path; | ||
// * the "encrypted" key; | ||
// * the nonce; | ||
// * the key name. | ||
key, err := trezor.DecryptKey(TREZOR_KEY_DERIVATION_PATH, TREZOR_DUMMYKEY, TREZOR_NONCE, TREZOR_KEY_NAME) | ||
if err != nil { | ||
tlog.Fatal.Printf("xxx some error was encountered...") | ||
tlog.Fatal.Printf("Cannot get the key from the Trezor device. Error description:\n\t%v", err.Error()) | ||
os.Exit(exitcodes.TrezorError) | ||
} | ||
|
||
tlog.Warn.Println("XXX readpassword.Trezor(): not implemented yet - returning hardcoded dummy bytes XXX") | ||
return []byte("1234567890123456") | ||
// Everything ok | ||
return key | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with a "random" value like this is that you can never know if it has been chosen for a particular reason. Like, maybe this exact value exposes a weakness? No one can tell.
Let's just go with 16 zeros. AES handles that just fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid of kinda randbow tables (but to optimize of getting encryption keys instead of getting hash function initial values) for zero-filled data. I mean somebody like NSA could have optimized ways of getting keys using known blocks of encrypted and decrypted data where the encrypted data is a zero-filled data. I understand that sounds crazy, but I feel more secure to use random data… On the other hand I agree with your argument (I had the same thought while generating that random numbers) and zero-filled data looks more trustfully. OK :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can go for something like "gocryptfs.trezor" or "trezor.trezor.tr" or "tttttt..." if you prefer, I'm fine with that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, that's sounds more reassuringly, thanks)