Closed prusnak closed 5 years ago
Terminology I propose using the term "SD salt" or "external salt" rather than "entropy". The reason is that this data will be combined with the PIN using PBKDF2 and it will be appended to the salt parameter which currently consists of "random salt" stored in the NV RAM and "hardware salt".
Requirements
Implementation details
Possible future features to consider
This would increase flash degradation, so it should be an optional setting.
Maybe we can do the following trick to avoid flash degradation when replacing the salt:
salt
filesalt.new
salt
filesalt.new
to saltThis might force FAT to use new blocks every time for a new entropy file, but we should test it. Also it is a non atomic operation.
- keep the original
salt
file- store the new salt in
salt.new
- erase
salt
file- rename
salt.new
to salt
this makes old salts recoverable. is that a problem? it doesn't seem to be, but?
- keep the original
salt
file- store the new salt in
salt.new
- erase
salt
file- rename
salt.new
to saltthis makes old salts recoverable. is that a problem? it doesn't seem to be, but?
Making old salts recoverable would be a bit problematic. Consider a scenario where an attacker tampers with the Trezor and manages to read out the internal NVRAM, then at some later time the attacker gains access to the SD card. If the user suspects that somebody tampered with their Trezor, then they could regenerate the salt and think they are safe. But if old salts are recoverable then the attacker could still decrypt the state of the storage as it was at the moment of tampering and gain access to the seed. On the other hand if the attacker gained access to the Trezor, then they could have done worse things. For example replaced the user's Trezor with a fake one, which would send all data from the SD card to the attacker as soon as it is plugged in.
In any case, I assumed that in step 3 above we would overwrite the original salt file with random data. To be more precise:
salt
filesalt.new
salt
file with random datasalt.new
to saltIn any case, I assumed that in step 3 above we would overwrite the original salt file with random data. To be more precise:
That makes the exercise pointless from the flash wear standpoint.
But in any case we are still wearing out the FAT segment. Isn't this a moot point though? How susceptible are today's SD cards to flash wear?
I started work on this feature: https://github.com/trezor/trezor-firmware/tree/andrewkozlik/sd-salt. The implementation seems to be working well on the emulator, but I haven't had time to test it all that much. I didn't do any testing whatsoever on the device. @stick please have a look to check that I am using the SD card and FATFS correctly.
TODOs
Notes In the core code I refer to the salt as "SD card salt", but in the storage code I refer to it as "external salt". Right now it's the same thing, but later on the external salt will be a combination of different salts from different sources.
Note that when this is merged with the FIDO2 branch, the check_pin() function in core/src/apps/webauthn/init.py will need to take retrieve the salt. This is similar to the change made in recovery_device/init.py.
It would be good to delegate the whole PIN checking procedure to a separate function, because it is getting complicated - get PIN from user, check if SD salt is in use, get salt from SD card, check PIN. Right now this code is duplicated in various forms in several places.
Testing Some test scenarios that come to mind:
The implementation is finished, but I think we still need to make a final decision on the naming of this feature. In case "SD card salt" is not suitable, it would be best to change the message name (SdSalt) and trezorctl command name (currently sd-salt) accordingly before merging. I prepared a short description of this feature for the wiki, which might help us identify some key words:
This feature serves as additional protection against physical attacks. When it is enabled, a randomly generated secret is stored on the SD card. During every PIN checking and unlocking operation this secret is combined with the entered PIN value to decrypt data stored on the device. Simply put, the device gets bound to the SD card and cannot be unlocked without it. However, if the SD card is lost or damaged the device can still be factory-reset or recovered using the backup seed.
Some names that come to mind (with trezorctl command and example usage):
sd-protect
, "secure your Trezor with SD card protection" sd-salt
, "secure your Trezor with with SD card salt"sd-lock
, "lock your Trezor with an SD card"sd-encrypt
, "encrypt the storage with SD card salt"sd-bind
, "bind your Trezor with an SD card"sd-key
, "secure your Trezor with SD card key"sd-armor
, "secure your Trezor with SD card armor"Let's have a vote on Monday :-)
The results of the vote, "+" indicates a vote for, "-" indicates a vote against:
(-1, +4) sd-protect
: +@tsusanka , -@ciny , +@hiviah , +@prusnak , +@bentonoliver
(-2, +1) sd-salt
: -@tsusanka , +@hiviah , -@prusnak
(-1, +0) sd-lock
: -@prusnak
(-3, +0) sd-encrypt
: -@andrewkozlik , -@onvej , -@prusnak
(-0, +2) sd-bind
: +@tsusanka , +@bentonoliver
(-2, +0) sd-key
: -@onvej , -@prusnak
(I am not sure I captured all votes, so feel free to edit the above.)
Some opinions that people expressed:
@bentonoliver, @hiviah any opinions?
I think actually "salt" means something to many users who heard at least something about cryptography. "sd-protect" would be second, but it's too generic.
So
++ sd-bind ++ sd-protect Because both describe the intended result (as opposed to "salt" or "key").
Closed via #526
Testing @sorooris
You will need two FAT32-formatted SD cards. You will also need to be using the current version of trezorctl. Clone the trezor-firmware repo if you don't have it yet and execute the following:
cd trezor-firmware
git checkout master
git pull
pipenv shell
# Type any trezorctl commands into this shell.
There is one new command for this feature in trezorctl:
trezorctl sd-protect --help
trezorctl sd-protect enable
trezorctl sd-protect refresh
trezorctl sd-protect disable
Basic flow:
trezorctl sd-protect enable
. Verify that the device asks for confirmation. Note: We are still experiencing random failures when writing to the SD card, so if this step fails, then try repeating it several times. Verify that it fails gracefully.trezorctl sd-protect disable
. Verify that the device asks for confirmation.Scenarios (some copied from above for convenience):
trezorctl sd-protect refresh
.
Depends on merging https://github.com/trezor/trezor-firmware/pull/264
If the file named
/trezor/entropy
is found on the SD card during the boot, open the file, hash it and use the result as an extra entropy when initializing the encrypted storage.We need to discuss the following: 1) how do we transition from regular storage to storage+sd_entropy storage (i.e. do we only allow this via the process on Trezor or can a user create their own entropy file manually on PC?) 2) do we need to store a special flag in the storage? (bool use_sd_card_entropy) - this would be very helpful, but we might need to initialize the storage twice?