HID report transmission partially works now
partially i.e. if you attach the keyboard before the noise handshake. I suspect some memory corruption somewhere.
This commit is contained in:
parent
e4e2318804
commit
21be46a0b5
8 changed files with 92 additions and 45 deletions
|
|
@ -80,3 +80,8 @@ if __name__ == '__main__':
|
|||
print('Handshake finished, handshake hash:')
|
||||
hexdump(print, proto.get_handshake_hash(), args.width)
|
||||
|
||||
while True:
|
||||
data = proto.decrypt(receive_packet(ser, args.width))
|
||||
print('Decrypted data:')
|
||||
hexdump(print, data, args.width)
|
||||
|
||||
|
|
|
|||
45
src/demo.c
45
src/demo.c
|
|
@ -113,22 +113,47 @@ static void gpio_setup(void)
|
|||
gpio_mode_setup(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO3 | GPIO4);
|
||||
}
|
||||
|
||||
enum packet_types {
|
||||
_RESERVED = 0,
|
||||
HID_KEYBOARD_REPORT = 1,
|
||||
HID_MOUSE_REPORT = 2
|
||||
};
|
||||
|
||||
struct hid_report_packet {
|
||||
uint8_t type;
|
||||
uint8_t len;
|
||||
uint8_t report[8];
|
||||
};
|
||||
|
||||
static void hid_in_message_handler(uint8_t device_id, const uint8_t *data, uint32_t length)
|
||||
{
|
||||
UNUSED(device_id);
|
||||
UNUSED(data);
|
||||
if (length < 4) {
|
||||
LOG_PRINTF("data too short, type=%d\n", hid_get_type(device_id));
|
||||
LOG_PRINTF("HID report too short\n");
|
||||
return;
|
||||
}
|
||||
if (length > 8) {
|
||||
LOG_PRINTF("HID report too long\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// print only first 4 bytes, since every mouse should have at least these four set.
|
||||
// Report descriptors are not read by driver for now, so we do not know what each byte means
|
||||
LOG_PRINTF("HID EVENT %02X %02X %02X %02X \n", data[0], data[1], data[2], data[3]);
|
||||
/*
|
||||
if (hid_get_type(device_id) == HID_TYPE_KEYBOARD) {
|
||||
}
|
||||
*/
|
||||
int type = hid_get_type(device_id);
|
||||
if (type != HID_TYPE_KEYBOARD && type != HID_TYPE_MOUSE) {
|
||||
LOG_PRINTF("Unsupported HID report type %x\n", type);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_PRINTF("Sending event %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]);
|
||||
struct hid_report_packet pkt = {
|
||||
.type = type == HID_TYPE_KEYBOARD ? HID_KEYBOARD_REPORT : HID_MOUSE_REPORT,
|
||||
.len = length,
|
||||
.report = {0}
|
||||
};
|
||||
memcpy(pkt.report, data, length);
|
||||
|
||||
if (send_encrypted_message((uint8_t *)&pkt, sizeof(pkt))) {
|
||||
LOG_PRINTF("Error sending HID report packet\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
volatile struct {
|
||||
|
|
|
|||
71
src/noise.c
71
src/noise.c
|
|
@ -16,11 +16,12 @@
|
|||
} while(0);
|
||||
|
||||
|
||||
static uint8_t local_key[CURVE25519_KEY_LEN];
|
||||
NoiseCipherState *tx_cipher, *rx_cipher;
|
||||
volatile uint8_t host_packet_buf[MAX_HOST_PACKET_SIZE];
|
||||
volatile uint8_t host_packet_length = 0;
|
||||
|
||||
static uint8_t local_key[CURVE25519_KEY_LEN];
|
||||
static NoiseCipherState *tx_cipher = NULL, *rx_cipher = NULL;
|
||||
|
||||
|
||||
NoiseHandshakeState *start_protocol_handshake() {
|
||||
/* TODO Noise-C is nice for prototyping, but we should really get rid of it for mostly three reasons:
|
||||
|
|
@ -71,19 +72,15 @@ errout:
|
|||
}
|
||||
|
||||
NoiseHandshakeState *try_continue_noise_handshake(NoiseHandshakeState *handshake) {
|
||||
#define MAX_MESSAGE_LEN 256
|
||||
uint8_t message[MAX_MESSAGE_LEN];
|
||||
int err;
|
||||
uint8_t message[MAX_HOST_PACKET_SIZE];
|
||||
NoiseBuffer noise_msg;
|
||||
/* Run the protocol handshake */
|
||||
switch (noise_handshakestate_get_action(handshake)) {
|
||||
case NOISE_ACTION_WRITE_MESSAGE:
|
||||
/* Write the next handshake message with a zero-length payload */
|
||||
noise_buffer_set_output(noise_msg, message, sizeof(message));
|
||||
if (noise_handshakestate_write_message(handshake, &noise_msg, NULL) != NOISE_ERROR_NONE) {
|
||||
LOG_PRINTF("Error writing handshake message\n");
|
||||
noise_handshakestate_free(handshake);
|
||||
handshake = NULL;
|
||||
}
|
||||
HANDLE_NOISE_ERROR(noise_handshakestate_write_message(handshake, &noise_msg, NULL), "writing handshake message");
|
||||
send_packet(usart2_out, message, noise_msg.size);
|
||||
break;
|
||||
|
||||
|
|
@ -91,29 +88,23 @@ NoiseHandshakeState *try_continue_noise_handshake(NoiseHandshakeState *handshake
|
|||
if (host_packet_length > 0) {
|
||||
/* Read the next handshake message and discard the payload */
|
||||
noise_buffer_set_input(noise_msg, (uint8_t *)host_packet_buf, host_packet_length);
|
||||
if (noise_handshakestate_read_message(handshake, &noise_msg, NULL) != NOISE_ERROR_NONE) {
|
||||
LOG_PRINTF("Error reading handshake message\n");
|
||||
noise_handshakestate_free(handshake);
|
||||
handshake = NULL;
|
||||
}
|
||||
HANDLE_NOISE_ERROR(noise_handshakestate_read_message(handshake, &noise_msg, NULL), "reading handshake message");
|
||||
host_packet_length = 0; /* Acknowledge to USART ISR the buffer has been handled */
|
||||
}
|
||||
break;
|
||||
|
||||
case NOISE_ACTION_SPLIT:
|
||||
if (noise_handshakestate_split(handshake, &tx_cipher, &rx_cipher) != NOISE_ERROR_NONE) {
|
||||
LOG_PRINTF("Error splitting handshake state\n");
|
||||
HANDLE_NOISE_ERROR(noise_handshakestate_split(handshake, &tx_cipher, &rx_cipher), "splitting handshake state");
|
||||
LOG_PRINTF("Noise protocol handshake completed successfully, handshake hash:\n");
|
||||
|
||||
uint8_t buf[BLAKE2S_HASH_SIZE];
|
||||
if (noise_handshakestate_get_handshake_hash(handshake, buf, sizeof(buf)) != NOISE_ERROR_NONE) {
|
||||
LOG_PRINTF("Error fetching noise handshake state\n");
|
||||
} else {
|
||||
LOG_PRINTF("Noise protocol handshake completed successfully, handshake hash:\n");
|
||||
uint8_t buf[BLAKE2S_HASH_SIZE];
|
||||
if (noise_handshakestate_get_handshake_hash(handshake, buf, sizeof(buf)) != NOISE_ERROR_NONE) {
|
||||
LOG_PRINTF("Error fetching noise handshake state\n");
|
||||
} else {
|
||||
LOG_PRINTF(" ");
|
||||
for (size_t i=0; i<sizeof(buf); i++)
|
||||
LOG_PRINTF("%02x ", buf[i]);
|
||||
LOG_PRINTF("\n");
|
||||
}
|
||||
LOG_PRINTF(" ");
|
||||
for (size_t i=0; i<sizeof(buf); i++)
|
||||
LOG_PRINTF("%02x ", buf[i]);
|
||||
LOG_PRINTF("\n");
|
||||
}
|
||||
|
||||
noise_handshakestate_free(handshake);
|
||||
|
|
@ -121,10 +112,34 @@ NoiseHandshakeState *try_continue_noise_handshake(NoiseHandshakeState *handshake
|
|||
|
||||
default:
|
||||
LOG_PRINTF("Noise protocol handshake failed\n");
|
||||
noise_handshakestate_free(handshake);
|
||||
return NULL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return handshake;
|
||||
|
||||
errout:
|
||||
noise_handshakestate_free(handshake);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int send_encrypted_message(uint8_t *msg, size_t len) {
|
||||
int err;
|
||||
NoiseBuffer noise_buf;
|
||||
uint8_t raw_buf[MAX_HOST_PACKET_SIZE];
|
||||
|
||||
if (!tx_cipher) {
|
||||
LOG_PRINTF("Cannot send encrypted packet: Data ciphers not yet initialized\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(raw_buf, msg, len); /* This is necessary because noises API doesn't support separate in and out buffers. D'oh! */
|
||||
noise_buffer_set_inout(noise_buf, raw_buf, len, sizeof(raw_buf));
|
||||
|
||||
HANDLE_NOISE_ERROR(noise_cipherstate_encrypt(tx_cipher, &noise_buf), "encrypting data");
|
||||
send_packet(usart2_out, raw_buf, noise_buf.size);
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,5 +20,6 @@ extern volatile uint8_t host_packet_length;
|
|||
NoiseHandshakeState *start_protocol_handshake(void);
|
||||
int generate_identity_key(void);
|
||||
NoiseHandshakeState *try_continue_noise_handshake(NoiseHandshakeState *handshake);
|
||||
int send_encrypted_message(uint8_t *msg, size_t len);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -57,3 +57,9 @@ void usart2_isr(void) {
|
|||
} /* else just return and wait for next byte */
|
||||
}
|
||||
|
||||
void send_packet(struct dma_usart_file *f, const uint8_t *data, size_t len) {
|
||||
/* ignore return value as putf is blocking and always succeeds */
|
||||
(void)cobs_encode_incremental(f, putf, (char *)data, len);
|
||||
flush(f);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,6 @@
|
|||
|
||||
extern struct dma_usart_file *usart2_out;
|
||||
|
||||
void send_packet(struct dma_usart_file *f, const uint8_t *data, size_t len);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -144,9 +144,3 @@ void flush(void *file) {
|
|||
nvic_enable_irq(f->irqn);
|
||||
}
|
||||
|
||||
void send_packet(struct dma_usart_file *f, const uint8_t *data, size_t len) {
|
||||
/* ignore return value as putf is blocking and always succeeds */
|
||||
(void)cobs_encode_incremental(f, putf, (char *)data, len);
|
||||
flush(f);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ int dma_fifo_push(volatile struct dma_buf *buf, char c);
|
|||
int putf(void *file, char c);
|
||||
int putb(void *file, const uint8_t *buf, size_t len);
|
||||
void flush(void *file);
|
||||
void send_packet(struct dma_usart_file *f, const uint8_t *data, size_t len);
|
||||
|
||||
/* This macro abomination templates a bunch of dma-specific register/constant names from preprocessor macros passed in
|
||||
* from cmake. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue