diff --git a/core/src/apps/ethereum/sign_tx.py b/core/src/apps/ethereum/sign_tx.py index 5ab6a65a6b..9b067b7ae5 100644 --- a/core/src/apps/ethereum/sign_tx.py +++ b/core/src/apps/ethereum/sign_tx.py @@ -102,7 +102,7 @@ async def sign_tx( rlp.write(sha, 0) digest = sha.get_digest() - result = _sign_digest(msg, keychain, digest) + result = await _sign_digest(msg, keychain, digest) progress_obj.stop() @@ -253,25 +253,53 @@ async def send_request_chunk(data_left: int) -> bytes: return resp.data_chunk -def _sign_digest( +async def send_request_entropy(nonce_commitment: bytes) -> bytes: + from trezor.messages import EthereumTxAck + from trezor.wire.context import call + + req = EthereumTxRequest() + req.nonce_commitment = nonce_commitment + resp = await call(req, EthereumTxAck) + assert resp.entropy is not None + return resp.entropy + + +async def _sign_digest( msg: EthereumSignTx, keychain: Keychain, digest: bytes ) -> EthereumTxRequest: from trezor.crypto.curve import secp256k1 node = keychain.derive(msg.address_n) - signature = secp256k1.sign_recoverable( - node.private_key(), digest, secp256k1.CANONICAL_SIG_ETHEREUM - ) + private_key = node.private_key() + + if msg.entropy_commitment is not None: + # use anti-exfil protocol + nonce_commitment = secp256k1.anti_exfil_commit_nonce( + private_key, digest, msg.entropy_commitment + ) + entropy = await send_request_entropy(nonce_commitment) + + signature = secp256k1.anti_exfil_sign(private_key, digest, entropy) + else: + signature = secp256k1.sign_recoverable( + private_key, digest, secp256k1.CANONICAL_SIG_ETHEREUM + ) req = EthereumTxRequest() - if msg.chain_id <= MAX_CHAIN_ID: - req.signature_v = signature[0] + 35 + 2 * msg.chain_id - else: - # https://github.com/trezor/trezor-core/pull/311 - req.signature_v = signature[0] - req.signature_r = signature[1:33] - req.signature_s = signature[33:] + if msg.entropy_commitment is not None: + # use anti-exfil protocol + req.signature_v = None + req.signature_r = signature[:32] + req.signature_s = signature[32:] + else: + if msg.chain_id <= MAX_CHAIN_ID: + req.signature_v = 35 + 2 * msg.chain_id + signature[0] + else: + # https://github.com/trezor/trezor-core/pull/311 + req.signature_v = signature[0] + req.signature_r = signature[1:33] + req.signature_s = signature[33:] return req diff --git a/core/src/apps/ethereum/sign_tx_eip1559.py b/core/src/apps/ethereum/sign_tx_eip1559.py index 0f73374898..111f2b0228 100644 --- a/core/src/apps/ethereum/sign_tx_eip1559.py +++ b/core/src/apps/ethereum/sign_tx_eip1559.py @@ -119,7 +119,7 @@ async def sign_tx_eip1559( rlp.write(sha, item.storage_keys) digest = sha.get_digest() - result = _sign_digest(msg, keychain, digest) + result = await _sign_digest(msg, keychain, digest) return result @@ -151,20 +151,40 @@ def _get_total_length(msg: EthereumSignTxEIP1559, data_total: int) -> int: return length -def _sign_digest( +async def _sign_digest( msg: EthereumSignTxEIP1559, keychain: Keychain, digest: bytes ) -> EthereumTxRequest: from trezor.crypto.curve import secp256k1 from trezor.messages import EthereumTxRequest + from .sign_tx import send_request_entropy + node = keychain.derive(msg.address_n) - signature = secp256k1.sign_recoverable( - node.private_key(), digest, secp256k1.CANONICAL_SIG_ETHEREUM - ) + private_key = node.private_key() + + if msg.entropy_commitment is not None: + # use anti-exfil protocol + nonce_commitment = secp256k1.anti_exfil_commit_nonce( + private_key, digest, msg.entropy_commitment + ) + entropy = await send_request_entropy(nonce_commitment) + + signature = secp256k1.anti_exfil_sign(private_key, digest, entropy) + else: + signature = secp256k1.sign_recoverable( + private_key, digest, secp256k1.CANONICAL_SIG_ETHEREUM + ) req = EthereumTxRequest() - req.signature_v = signature[0] - req.signature_r = signature[1:33] - req.signature_s = signature[33:] + + if msg.entropy_commitment is not None: + # use anti-exfil protocol + req.signature_v = None + req.signature_r = signature[:32] + req.signature_s = signature[32:] + else: + req.signature_v = signature[0] + req.signature_r = signature[1:33] + req.signature_s = signature[33:] return req