Ejemplo n.º 1
0
async def bootscreen() -> None:
    ui.display.orientation(storage_device.get_rotation())
    salt_auth_key = storage_device.get_sd_salt_auth_key()

    while True:
        try:
            if salt_auth_key is not None or config.has_pin():
                await lockscreen()

            if salt_auth_key is not None:
                salt = await request_sd_salt(None, salt_auth_key
                                             )  # type: Optional[bytearray]
            else:
                salt = None

            if not config.has_pin():
                config.unlock(pin_to_int(""), salt)
                storage.init_unlocked()
                return

            label = "Enter your PIN"
            while True:
                pin = await request_pin(label, config.get_pin_rem())
                if config.unlock(pin_to_int(pin), salt):
                    storage.init_unlocked()
                    return
                else:
                    label = "Wrong PIN, enter again"
        except (OSError, PinCancelled, SdProtectCancelled) as e:
            if __debug__:
                log.exception(__name__, e)
        except BaseException as e:
            utils.halt(e.__class__.__name__)
Ejemplo n.º 2
0
async def sd_protect_disable(ctx: wire.Context, msg: SdProtect) -> Success:
    if device.get_sd_salt_auth_key() is None:
        raise wire.ProcessError("SD card protection not enabled")

    # Confirm that user wants to proceed with the operation.
    await require_confirm_sd_protect(ctx, msg)

    # Get the current PIN and salt from the SD card.
    pin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN")

    # Check PIN and remove salt.
    if not config.change_pin(pin_to_int(pin), pin_to_int(pin), salt, None):
        await show_pin_invalid(ctx)
        raise wire.PinInvalid("PIN invalid")

    device.set_sd_salt_auth_key(None)

    try:
        # Clean up.
        await remove_sd_salt(ctx)
    except Exception:
        # The cleanup is not necessary for the correct functioning of
        # SD-protection. If it fails for any reason, we suppress the exception,
        # because overall SD-protection was successfully disabled.
        pass

    await show_success(ctx,
                       ("You have successfully", "disabled SD protection."))
    return Success(message="SD card protection disabled")
Ejemplo n.º 3
0
async def request_pin_and_sd_salt(
    ctx: wire.Context, prompt: str = "Enter your PIN", allow_cancel: bool = True
) -> Tuple[str, Optional[bytearray]]:
    salt_auth_key = device.get_sd_salt_auth_key()
    if salt_auth_key is not None:
        salt = await request_sd_salt(ctx, salt_auth_key)  # type: Optional[bytearray]
    else:
        salt = None

    if config.has_pin():
        pin = await request_pin_ack(ctx, prompt, config.get_pin_rem(), allow_cancel)
    else:
        pin = ""

    return pin, salt
Ejemplo n.º 4
0
async def sd_protect_enable(ctx: wire.Context, msg: SdProtect) -> Success:
    salt_auth_key = device.get_sd_salt_auth_key()
    if salt_auth_key is not None:
        raise wire.ProcessError("SD card protection already enabled")

    # Confirm that user wants to proceed with the operation.
    await require_confirm_sd_protect(ctx, msg)

    # Get the current PIN.
    if config.has_pin():
        pin = pin_to_int(await request_pin_ack(ctx, "Enter PIN",
                                               config.get_pin_rem()))
    else:
        pin = pin_to_int("")

    # Check PIN and prepare salt file.
    salt = random.bytes(SD_SALT_LEN_BYTES)
    salt_auth_key = random.bytes(SD_SALT_AUTH_KEY_LEN_BYTES)
    salt_tag = hmac.new(salt_auth_key, salt,
                        sha256).digest()[:SD_SALT_AUTH_TAG_LEN_BYTES]
    try:
        await set_sd_salt(ctx, salt, salt_tag)
    except Exception:
        raise wire.ProcessError("Failed to write to SD card")

    if not config.change_pin(pin, pin, None, salt):
        # Wrong PIN. Clean up the prepared salt file.
        try:
            await remove_sd_salt(ctx)
        except Exception:
            # The cleanup is not necessary for the correct functioning of
            # SD-protection. If it fails for any reason, we suppress the
            # exception, because primarily we need to raise wire.PinInvalid.
            pass
        await show_pin_invalid(ctx)
        raise wire.PinInvalid("PIN invalid")

    device.set_sd_salt_auth_key(salt_auth_key)

    await show_success(ctx,
                       ("You have successfully", "enabled SD protection."))
    return Success(message="SD card protection enabled")
Ejemplo n.º 5
0
async def verify_user_pin(
    prompt: str = "Enter your PIN", allow_cancel: bool = True, retry: bool = True
) -> None:
    salt_auth_key = device.get_sd_salt_auth_key()
    if salt_auth_key is not None:
        salt = await request_sd_salt(None, salt_auth_key)  # type: Optional[bytearray]
    else:
        salt = None

    if not config.has_pin() and not config.check_pin(pin_to_int(""), salt):
        raise RuntimeError

    while retry:
        pin = await request_pin(prompt, config.get_pin_rem(), allow_cancel)
        if config.check_pin(pin_to_int(pin), salt):
            return
        else:
            prompt = "Wrong PIN, enter again"

    raise PinInvalid
Ejemplo n.º 6
0
async def sd_protect_refresh(ctx: wire.Context, msg: SdProtect) -> Success:
    if device.get_sd_salt_auth_key() is None:
        raise wire.ProcessError("SD card protection not enabled")

    # Confirm that user wants to proceed with the operation.
    await require_confirm_sd_protect(ctx, msg)

    # Get the current PIN and salt from the SD card.
    pin, old_salt = await request_pin_and_sd_salt(ctx, "Enter PIN")

    # Check PIN and change salt.
    new_salt = random.bytes(SD_SALT_LEN_BYTES)
    new_salt_auth_key = random.bytes(SD_SALT_AUTH_KEY_LEN_BYTES)
    new_salt_tag = hmac.new(new_salt_auth_key, new_salt,
                            sha256).digest()[:SD_SALT_AUTH_TAG_LEN_BYTES]
    try:
        await stage_sd_salt(ctx, new_salt, new_salt_tag)
    except Exception:
        raise wire.ProcessError("Failed to write to SD card")

    if not config.change_pin(pin_to_int(pin), pin_to_int(pin), old_salt,
                             new_salt):
        await show_pin_invalid(ctx)
        raise wire.PinInvalid("PIN invalid")

    device.set_sd_salt_auth_key(new_salt_auth_key)

    try:
        # Clean up.
        await commit_sd_salt(ctx)
    except Exception:
        # If the cleanup fails, then request_sd_salt() will bring the SD card
        # into a consistent state. We suppress the exception, because overall
        # SD-protection was successfully refreshed.
        pass

    await show_success(ctx,
                       ("You have successfully", "refreshed SD protection."))
    return Success(message="SD card protection refreshed")