Add passthrough reports
This commit is contained in:
parent
dbb264c68d
commit
adfffcd8fb
3 changed files with 95 additions and 36 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
import time
|
import time
|
||||||
import enum
|
import enum
|
||||||
import os
|
import os
|
||||||
|
import warnings
|
||||||
import sys
|
import sys
|
||||||
import binascii
|
import binascii
|
||||||
from contextlib import contextmanager, suppress, wraps
|
from contextlib import contextmanager, suppress, wraps
|
||||||
|
|
@ -29,6 +30,7 @@ class PacketType(enum.Enum):
|
||||||
COMM_ERROR = 4
|
COMM_ERROR = 4
|
||||||
CRYPTO_ERROR = 5
|
CRYPTO_ERROR = 5
|
||||||
TOO_MANY_FAILS = 6
|
TOO_MANY_FAILS = 6
|
||||||
|
PASSTHROUGH_REPORT = 7
|
||||||
|
|
||||||
class ReportType(enum.Enum):
|
class ReportType(enum.Enum):
|
||||||
_RESERVED = 0
|
_RESERVED = 0
|
||||||
|
|
@ -263,7 +265,7 @@ class NoiseEngine:
|
||||||
self.connected, self.paired = True, False
|
self.connected, self.paired = True, False
|
||||||
else:
|
else:
|
||||||
self.connected, self.paired = True, False
|
self.connected, self.paired = True, False
|
||||||
raise UserWarning(f'Unexpected record type {rtype} in {msg_type} packet. Ignoring.')
|
warnings.warn(f'Unexpected record type {rtype} in {msg_type} packet. Ignoring.')
|
||||||
|
|
||||||
if self.debug:
|
if self.debug:
|
||||||
print('Handshake finished, handshake hash:')
|
print('Handshake finished, handshake hash:')
|
||||||
|
|
@ -281,15 +283,19 @@ class NoiseEngine:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.debug_print('Invalid framing:', e)
|
self.debug_print('Invalid framing:', e)
|
||||||
|
|
||||||
if pkt_type is not PacketType.DATA:
|
if pkt_type not in [PacketType.DATA, PacketType.PASSTHROUGH_REPORT]:
|
||||||
raise UserWarning(f'Unexpected packet type {pkt_type}. Ignoring.')
|
warnings.warn(f'Unexpected packet type {pkt_type}. Ignoring.')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
rtype, data = self._decrypt(received)
|
if pkt_type == PacketType.DATA:
|
||||||
if self.debug:
|
rtype, data = self._decrypt(received)
|
||||||
print(f'Decrypted packet {rtype} ({rtype.value}):')
|
if self.debug:
|
||||||
hexdump(print, data)
|
print(f'Decrypted packet {rtype} ({rtype.value}):')
|
||||||
yield rtype, data
|
hexdump(print, data)
|
||||||
|
yield rtype, data
|
||||||
|
|
||||||
|
else: # plaintext passthrough input
|
||||||
|
print('Plaintext report: ', binascii.hexlify(received))
|
||||||
|
|
||||||
def _decrypt(self, received):
|
def _decrypt(self, received):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
108
fw/src/demo.c
108
fw/src/demo.c
|
|
@ -77,13 +77,31 @@ static struct {
|
||||||
} mgmt __attribute__((aligned(4)));
|
} mgmt __attribute__((aligned(4)));
|
||||||
} keystore __attribute__((section(".backup_sram"))) = {0};
|
} keystore __attribute__((section(".backup_sram"))) = {0};
|
||||||
|
|
||||||
|
enum operation_mode_t {
|
||||||
|
OPMODE_DIRECT,
|
||||||
|
OPMODE_ENCRYPTED,
|
||||||
|
OPMODE_NUM,
|
||||||
|
} g_operation_mode = OPMODE_DIRECT;
|
||||||
|
|
||||||
|
bool send_plaintext_message(const uint8_t *msg, size_t len);
|
||||||
void _fini(void);
|
void _fini(void);
|
||||||
|
|
||||||
static inline void delay(uint32_t n) {
|
static inline void delay(uint32_t n) {
|
||||||
for (volatile uint32_t i = 0; i < 1490*n; i++);
|
for (volatile uint32_t i = 0; i < 1490*n; i++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_opmode(enum operation_mode_t new_opmode) {
|
||||||
|
g_operation_mode = new_opmode;
|
||||||
|
|
||||||
|
if (g_operation_mode == OPMODE_DIRECT) {
|
||||||
|
gpio_clear(GPIOE, GPIO13);
|
||||||
|
gpio_set(GPIOE, GPIO14);
|
||||||
|
|
||||||
|
} else { /* OPMODE_ENCRYPTED */
|
||||||
|
gpio_set(GPIOE, GPIO13);
|
||||||
|
gpio_clear(GPIOE, GPIO14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set STM32 to 168 MHz. */
|
/* Set STM32 to 168 MHz. */
|
||||||
static void clock_setup(void) {
|
static void clock_setup(void) {
|
||||||
|
|
@ -417,12 +435,19 @@ static void hid_in_message_handler(uint8_t device_id, const uint8_t *data, uint3
|
||||||
};
|
};
|
||||||
memcpy(pkt.report.report, data, length);
|
memcpy(pkt.report.report, data, length);
|
||||||
|
|
||||||
if (send_encrypted_message(&noise_state, (uint8_t *)&pkt, sizeof(pkt))) {
|
if (g_operation_mode == OPMODE_DIRECT) {
|
||||||
LOG_PRINTF("Error sending HID report packet\n");
|
if (!send_plaintext_message((uint8_t *)&pkt, sizeof(pkt))) {
|
||||||
TRACING_CLEAR(TR_HID_MESSAGE_HANDLER);
|
LOG_PRINTF("Error sending plaintext HID report packet\n");
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
} else { /* OPMODE_ENCRYPTED */
|
||||||
|
if (send_encrypted_message(&noise_state, (uint8_t *)&pkt, sizeof(pkt))) {
|
||||||
|
LOG_PRINTF("Error sending encrypted HID report packet\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACING_CLEAR(TR_HID_MESSAGE_HANDLER);
|
TRACING_CLEAR(TR_HID_MESSAGE_HANDLER);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile struct {
|
volatile struct {
|
||||||
|
|
@ -444,7 +469,7 @@ struct dma_usart_file *debug_out = &debug_out_s;
|
||||||
/* FIXME start unsafe debug code */
|
/* FIXME start unsafe debug code */
|
||||||
bool debug_emulate_pairing_input(char c);
|
bool debug_emulate_pairing_input(char c);
|
||||||
bool debug_fill_report_from_ascii(char c, struct hid_report *out);
|
bool debug_fill_report_from_ascii(char c, struct hid_report *out);
|
||||||
bool debug_send_encrypted_emulated_report(char c);
|
bool debug_send_emulated_report(char c);
|
||||||
bool debug_enqueue_emulated_input(char c);
|
bool debug_enqueue_emulated_input(char c);
|
||||||
|
|
||||||
/* Feed keyboard input from debug UART into keyboard subsystem */
|
/* Feed keyboard input from debug UART into keyboard subsystem */
|
||||||
|
|
@ -550,7 +575,7 @@ bool debug_emulate_pairing_input(char c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true on success */
|
/* Returns true on success */
|
||||||
bool debug_send_encrypted_emulated_report(char c) {
|
bool debug_send_emulated_report(char c) {
|
||||||
struct hid_report_packet pkt = {
|
struct hid_report_packet pkt = {
|
||||||
.type = REPORT_KEYBOARD,
|
.type = REPORT_KEYBOARD,
|
||||||
.report = {
|
.report = {
|
||||||
|
|
@ -563,17 +588,33 @@ bool debug_send_encrypted_emulated_report(char c) {
|
||||||
if (!debug_fill_report_from_ascii(c, &pkt.report.report))
|
if (!debug_fill_report_from_ascii(c, &pkt.report.report))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (send_encrypted_message(&noise_state, (uint8_t *)&pkt, sizeof(pkt))) {
|
if (g_operation_mode == OPMODE_ENCRYPTED) {
|
||||||
LOG_PRINTF("Error sending emulated HID report packet\n");
|
if (send_encrypted_message(&noise_state, (uint8_t *)&pkt, sizeof(pkt))) {
|
||||||
return false;
|
LOG_PRINTF("Error sending emulated encrypted HID report packet\n");
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* key release */
|
/* key release */
|
||||||
memset(&pkt.report.report, 0, sizeof(struct hid_report));
|
memset(&pkt.report.report, 0, sizeof(struct hid_report));
|
||||||
|
|
||||||
if (send_encrypted_message(&noise_state, (uint8_t *)&pkt, sizeof(pkt))) {
|
if (send_encrypted_message(&noise_state, (uint8_t *)&pkt, sizeof(pkt))) {
|
||||||
LOG_PRINTF("Error sending emulated HID report packet\n");
|
LOG_PRINTF("Error sending emulated encrypted HID report packet\n");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { /* OPMODE_DIRECT */
|
||||||
|
if (!send_plaintext_message((uint8_t *)&pkt, sizeof(pkt))) {
|
||||||
|
LOG_PRINTF("Error sending emulated plaintext HID report packet\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* key release */
|
||||||
|
memset(&pkt.report.report, 0, sizeof(struct hid_report));
|
||||||
|
|
||||||
|
if (!send_plaintext_message((uint8_t *)&pkt, sizeof(pkt))) {
|
||||||
|
LOG_PRINTF("Error sending emulated plaintext HID report packet\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -618,6 +659,7 @@ void handle_host_packet(struct NoiseState *st, const struct control_packet *pkt,
|
||||||
LOG_PRINTF("Extraneous data in INITIATE_HANDSHAKE message\n");
|
LOG_PRINTF("Extraneous data in INITIATE_HANDSHAKE message\n");
|
||||||
} else if (st->failed_handshakes < MAX_FAILED_HANDSHAKES) {
|
} else if (st->failed_handshakes < MAX_FAILED_HANDSHAKES) {
|
||||||
LOG_PRINTF("Starting noise protocol handshake...\n");
|
LOG_PRINTF("Starting noise protocol handshake...\n");
|
||||||
|
set_opmode(OPMODE_ENCRYPTED);
|
||||||
if (reset_protocol_handshake(st))
|
if (reset_protocol_handshake(st))
|
||||||
LOG_PRINTF("Error starting protocol handshake.\n");
|
LOG_PRINTF("Error starting protocol handshake.\n");
|
||||||
pairing_buf_pos = 0; /* Reset channel binding keyboard input buffer */
|
pairing_buf_pos = 0; /* Reset channel binding keyboard input buffer */
|
||||||
|
|
@ -718,8 +760,7 @@ int main(void)
|
||||||
int debounce_ctr_test = 0;
|
int debounce_ctr_test = 0;
|
||||||
int mode_debug = 0;
|
int mode_debug = 0;
|
||||||
#define DEBOUNCE_IVL 1000
|
#define DEBOUNCE_IVL 1000
|
||||||
gpio_set(GPIOE, GPIO13);
|
set_opmode(OPMODE_DIRECT);
|
||||||
gpio_clear(GPIOE, GPIO14);
|
|
||||||
|
|
||||||
int dbg_keyem_ctr = 0;
|
int dbg_keyem_ctr = 0;
|
||||||
#define DBG_KEYEM_IVL 100
|
#define DBG_KEYEM_IVL 100
|
||||||
|
|
@ -731,7 +772,7 @@ int main(void)
|
||||||
int rc = debug_dequeue_emulated_input();
|
int rc = debug_dequeue_emulated_input();
|
||||||
if (rc >= 0) {
|
if (rc >= 0) {
|
||||||
dbg_keyem_ctr = DBG_KEYEM_IVL;
|
dbg_keyem_ctr = DBG_KEYEM_IVL;
|
||||||
if (!debug_send_encrypted_emulated_report((char) rc)) {
|
if (!debug_send_emulated_report((char) rc)) {
|
||||||
LOG_PRINTF("Error sending emulated keyboard input\n");
|
LOG_PRINTF("Error sending emulated keyboard input\n");
|
||||||
} else {
|
} else {
|
||||||
LOG_PRINTF("Sent emulated keypress %02x\n", (unsigned char)rc);
|
LOG_PRINTF("Sent emulated keypress %02x\n", (unsigned char)rc);
|
||||||
|
|
@ -769,16 +810,7 @@ int main(void)
|
||||||
if (last_btn_st_mode) {
|
if (last_btn_st_mode) {
|
||||||
debounce_ctr_mode = DEBOUNCE_IVL;
|
debounce_ctr_mode = DEBOUNCE_IVL;
|
||||||
|
|
||||||
mode_debug = !mode_debug;
|
set_opmode((g_operation_mode + 1) % OPMODE_NUM);
|
||||||
|
|
||||||
if (mode_debug) {
|
|
||||||
gpio_clear(GPIOE, GPIO13);
|
|
||||||
gpio_set(GPIOE, GPIO14);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
gpio_set(GPIOE, GPIO13);
|
|
||||||
gpio_clear(GPIOE, GPIO14);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
last_btn_st_mode = 0;
|
last_btn_st_mode = 0;
|
||||||
|
|
@ -865,3 +897,23 @@ void _fini() {
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true on success */
|
||||||
|
bool send_plaintext_message(const uint8_t *msg, size_t len) {
|
||||||
|
int err;
|
||||||
|
struct {
|
||||||
|
struct control_packet header;
|
||||||
|
uint8_t payload[MAX_HOST_PACKET_SIZE];
|
||||||
|
} pkt;
|
||||||
|
|
||||||
|
if (len > sizeof(pkt.payload)) {
|
||||||
|
LOG_PRINTF("Packet too long\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt.header.type = HOST_PASSTHROUGH_REPORT;
|
||||||
|
memcpy(pkt.payload, msg, len);
|
||||||
|
|
||||||
|
send_packet(uart4_out, (uint8_t *)&pkt, len + sizeof(pkt.header));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ enum control_packet_types {
|
||||||
HOST_COMM_ERROR = 4,
|
HOST_COMM_ERROR = 4,
|
||||||
HOST_CRYPTO_ERROR = 5,
|
HOST_CRYPTO_ERROR = 5,
|
||||||
HOST_TOO_MANY_FAILS = 6,
|
HOST_TOO_MANY_FAILS = 6,
|
||||||
|
HOST_PASSTHROUGH_REPORT = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum packet_types {
|
enum packet_types {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue