1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 20:11:00 +00:00

core/sd-protect: If writing to the SD card fails in request_sd_salt(), inform the user and allow them to retry or abort.

This commit is contained in:
Andrew Kozlik 2019-10-18 13:53:00 +02:00
parent 236b6334c6
commit 39b4376b65

View File

@ -30,7 +30,7 @@ async def _wrong_card_dialog(ctx: Optional[wire.Context]) -> None:
text.br_half() text.br_half()
if SD_CARD_HOT_SWAPPABLE: if SD_CARD_HOT_SWAPPABLE:
text.normal("Please insert the", "correct SD card for", "this device.") text.normal("Please insert the", "correct SD card for", "this device.")
btn_confirm = "Retry" btn_confirm = "Retry" # type: Optional[str]
btn_cancel = "Abort" btn_cancel = "Abort"
else: else:
text.normal("Please unplug the", "device and insert the", "correct SD card.") text.normal("Please unplug the", "device and insert the", "correct SD card.")
@ -51,7 +51,7 @@ async def _insert_card_dialog(ctx: Optional[wire.Context]) -> None:
text.br_half() text.br_half()
if SD_CARD_HOT_SWAPPABLE: if SD_CARD_HOT_SWAPPABLE:
text.normal("Please insert your", "SD card.") text.normal("Please insert your", "SD card.")
btn_confirm = "Retry" btn_confirm = "Retry" # type: Optional[str]
btn_cancel = "Abort" btn_cancel = "Abort"
else: else:
text.normal("Please unplug the", "device and insert your", "SD card.") text.normal("Please unplug the", "device and insert your", "SD card.")
@ -88,6 +88,27 @@ def _get_salt_path(new: bool = False) -> str:
return "%s/salt" % _get_device_dir() return "%s/salt" % _get_device_dir()
def _load_salt(fs: io.FatFS, auth_key: bytes, path: str) -> Optional[bytearray]:
# Load the salt file if it exists.
try:
with fs.open(path, "r") as f:
salt = bytearray(SD_SALT_LEN_BYTES)
stored_tag = bytearray(SD_SALT_AUTH_TAG_LEN_BYTES)
f.read(salt)
f.read(stored_tag)
except OSError:
return None
# Check the salt's authentication tag.
computed_tag = hmac.new(auth_key, salt, sha256).digest()[
:SD_SALT_AUTH_TAG_LEN_BYTES
]
if not consteq(computed_tag, stored_tag):
return None
return salt
async def request_sd_salt( async def request_sd_salt(
ctx: Optional[wire.Context], salt_auth_key: bytes ctx: Optional[wire.Context], salt_auth_key: bytes
) -> bytearray: ) -> bytearray:
@ -102,56 +123,34 @@ async def request_sd_salt(
try: try:
fs.mount() fs.mount()
salt = _load_salt(fs, salt_auth_key, salt_path)
# Load salt if it exists. if salt is not None:
salt = None # type: Optional[bytearray]
try:
with fs.open(salt_path, "r") as f:
salt = bytearray(SD_SALT_LEN_BYTES)
salt_tag = bytearray(SD_SALT_AUTH_TAG_LEN_BYTES)
f.read(salt)
f.read(salt_tag)
except OSError:
salt = None
if salt is not None and consteq(
hmac.new(salt_auth_key, salt, sha256).digest()[
:SD_SALT_AUTH_TAG_LEN_BYTES
],
salt_tag,
):
return salt return salt
# Load salt.new if it exists. # Check if there is a new salt.
new_salt = None # type: Optional[bytearray] salt = _load_salt(fs, salt_auth_key, new_salt_path)
try: if salt is not None:
with fs.open(new_salt_path, "r") as f:
new_salt = bytearray(SD_SALT_LEN_BYTES)
new_salt_tag = bytearray(SD_SALT_AUTH_TAG_LEN_BYTES)
f.read(new_salt)
f.read(new_salt_tag)
except OSError:
new_salt = None
if new_salt is not None and consteq(
hmac.new(salt_auth_key, new_salt, sha256).digest()[
:SD_SALT_AUTH_TAG_LEN_BYTES
],
new_salt_tag,
):
# SD salt regeneration was interrupted earlier. Bring into consistent state. # SD salt regeneration was interrupted earlier. Bring into consistent state.
# TODO Possibly overwrite salt file with random data. # TODO Possibly overwrite salt file with random data.
try: try:
fs.unlink(salt_path) fs.unlink(salt_path)
except OSError: except OSError:
pass pass
fs.rename(new_salt_path, salt_path)
return new_salt try:
fs.rename(new_salt_path, salt_path)
except OSError:
error_dialog = _write_failed_dialog(ctx)
else:
return salt
else:
# No valid salt file on this SD card.
error_dialog = _wrong_card_dialog(ctx)
finally: finally:
fs.unmount() fs.unmount()
sd.power(False) sd.power(False)
await _wrong_card_dialog(ctx) await error_dialog
async def set_sd_salt( async def set_sd_salt(
@ -195,7 +194,7 @@ async def commit_sd_salt(ctx: Optional[wire.Context]) -> None:
sd = io.SDCard() sd = io.SDCard()
fs = io.FatFS() fs = io.FatFS()
if not sd.power(True): if not sd.power(True):
raise IOError raise OSError
try: try:
fs.mount() fs.mount()
@ -216,7 +215,7 @@ async def remove_sd_salt(ctx: Optional[wire.Context]) -> None:
sd = io.SDCard() sd = io.SDCard()
fs = io.FatFS() fs = io.FatFS()
if not sd.power(True): if not sd.power(True):
raise IOError raise OSError
try: try:
fs.mount() fs.mount()