Skip to content

Commit c356473

Browse files
committed
Merge branch 'bb02p-product-string'
2 parents e3b05d3 + 574d85b commit c356473

File tree

17 files changed

+435
-166
lines changed

17 files changed

+435
-166
lines changed

py/bitbox02/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- SD card: Remove API to prompt removal of the microSD card from the device
99
- Add support for regtest (supported from firmware version v9.21.0)
1010
- btc_sign: allow identifying outputs belonging to different accounts of the same keystore
11+
- Detect BitBox02 Plus
1112

1213
# 6.3.0
1314
- Allow infering product and version via API call instead of via USB descriptor

py/bitbox02/bitbox02/bitbox02/bootloader.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@
2323

2424
from bitbox02.communication import TransportLayer
2525

26-
from bitbox02.communication.devices import DeviceInfo, parse_device_version
26+
from bitbox02.communication.devices import (
27+
DeviceInfo,
28+
parse_device_version,
29+
BB02MULTI_BOOTLOADER,
30+
BB02BTC_BOOTLOADER,
31+
BITBOX02PLUS_MULTI_BOOTLOADER,
32+
BITBOX02PLUS_BTC_BOOTLOADER,
33+
)
2734

2835
BOOTLOADER_CMD = 0x80 + 0x40 + 0x03
2936
NUM_ROOT_KEYS = 3
@@ -35,9 +42,10 @@
3542
assert MAX_FIRMWARE_SIZE % CHUNK_SIZE == 0
3643
FIRMWARE_CHUNKS = MAX_FIRMWARE_SIZE // CHUNK_SIZE
3744

38-
SIGDATA_MAGIC_STANDARD = struct.pack(">I", 0x653F362B)
39-
SIGDATA_MAGIC_BTCONLY = struct.pack(">I", 0x11233B0B)
40-
SIGDATA_MAGIC_BITBOXBASE_STANDARD = struct.pack(">I", 0xAB6BD345)
45+
SIGDATA_MAGIC_BITBOX02_MULTI = struct.pack(">I", 0x653F362B)
46+
SIGDATA_MAGIC_BITBOX02_BTCONLY = struct.pack(">I", 0x11233B0B)
47+
SIGDATA_MAGIC_BITBOX02PLUS_MULTI = struct.pack(">I", 0x5B648CEB)
48+
SIGDATA_MAGIC_BITBOX02PLUS_BTCONLY = struct.pack(">I", 0x48714774)
4149

4250
MAGIC_LEN = 4
4351

@@ -69,9 +77,10 @@ def parse_signed_firmware(firmware: bytes) -> typing.Tuple[bytes, bytes, bytes]:
6977
raise ValueError("firmware too small")
7078
magic, firmware = firmware[:MAGIC_LEN], firmware[MAGIC_LEN:]
7179
if magic not in (
72-
SIGDATA_MAGIC_STANDARD,
73-
SIGDATA_MAGIC_BTCONLY,
74-
SIGDATA_MAGIC_BITBOXBASE_STANDARD,
80+
SIGDATA_MAGIC_BITBOX02_MULTI,
81+
SIGDATA_MAGIC_BITBOX02_BTCONLY,
82+
SIGDATA_MAGIC_BITBOX02PLUS_MULTI,
83+
SIGDATA_MAGIC_BITBOX02PLUS_BTCONLY,
7584
):
7685
raise ValueError("invalid magic")
7786

@@ -87,9 +96,10 @@ class Bootloader:
8796
def __init__(self, transport: TransportLayer, device_info: DeviceInfo):
8897
self._transport = transport
8998
self.expected_magic = {
90-
"bb02-bootloader": SIGDATA_MAGIC_STANDARD,
91-
"bb02btc-bootloader": SIGDATA_MAGIC_BTCONLY,
92-
"bitboxbase-bootloader": SIGDATA_MAGIC_BITBOXBASE_STANDARD,
99+
BB02MULTI_BOOTLOADER: SIGDATA_MAGIC_BITBOX02_MULTI,
100+
BB02BTC_BOOTLOADER: SIGDATA_MAGIC_BITBOX02_BTCONLY,
101+
BITBOX02PLUS_MULTI_BOOTLOADER: SIGDATA_MAGIC_BITBOX02PLUS_MULTI,
102+
BITBOX02PLUS_BTC_BOOTLOADER: SIGDATA_MAGIC_BITBOX02PLUS_BTCONLY,
93103
}.get(device_info["product_string"])
94104
self.version = parse_device_version(device_info["serial_number"])
95105
# Delete the prelease part, as it messes with the comparison (e.g. 3.0.0-pre < 3.0.0 is

py/bitbox02/bitbox02/communication/bitbox_api_protocol.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from .devices import parse_device_version, DeviceInfo
3232

3333
from .communication import TransportLayer
34-
from .devices import BITBOX02MULTI, BITBOX02BTC
34+
from .devices import BITBOX02MULTI, BITBOX02BTC, BITBOX02PLUS_MULTI, BITBOX02PLUS_BTC
3535

3636
try:
3737
from .generated import hww_pb2 as hww
@@ -182,6 +182,7 @@ class Platform(enum.Enum):
182182
"""Available hardware platforms"""
183183

184184
BITBOX02 = "bitbox02"
185+
BITBOX02PLUS = "bitbox02-plus"
185186

186187

187188
class BitBox02Edition(enum.Enum):
@@ -541,9 +542,9 @@ def __init__(
541542

542543
if device_info is not None:
543544
version = device_info["serial_number"]
544-
if device_info["product_string"] == BITBOX02MULTI:
545+
if device_info["product_string"] in (BITBOX02MULTI, BITBOX02PLUS_MULTI):
545546
edition = BitBox02Edition.MULTI
546-
elif device_info["product_string"] == BITBOX02BTC:
547+
elif device_info["product_string"] in (BITBOX02BTC, BITBOX02PLUS_BTC):
547548
edition = BitBox02Edition.BTCONLY
548549
else:
549550
version, _, edition, _, _ = self.get_info(transport)
@@ -696,11 +697,11 @@ def get_info(
696697
version_str = version.rstrip(b"\0").decode("ascii")
697698

698699
platform_byte, response = response[0], response[1:]
699-
platform = {0x00: Platform.BITBOX02}[platform_byte]
700+
platform = {0x00: Platform.BITBOX02, 0x02: Platform.BITBOX02PLUS}[platform_byte]
700701

701702
edition_byte, response = response[0], response[1:]
702703
edition: Union[BitBox02Edition]
703-
if platform == Platform.BITBOX02:
704+
if platform in (Platform.BITBOX02, Platform.BITBOX02PLUS):
704705
edition = {0x00: BitBox02Edition.MULTI, 0x01: BitBox02Edition.BTCONLY}[edition_byte]
705706
else:
706707
raise Exception("Unknown platform: {}".format(platform))

py/bitbox02/bitbox02/communication/devices.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
BITBOX02MULTI = "BitBox02"
2727
BITBOX02BTC = "BitBox02BTC"
2828

29+
BITBOX02PLUS_MULTI_BOOTLOADER = "bb02p-bl-multi"
30+
BITBOX02PLUS_BTC_BOOTLOADER = "bb02p-bl-btconly"
31+
BITBOX02PLUS_MULTI = "bb02p-multi"
32+
BITBOX02PLUS_BTC = "bb02p-btconly"
33+
2934

3035
class TooManyFoundException(Exception):
3136
def __init__(self, count: int) -> None:
@@ -111,6 +116,8 @@ def get_any_bitbox02s() -> List[DeviceInfo]:
111116
"""
112117
devices = get_bitbox02multi_devices()
113118
devices.extend(get_bitbox02btc_devices())
119+
devices.extend(get_devices(BITBOX02PLUS_MULTI))
120+
devices.extend(get_devices(BITBOX02PLUS_BTC))
114121
return devices
115122

116123

@@ -138,6 +145,8 @@ def get_any_bitbox02_bootloaders() -> List[DeviceInfo]:
138145
"""
139146
devices = get_bitbox02multi_bootloaders()
140147
devices.extend(get_bitbox02btc_bootloaders())
148+
devices.extend(get_devices(BITBOX02PLUS_MULTI_BOOTLOADER))
149+
devices.extend(get_devices(BITBOX02PLUS_BTC_BOOTLOADER))
141150
return devices
142151

143152

src/CMakeLists.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ set(SECURECHIP-SOURCES
162162
)
163163
set(SECURECHIP-SOURCES ${SECURECHIP-SOURCES} PARENT_SCOPE)
164164

165-
set(FIRMWARE-DRIVER-SOURCES
165+
set(FIRMWARE-U2F-DRIVER-SOURCES
166166
${CMAKE_SOURCE_DIR}/src/usb/class/hid/u2f/hid_u2f.c
167167
)
168-
set(FIRMWARE-DRIVER-SOURCES ${FIRMWARE-DRIVER-SOURCES} PARENT_SCOPE)
168+
set(FIRMWARE-U2F-DRIVER-SOURCES ${FIRMWARE-U2F-DRIVER-SOURCES} PARENT_SCOPE)
169169

170170
set(FIRMWARE-U2F-SOURCES
171171
${CMAKE_SOURCE_DIR}/src/u2f.c
@@ -193,7 +193,6 @@ set(INCLUDES ${INCLUDES} PARENT_SCOPE)
193193
set(FIRMWARE-SOURCES
194194
${DBB-FIRMWARE-SOURCES}
195195
${DBB-FIRMWARE-UI-SOURCES}
196-
${FIRMWARE-DRIVER-SOURCES}
197196
${DRIVER-SOURCES}
198197
${QTOUCH-SOURCES}
199198
${SECURECHIP-SOURCES}
@@ -515,7 +514,7 @@ if(CMAKE_CROSSCOMPILING)
515514

516515
target_sources(firmware.elf PRIVATE firmware.c)
517516
target_compile_definitions(firmware.elf PRIVATE PRODUCT_BITBOX_MULTI "APP_BTC=1" "APP_LTC=1" "APP_ETH=1" "APP_U2F=1")
518-
target_sources(firmware.elf PRIVATE ${FIRMWARE-U2F-SOURCES} ${PLATFORM-BITBOX02-SOURCES})
517+
target_sources(firmware.elf PRIVATE ${FIRMWARE-U2F-SOURCES} ${FIRMWARE-U2F-DRIVER-SOURCES} ${PLATFORM-BITBOX02-SOURCES})
519518

520519
target_sources(firmware-btc.elf PRIVATE firmware.c)
521520
target_compile_definitions(firmware-btc.elf PRIVATE PRODUCT_BITBOX_BTCONLY "APP_BTC=1" "APP_LTC=0" "APP_ETH=0" "APP_U2F=0")

src/hww.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
#include <hardfault.h>
1818
#include <keystore.h>
1919
#include <memory/memory.h>
20+
#include <version.h>
2021

22+
#include <memory/memory_shared.h>
2123
#include <platform_config.h>
2224
#include <rust/rust.h>
2325
#include <usb/usb_packet.h>
@@ -59,8 +61,9 @@ typedef struct {
5961
* 1 byte: platform code:
6062
* - 0x00 - BitBox02
6163
* - 0x01 - BitBoxBase (deprecated)
64+
* - 0x02 - BitBox02Plus
6265
* 1 byte: edition code:
63-
* - For the BitBox02 edition:
66+
* - For the BitBox02 and BitBox02Plus edition:
6467
* - - 0x00 - Multi
6568
* - - 0x01 - Bitcoin-only
6669
* - For the BitBoxBase platform (deprecated):
@@ -83,14 +86,21 @@ static size_t _api_info(uint8_t* buf)
8386
memcpy((char*)current, DIGITAL_BITBOX_VERSION_SHORT, version_string_len);
8487
current += version_string_len;
8588

86-
// 1 byte platform code and 1 byte edition code
87-
#if PRODUCT_BITBOX_MULTI == 1 || PRODUCT_BITBOX02_FACTORYSETUP == 1
88-
*current = 0x00;
89+
// 1 byte platform code
90+
switch (memory_get_platform()) {
91+
case MEMORY_PLATFORM_BITBOX02_PLUS:
92+
*current = 0x02;
93+
break;
94+
default:
95+
*current = 0x00;
96+
break;
97+
}
8998
current++;
99+
100+
// 1 byte edition code
101+
#if PRODUCT_BITBOX_MULTI == 1 || PRODUCT_BITBOX02_FACTORYSETUP == 1
90102
*current = 0x00;
91103
#elif PRODUCT_BITBOX_BTCONLY == 1
92-
*current = 0x00;
93-
current++;
94104
*current = 0x01;
95105
#endif
96106
current++;

src/memory/memory_shared.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,17 @@ uint8_t memory_get_securechip_type(void)
6565
return MEMORY_SECURECHIP_TYPE_ATECC;
6666
}
6767
}
68+
69+
uint8_t memory_get_platform(void)
70+
{
71+
chunk_shared_t chunk = {0};
72+
memory_read_shared_bootdata(&chunk);
73+
uint8_t platform = chunk.fields.platform;
74+
util_zero(&chunk, sizeof(chunk));
75+
switch (platform) {
76+
case MEMORY_PLATFORM_BITBOX02_PLUS:
77+
return platform;
78+
default:
79+
return MEMORY_PLATFORM_BITBOX02;
80+
}
81+
}

src/memory/memory_shared.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ typedef union {
8080
uint8_t io_protection_key_split[32];
8181
uint8_t authorization_key_split[32];
8282
uint8_t encryption_key_split[32];
83+
uint8_t platform;
84+
uint8_t reserved[3]; // align to 4 bytes
8385
} fields;
8486
uint8_t bytes[FLASH_SHARED_DATA_LEN];
8587
} chunk_shared_t;
@@ -106,4 +108,8 @@ USE_RESULT uint8_t memory_get_screen_type(void);
106108
#define MEMORY_SECURECHIP_TYPE_OPTIGA 0x01
107109
USE_RESULT uint8_t memory_get_securechip_type(void);
108110

111+
#define MEMORY_PLATFORM_BITBOX02 0xFF
112+
#define MEMORY_PLATFORM_BITBOX02_PLUS 0x01
113+
USE_RESULT uint8_t memory_get_platform(void);
114+
109115
#endif

src/u2f.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <usb/u2f/u2f_keys.h>
3333
#include <usb/usb_packet.h>
3434
#include <usb/usb_processing.h>
35+
#include <version.h>
3536
#include <wally_crypto.h>
3637

3738
#ifndef TESTING

src/usb/class/hid/u2f/hid_u2f.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
#include "hid_u2f.h"
1616
#include "usb/usb_processing.h"
17-
#include "usb_desc.h"
17+
#include "usb_size.h"
18+
#include "usb_u2f_desc.h"
1819
#include <queue.h>
1920
#include <string.h>
2021
#include <u2f/u2f_packet.h>

0 commit comments

Comments
 (0)