Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion firmware/bluetooth_rxtx/le_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ uint8_t le_dma_dest[2];

extern volatile uint8_t mode;
extern volatile uint8_t requested_mode;

// Shared LE state owned by bluetooth_rxtx.c. We only read le.crc_verify here,
// which the host toggles via UBERTOOTH_SET_CRC_VERIFY (ubertooth-btle -v1).
extern le_state_t le;
extern volatile uint16_t le_adv_channel;
extern volatile int cancel_follow;

Expand Down Expand Up @@ -975,7 +979,30 @@ void le_phy_main(void) {
if (queue_remove(&packet_queue, (void **)&packet)) {
le_dewhiten(packet->data, packet->size, packet->channel);

if (filter_match(packet)) {
// On-device CRC validation. This modern LE engine previously
// forwarded every packet including bit-errored ones, so the
// host's UBERTOOTH_SET_CRC_VERIFY (ubertooth-btle -v1) had no
// effect on advertising/follow captures and bit-flipped
// "phantom" advertisers leaked to the host. Advertising-channel
// PDUs use the fixed CRCInit (reversed: 0xAAAAAA); data-channel
// PDUs use the value recovered from CONNECT_IND. Disabled by
// default, so the legacy behaviour is unchanged unless -v1 is set.
int crc_ok = 1;
if (le.crc_verify && packet->size > 3) {
unsigned pdu_len = packet->size - 3;
uint32_t crc_init_rev =
(btle_channel_index(packet->channel) >= 37)
? 0xAAAAAA : conn.crc_init_reversed;
uint32_t calc_crc =
btle_crcgen_lut(crc_init_rev, packet->data, pdu_len);
uint32_t wire_crc =
(packet->data[pdu_len + 2] << 16)
| (packet->data[pdu_len + 1] << 8)
| packet->data[pdu_len + 0];
crc_ok = (calc_crc == wire_crc);
}

if (crc_ok && filter_match(packet)) {
blink(0, 1, 0); // RX LED
usb_enqueue_le(packet);
packet_handler(packet);
Expand Down
12 changes: 11 additions & 1 deletion host/ubertooth-tools/src/ubertooth-btle.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,15 @@ int main(int argc, char *argv[])
cmd_btle_promisc(ut->devh);
}

// Set CRC verification *after* the mode has started (mode entry runs
// reset_le() which clears crc_verify) but *before* the capture loop —
// otherwise the do_crc block further below only ran after streaming
// ended, making -v1 a no-op for sniffing modes.
if (do_crc >= 0 && do_crc != 2) {
cmd_set_crc_verify(ut->devh, do_crc);
printf("CRC: %sverify\n", do_crc ? "" : "DO NOT ");
}

// running can be changed by signal handler
while (running) {
if (cancel_follow) {
Expand Down Expand Up @@ -366,7 +375,8 @@ int main(int argc, char *argv[])
printf("access address set to: %08x\n", access_address);
}

if (do_crc >= 0) {
// For sniffing modes this was already handled before the capture loop.
if (do_crc >= 0 && !(do_follow || do_no_follow || do_promisc)) {
int r;
if (do_crc == 2) {
r = cmd_get_crc_verify(ut->devh);
Expand Down