Add passthrough reports

This commit is contained in:
jaseg 2021-03-24 14:48:01 +01:00
parent dbb264c68d
commit adfffcd8fb
3 changed files with 95 additions and 36 deletions

View file

@ -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:

View file

@ -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;
}

View file

@ -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 {