|
|
@ -1,19 +1,57 @@
|
|
|
|
from storage.device import get_device_id
|
|
|
|
from storage.device import get_device_id
|
|
|
|
from trezor import io, utils
|
|
|
|
from trezor import io, utils
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_iface_iter = iter(range(5))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ENABLE_IFACE_DEBUG = __debug__
|
|
|
|
|
|
|
|
# change to False to enable VCP, see below
|
|
|
|
|
|
|
|
ENABLE_IFACE_WEBAUTHN = not utils.BITCOIN_ONLY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# We only have 10 available USB endpoints on real HW, of which 2 are taken up by the USB descriptor.
|
|
|
|
|
|
|
|
# iface_wire, iface_debug and iface_webauthn also consume 2 each, iface_vcp uses 3.
|
|
|
|
|
|
|
|
# That is a grand total of 11. That means that we can't enable everything at the same time.
|
|
|
|
|
|
|
|
# By default, iface_vcp is only enabled on bitcoin_only firmware, where iface_webauthn
|
|
|
|
|
|
|
|
# is disabled. Implementation-wise, we check if any of the previous ifaces is disabled
|
|
|
|
|
|
|
|
# in order to enable VCP.
|
|
|
|
|
|
|
|
ENABLE_IFACE_VCP = __debug__ and (
|
|
|
|
|
|
|
|
utils.EMULATOR or not ENABLE_IFACE_DEBUG or not ENABLE_IFACE_WEBAUTHN
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# interface used for trezor wire protocol
|
|
|
|
# interface used for trezor wire protocol
|
|
|
|
iface_wire = io.WebUSB(iface_num=0, ep_in=0x81, ep_out=0x01)
|
|
|
|
id_wire = next(_iface_iter)
|
|
|
|
|
|
|
|
iface_wire = io.WebUSB(
|
|
|
|
|
|
|
|
iface_num=id_wire,
|
|
|
|
|
|
|
|
ep_in=0x81 + id_wire,
|
|
|
|
|
|
|
|
ep_out=0x01 + id_wire,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# XXXXXXXXXXXXXXXXXXX
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# We want the following branches present only in their respective firmwares. To achieve
|
|
|
|
|
|
|
|
# that, we are taking advantage of the upy compiler static optimization: when an
|
|
|
|
|
|
|
|
# if-expression statically evaluates to False, the branch is excluded from the bytecode.
|
|
|
|
|
|
|
|
# This works magically for the __debug__ builtin, and `utils.BITCOIN_ONLY` is replaced
|
|
|
|
|
|
|
|
# by a literal True/False by us in the build step.
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# Therefore, each of the following needs to include the respective static expression
|
|
|
|
|
|
|
|
# so that it can be correctly excluded from the resulting build.
|
|
|
|
|
|
|
|
|
|
|
|
if __debug__:
|
|
|
|
if __debug__ and ENABLE_IFACE_DEBUG:
|
|
|
|
# interface used for debug messages with trezor wire protocol
|
|
|
|
# interface used for debug messages with trezor wire protocol
|
|
|
|
iface_debug = io.WebUSB(iface_num=1, ep_in=0x82, ep_out=0x02)
|
|
|
|
id_debug = next(_iface_iter)
|
|
|
|
|
|
|
|
iface_debug = io.WebUSB(
|
|
|
|
|
|
|
|
iface_num=id_debug,
|
|
|
|
|
|
|
|
ep_in=0x81 + id_debug,
|
|
|
|
|
|
|
|
ep_out=0x01 + id_debug,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if not utils.BITCOIN_ONLY:
|
|
|
|
if not utils.BITCOIN_ONLY and ENABLE_IFACE_WEBAUTHN:
|
|
|
|
# interface used for FIDO/U2F and FIDO2/WebAuthn HID transport
|
|
|
|
# interface used for FIDO/U2F and FIDO2/WebAuthn HID transport
|
|
|
|
|
|
|
|
id_webauthn = next(_iface_iter)
|
|
|
|
iface_webauthn = io.HID(
|
|
|
|
iface_webauthn = io.HID(
|
|
|
|
iface_num=2 if __debug__ else 1,
|
|
|
|
iface_num=id_webauthn,
|
|
|
|
ep_in=0x83 if __debug__ else 0x82,
|
|
|
|
ep_in=0x81 + id_webauthn,
|
|
|
|
ep_out=0x03 if __debug__ else 0x02,
|
|
|
|
ep_out=0x01 + id_webauthn,
|
|
|
|
# fmt: off
|
|
|
|
# fmt: off
|
|
|
|
report_desc=bytes([
|
|
|
|
report_desc=bytes([
|
|
|
|
0x06, 0xd0, 0xf1, # USAGE_PAGE (FIDO Alliance)
|
|
|
|
0x06, 0xd0, 0xf1, # USAGE_PAGE (FIDO Alliance)
|
|
|
@ -36,20 +74,17 @@ if not utils.BITCOIN_ONLY:
|
|
|
|
# fmt: on
|
|
|
|
# fmt: on
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if __debug__:
|
|
|
|
if __debug__ and ENABLE_IFACE_VCP:
|
|
|
|
# We cannot use this on real device simultaneously with the iface_webauthn
|
|
|
|
# interface used for cdc/vcp console emulation (debug messages)
|
|
|
|
# interface, because we have only limited number of endpoints (10).
|
|
|
|
id_vcp = next(_iface_iter)
|
|
|
|
# We start this only for bitcoin-only firmware or for emulator.
|
|
|
|
id_vcp_data = next(_iface_iter)
|
|
|
|
ENABLE_VCP_IFACE = utils.EMULATOR or utils.BITCOIN_ONLY
|
|
|
|
iface_vcp = io.VCP(
|
|
|
|
if ENABLE_VCP_IFACE:
|
|
|
|
iface_num=id_vcp,
|
|
|
|
# interface used for cdc/vcp console emulation (debug messages)
|
|
|
|
data_iface_num=id_vcp_data,
|
|
|
|
iface_vcp = io.VCP(
|
|
|
|
ep_in=0x81 + id_vcp,
|
|
|
|
iface_num=2 if utils.BITCOIN_ONLY else 3,
|
|
|
|
ep_out=0x01 + id_vcp,
|
|
|
|
data_iface_num=3 if utils.BITCOIN_ONLY else 4,
|
|
|
|
ep_cmd=0x81 + id_vcp_data,
|
|
|
|
ep_in=0x83 if utils.BITCOIN_ONLY else 0x84,
|
|
|
|
)
|
|
|
|
ep_out=0x03 if utils.BITCOIN_ONLY else 0x04,
|
|
|
|
|
|
|
|
ep_cmd=0x84 if utils.BITCOIN_ONLY else 0x85,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bus = io.USB(
|
|
|
|
bus = io.USB(
|
|
|
|
vendor_id=0x1209,
|
|
|
|
vendor_id=0x1209,
|
|
|
@ -62,10 +97,9 @@ bus = io.USB(
|
|
|
|
usb21_landing=False,
|
|
|
|
usb21_landing=False,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
bus.add(iface_wire)
|
|
|
|
bus.add(iface_wire)
|
|
|
|
if __debug__:
|
|
|
|
if __debug__ and ENABLE_IFACE_DEBUG:
|
|
|
|
bus.add(iface_debug)
|
|
|
|
bus.add(iface_debug)
|
|
|
|
if not utils.BITCOIN_ONLY:
|
|
|
|
if not utils.BITCOIN_ONLY and ENABLE_IFACE_WEBAUTHN:
|
|
|
|
bus.add(iface_webauthn)
|
|
|
|
bus.add(iface_webauthn)
|
|
|
|
if __debug__:
|
|
|
|
if __debug__ and ENABLE_IFACE_VCP:
|
|
|
|
if ENABLE_VCP_IFACE:
|
|
|
|
bus.add(iface_vcp)
|
|
|
|
bus.add(iface_vcp)
|
|
|
|
|
|
|
|