1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-02 19:40:57 +00:00

chore(core): decrease misc size by 430 bytes

This commit is contained in:
grdddj 2022-09-17 19:53:27 +02:00 committed by matejcik
parent d182ac5b53
commit 11fc2d36f7
5 changed files with 118 additions and 152 deletions

View File

@ -1,25 +1,25 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import wire
from trezor.crypto import aes, hmac
from trezor.messages import CipheredKeyValue
from trezor.ui.layouts import confirm_action
from apps.common.keychain import get_keychain
from apps.common.paths import AlwaysMatchingSchema
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.messages import CipherKeyValue from trezor.messages import CipherKeyValue, CipheredKeyValue
from trezor.wire import Context
# This module implements the SLIP-0011 symmetric encryption of key-value pairs using a # This module implements the SLIP-0011 symmetric encryption of key-value pairs using a
# deterministic hierarchy, see https://github.com/satoshilabs/slips/blob/master/slip-0011.md. # deterministic hierarchy, see https://github.com/satoshilabs/slips/blob/master/slip-0011.md.
async def cipher_key_value(ctx: wire.Context, msg: CipherKeyValue) -> CipheredKeyValue: async def cipher_key_value(ctx: Context, msg: CipherKeyValue) -> CipheredKeyValue:
from trezor.wire import DataError
from trezor.messages import CipheredKeyValue
from trezor.crypto import aes, hmac
from apps.common.keychain import get_keychain
from apps.common.paths import AlwaysMatchingSchema
from trezor.ui.layouts import confirm_action
keychain = await get_keychain(ctx, "secp256k1", [AlwaysMatchingSchema]) keychain = await get_keychain(ctx, "secp256k1", [AlwaysMatchingSchema])
if len(msg.value) % 16 > 0: if len(msg.value) % 16 > 0:
raise wire.DataError("Value length must be a multiple of 16") raise DataError("Value length must be a multiple of 16")
encrypt = msg.encrypt encrypt = msg.encrypt
decrypt = not msg.encrypt decrypt = not msg.encrypt
@ -31,11 +31,9 @@ async def cipher_key_value(ctx: wire.Context, msg: CipherKeyValue) -> CipheredKe
await confirm_action(ctx, "cipher_key_value", title, description=msg.key) await confirm_action(ctx, "cipher_key_value", title, description=msg.key)
node = keychain.derive(msg.address_n) node = keychain.derive(msg.address_n)
value = compute_cipher_key_value(msg, node.private_key())
return CipheredKeyValue(value=value)
# compute_cipher_key_value
def compute_cipher_key_value(msg: CipherKeyValue, seckey: bytes) -> bytes: seckey = node.private_key()
data = msg.key.encode() data = msg.key.encode()
data += b"E1" if msg.ask_on_encrypt else b"E0" data += b"E1" if msg.ask_on_encrypt else b"E0"
data += b"D1" if msg.ask_on_decrypt else b"D0" data += b"D1" if msg.ask_on_decrypt else b"D0"
@ -46,8 +44,11 @@ def compute_cipher_key_value(msg: CipherKeyValue, seckey: bytes) -> bytes:
else: else:
iv = data[32:48] iv = data[32:48]
ctx = aes(aes.CBC, key, iv) hash_ctx = aes(aes.CBC, key, iv)
if msg.encrypt: if msg.encrypt:
return ctx.encrypt(msg.value) value = hash_ctx.encrypt(msg.value)
else: else:
return ctx.decrypt(msg.value) value = hash_ctx.decrypt(msg.value)
# END compute_cipher_key_value
return CipheredKeyValue(value=value)

View File

@ -1,85 +1,67 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from ustruct import pack, unpack
from trezor import ui, wire
from trezor.crypto.hashlib import sha256
from trezor.messages import ECDHSessionKey
from trezor.ui.layouts import confirm_address
from apps.common.keychain import get_keychain
from apps.common.paths import HARDENED, AlwaysMatchingSchema
from .sign_identity import serialize_identity, serialize_identity_without_proto
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.messages import GetECDHSessionKey, IdentityType from trezor.messages import GetECDHSessionKey, ECDHSessionKey
from trezor.wire import Context
from apps.common.paths import Bip32Path
# This module implements the SLIP-0017 Elliptic Curve Diffie-Hellman algorithm, using a # This module implements the SLIP-0017 Elliptic Curve Diffie-Hellman algorithm, using a
# deterministic hierarchy, see https://github.com/satoshilabs/slips/blob/master/slip-0017.md. # deterministic hierarchy, see https://github.com/satoshilabs/slips/blob/master/slip-0017.md.
async def get_ecdh_session_key( async def get_ecdh_session_key(ctx: Context, msg: GetECDHSessionKey) -> ECDHSessionKey:
ctx: wire.Context, msg: GetECDHSessionKey from trezor.ui.layouts import confirm_address
) -> ECDHSessionKey: from .sign_identity import (
if msg.ecdsa_curve_name is None: get_identity_path,
msg.ecdsa_curve_name = "secp256k1" serialize_identity_without_proto,
serialize_identity,
keychain = await get_keychain(ctx, msg.ecdsa_curve_name, [AlwaysMatchingSchema])
identity = serialize_identity(msg.identity)
await require_confirm_ecdh_session_key(ctx, msg.identity)
address_n = get_ecdh_path(identity, msg.identity.index or 0)
node = keychain.derive(address_n)
session_key = ecdh(
seckey=node.private_key(),
peer_public_key=msg.peer_public_key,
curve=msg.ecdsa_curve_name,
) )
return ECDHSessionKey(session_key=session_key, public_key=node.public_key()) from trezor import ui
from trezor.wire import DataError
from trezor.messages import ECDHSessionKey
from apps.common.keychain import get_keychain
from apps.common.paths import AlwaysMatchingSchema
msg_identity = msg.identity # local_cache_attribute
peer_public_key = msg.peer_public_key # local_cache_attribute
curve_name = msg.ecdsa_curve_name or "secp256k1"
async def require_confirm_ecdh_session_key( keychain = await get_keychain(ctx, curve_name, [AlwaysMatchingSchema])
ctx: wire.Context, identity: IdentityType identity = serialize_identity(msg_identity)
) -> None:
proto = identity.proto.upper() if identity.proto else "identity" # require_confirm_ecdh_session_key
proto = msg_identity.proto.upper() if msg_identity.proto else "identity"
await confirm_address( await confirm_address(
ctx, ctx,
f"Decrypt {proto}", f"Decrypt {proto}",
serialize_identity_without_proto(identity), serialize_identity_without_proto(msg_identity),
description=None, None,
icon=ui.ICON_DEFAULT, icon=ui.ICON_DEFAULT,
icon_color=ui.ORANGE_ICON, icon_color=ui.ORANGE_ICON,
) )
# END require_confirm_ecdh_session_key
address_n = get_identity_path(identity, msg_identity.index or 0, 17)
node = keychain.derive(address_n)
def get_ecdh_path(identity: str, index: int) -> Bip32Path: # ecdh
identity_hash = sha256(pack("<I", index) + identity.encode()).digest() if curve_name == "secp256k1":
address_n = [HARDENED | x for x in (17,) + unpack("<IIII", identity_hash[:16])]
return address_n
def ecdh(seckey: bytes, peer_public_key: bytes, curve: str) -> bytes:
if curve == "secp256k1":
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
session_key = secp256k1.multiply(seckey, peer_public_key) session_key = secp256k1.multiply(node.private_key(), peer_public_key)
elif curve == "nist256p1": elif curve_name == "nist256p1":
from trezor.crypto.curve import nist256p1 from trezor.crypto.curve import nist256p1
session_key = nist256p1.multiply(seckey, peer_public_key) session_key = nist256p1.multiply(node.private_key(), peer_public_key)
elif curve == "curve25519": elif curve_name == "curve25519":
from trezor.crypto.curve import curve25519 from trezor.crypto.curve import curve25519
if peer_public_key[0] != 0x40: if peer_public_key[0] != 0x40:
raise wire.DataError("Curve25519 public key should start with 0x40") raise DataError("Curve25519 public key should start with 0x40")
session_key = b"\x04" + curve25519.multiply(seckey, peer_public_key[1:]) session_key = b"\x04" + curve25519.multiply(
node.private_key(), peer_public_key[1:]
)
else: else:
raise wire.DataError("Unsupported curve for ECDH: " + curve) raise DataError("Unsupported curve for ECDH: " + curve_name)
# END ecdh
return session_key return ECDHSessionKey(session_key=session_key, public_key=node.public_key())

View File

@ -1,22 +1,22 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor.crypto import random
from trezor.enums import ButtonRequestType
from trezor.messages import Entropy
from trezor.ui.layouts import confirm_action
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.wire import Context from trezor.wire import Context
from trezor.messages import GetEntropy from trezor.messages import GetEntropy, Entropy
async def get_entropy(ctx: Context, msg: GetEntropy) -> Entropy: async def get_entropy(ctx: Context, msg: GetEntropy) -> Entropy:
from trezor.crypto import random
from trezor.enums import ButtonRequestType
from trezor.messages import Entropy
from trezor.ui.layouts import confirm_action
await confirm_action( await confirm_action(
ctx, ctx,
"get_entropy", "get_entropy",
"Confirm entropy", "Confirm entropy",
action="Do you really want\nto send entropy?", "Do you really want\nto send entropy?",
description="Continue only if you\nknow what you are doing!", "Continue only if you\nknow what you are doing!",
br_code=ButtonRequestType.ProtectCall, br_code=ButtonRequestType.ProtectCall,
) )

View File

@ -1,16 +1,16 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from trezor import ui, wire, workflow
from trezor.messages import FirmwareHash
from trezor.ui.layouts import draw_simple_text
from trezor.utils import DISABLE_ANIMATION, firmware_hash
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.messages import GetFirmwareHash from trezor.messages import GetFirmwareHash, FirmwareHash
from trezor.wire import Context from trezor.wire import Context
async def get_firmware_hash(ctx: Context, msg: GetFirmwareHash) -> FirmwareHash: async def get_firmware_hash(ctx: Context, msg: GetFirmwareHash) -> FirmwareHash:
from trezor.messages import FirmwareHash
from trezor.utils import firmware_hash
from trezor.ui.layouts import draw_simple_text
from trezor import wire, workflow
workflow.close_others() workflow.close_others()
draw_simple_text("Please wait") draw_simple_text("Please wait")
@ -23,6 +23,9 @@ async def get_firmware_hash(ctx: Context, msg: GetFirmwareHash) -> FirmwareHash:
def _render_progress(progress: int, total: int) -> None: def _render_progress(progress: int, total: int) -> None:
from trezor.utils import DISABLE_ANIMATION
from trezor import ui
if not DISABLE_ANIMATION: if not DISABLE_ANIMATION:
p = 1000 * progress // total p = 1000 * progress // total
ui.display.loader(p, False, 18, ui.WHITE, ui.BG) ui.display.loader(p, False, 18, ui.WHITE, ui.BG)

View File

@ -1,38 +1,45 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from ustruct import pack, unpack
from trezor import wire
from trezor.crypto.hashlib import sha256 from trezor.crypto.hashlib import sha256
from trezor.messages import SignedIdentity
from trezor.ui.layouts import confirm_sign_identity
from apps.common import coininfo from apps.common import coininfo
from apps.common.keychain import get_keychain
from apps.common.paths import HARDENED, AlwaysMatchingSchema
if TYPE_CHECKING: if TYPE_CHECKING:
from trezor.messages import IdentityType, SignIdentity from trezor.messages import IdentityType, SignIdentity, SignedIdentity
from trezor.wire import Context
from apps.common.paths import Bip32Path from apps.common.paths import Bip32Path
# This module implements the SLIP-0013 authentication using a deterministic hierarchy, see # This module implements the SLIP-0013 authentication using a deterministic hierarchy, see
# https://github.com/satoshilabs/slips/blob/master/slip-0013.md. # https://github.com/satoshilabs/slips/blob/master/slip-0013.md.
async def sign_identity(ctx: wire.Context, msg: SignIdentity) -> SignedIdentity: async def sign_identity(ctx: Context, msg: SignIdentity) -> SignedIdentity:
if msg.ecdsa_curve_name is None: from trezor.messages import SignedIdentity
msg.ecdsa_curve_name = "secp256k1" from trezor.ui.layouts import confirm_sign_identity
from apps.common.keychain import get_keychain
from apps.common.paths import AlwaysMatchingSchema
keychain = await get_keychain(ctx, msg.ecdsa_curve_name, [AlwaysMatchingSchema]) msg_identity = msg.identity # local_cache_attribute
identity = serialize_identity(msg.identity) msg_identity_proto = msg_identity.proto # local_cache_attribute
challenge_visual = msg.challenge_visual # local_cache_attribute
challenge_hidden = msg.challenge_hidden # local_cache_attribute
curve_name = msg.ecdsa_curve_name or "secp256k1"
await require_confirm_sign_identity(ctx, msg.identity, msg.challenge_visual) keychain = await get_keychain(ctx, curve_name, [AlwaysMatchingSchema])
identity = serialize_identity(msg_identity)
address_n = get_identity_path(identity, msg.identity.index or 0) # require_confirm_sign_identity
proto = msg_identity_proto.upper() if msg_identity_proto else "identity"
await confirm_sign_identity(
ctx, proto, serialize_identity_without_proto(msg_identity), challenge_visual
)
# END require_confirm_sign_identity
address_n = get_identity_path(identity, msg_identity.index or 0, 13)
node = keychain.derive(address_n) node = keychain.derive(address_n)
coin = coininfo.by_name("Bitcoin") coin = coininfo.by_name("Bitcoin")
if msg.ecdsa_curve_name == "secp256k1": if curve_name == "secp256k1":
# hardcoded bitcoin address type # hardcoded bitcoin address type
address: str | None = node.address(coin.address_type) address: str | None = node.address(coin.address_type)
else: else:
@ -42,51 +49,22 @@ async def sign_identity(ctx: wire.Context, msg: SignIdentity) -> SignedIdentity:
pubkey = b"\x00" + pubkey[1:] pubkey = b"\x00" + pubkey[1:]
seckey = node.private_key() seckey = node.private_key()
if msg.identity.proto == "gpg": if msg_identity_proto in ("gpg", "signify", "ssh"):
signature = sign_challenge( sigtype = msg_identity_proto
seckey,
msg.challenge_hidden,
msg.challenge_visual,
"gpg",
msg.ecdsa_curve_name,
)
elif msg.identity.proto == "signify":
signature = sign_challenge(
seckey,
msg.challenge_hidden,
msg.challenge_visual,
"signify",
msg.ecdsa_curve_name,
)
elif msg.identity.proto == "ssh":
signature = sign_challenge(
seckey,
msg.challenge_hidden,
msg.challenge_visual,
"ssh",
msg.ecdsa_curve_name,
)
else: else:
signature = sign_challenge( sigtype = coin
seckey,
msg.challenge_hidden, signature = sign_challenge(
msg.challenge_visual, seckey,
coin, challenge_hidden,
msg.ecdsa_curve_name, challenge_visual,
) sigtype,
curve_name,
)
return SignedIdentity(address=address, public_key=pubkey, signature=signature) return SignedIdentity(address=address, public_key=pubkey, signature=signature)
async def require_confirm_sign_identity(
ctx: wire.Context, identity: IdentityType, challenge_visual: str | None
) -> None:
proto = identity.proto.upper() if identity.proto else "identity"
await confirm_sign_identity(
ctx, proto, serialize_identity_without_proto(identity), challenge_visual
)
def serialize_identity(identity: IdentityType) -> str: def serialize_identity(identity: IdentityType) -> str:
s = "" s = ""
if identity.proto: if identity.proto:
@ -110,12 +88,13 @@ def serialize_identity_without_proto(identity: IdentityType) -> str:
return s return s
def get_identity_path(identity: str, index: int) -> Bip32Path: def get_identity_path(identity: str, index: int, num: int) -> Bip32Path:
from ustruct import pack, unpack
from apps.common.paths import HARDENED
identity_hash = sha256(pack("<I", index) + identity.encode()).digest() identity_hash = sha256(pack("<I", index) + identity.encode()).digest()
address_n = [HARDENED | x for x in (13,) + unpack("<IIII", identity_hash[:16])] return [HARDENED | x for x in (num,) + unpack("<IIII", identity_hash[:16])]
return address_n
def sign_challenge( def sign_challenge(
@ -126,12 +105,13 @@ def sign_challenge(
curve: str, curve: str,
) -> bytes: ) -> bytes:
from apps.common.signverify import message_digest from apps.common.signverify import message_digest
from trezor.wire import DataError
if sigtype == "gpg": if sigtype == "gpg":
data = challenge_hidden data = challenge_hidden
elif sigtype == "signify": elif sigtype == "signify":
if curve != "ed25519": if curve != "ed25519":
raise wire.DataError("Unsupported curve") raise DataError("Unsupported curve")
data = challenge_hidden data = challenge_hidden
elif sigtype == "ssh": elif sigtype == "ssh":
if curve != "ed25519": if curve != "ed25519":
@ -146,7 +126,7 @@ def sign_challenge(
) )
data = message_digest(sigtype, challenge) data = message_digest(sigtype, challenge)
else: else:
raise wire.DataError("Unsupported sigtype") raise DataError("Unsupported sigtype")
if curve == "secp256k1": if curve == "secp256k1":
from trezor.crypto.curve import secp256k1 from trezor.crypto.curve import secp256k1
@ -161,7 +141,7 @@ def sign_challenge(
signature = ed25519.sign(seckey, data) signature = ed25519.sign(seckey, data)
else: else:
raise wire.DataError("Unknown curve") raise DataError("Unknown curve")
if curve == "ed25519": if curve == "ed25519":
signature = b"\x00" + signature signature = b"\x00" + signature