From eb481f1cda0a6eae1aa0486acb637f985cddcc2f Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 14 Nov 2018 22:47:04 +0900 Subject: known device/sram data persistence working --- libusbhost_stm32f4.ld | 11 +++++++++++ pairing.py | 5 +++-- src/demo.c | 23 ++++++++++++++++++----- src/noise.c | 24 +++++++++++++++++++----- src/noise.h | 4 ++-- 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/libusbhost_stm32f4.ld b/libusbhost_stm32f4.ld index d1801d8..a1cf6d9 100644 --- a/libusbhost_stm32f4.ld +++ b/libusbhost_stm32f4.ld @@ -33,6 +33,17 @@ MEMORY /* Include the common ld script. */ INCLUDE libopencm3_stm32f4.ld +/* Extra stuff */ +SECTIONS +{ + .backup_sram : { + . = ALIGN(4); + __backup_sram_start = .; + *(.backup_sram) + __backup_sram_end = .; + } >backup +} + PROVIDE(_ram_start = ORIGIN(ram)); PROVIDE(_ram_end = ORIGIN(ram) + LENGTH(ram)); PROVIDE(_rom_start = ORIGIN(rom)); diff --git a/pairing.py b/pairing.py index 840e0bc..ce50081 100755 --- a/pairing.py +++ b/pairing.py @@ -3,6 +3,7 @@ import threading import binascii import re import os +import time import serial import gi @@ -136,11 +137,11 @@ def run_pairing_gui(port, baudrate, debug=False): raise SystemError('Unknown noise error') with open(known_devices_file, 'a') as f: - f.write(noise.remote_fingerprint) + f.write(f'{noise.remote_fingerprint} # added {time.ctime()}\n') else: with open(known_devices_file) as f: - known_devices = [ l.strip() for l in f.readlines() if not l[0] == '#' ] + known_devices = [ l.strip().partition('#')[0].strip() for l in f.readlines() if not l[0] == '#' ] if noise.remote_fingerprint not in known_devices: raise ValueError('Remote host is untrusted but seems to trust us.') diff --git a/src/demo.c b/src/demo.c index ad73cff..05875b8 100644 --- a/src/demo.c +++ b/src/demo.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,9 @@ static struct NoiseState noise_state; -static uint8_t remote_key_reference[CURVE25519_KEY_LEN]; +static uint8_t remote_key_reference[BLAKE2S_HASH_SIZE] __attribute__((section(".backup_sram"))); +static uint8_t local_key[CURVE25519_KEY_LEN] __attribute__((section(".backup_sram"))); +static uint8_t identity_key_valid __attribute__((section(".backup_sram"))) = 0; void _fini(void); @@ -81,6 +84,9 @@ static void clock_setup(void) { rcc_periph_clock_enable(RCC_DMA2); rcc_periph_clock_enable(RCC_DMA1); + rcc_periph_clock_enable(RCC_PWR); + rcc_periph_clock_enable(RCC_BKPSRAM); + rcc_periph_clock_enable(RCC_RNG); } @@ -413,6 +419,8 @@ int main(void) { clock_setup(); gpio_setup(); + pwr_disable_backup_domain_write_protect(); + PWR_CSR |= PWR_CSR_BRE; /* Enable backup SRAM battery power regulator */ /* provides time_curr_us to usbh_poll function */ tim6_setup(); @@ -447,12 +455,17 @@ int main(void) LOG_PRINTF("Initializing RNG...\n"); rand_init(); - noise_state_init(&noise_state, remote_key_reference); + noise_state_init(&noise_state, remote_key_reference, local_key); /* FIXME load remote key from backup memory */ /* FIXME only run this on first boot and persist key in backup sram. Allow reset via jumper-triggered factory reset function. */ - LOG_PRINTF("Generating identity key...\n"); - if (generate_identity_key(&noise_state)) - LOG_PRINTF("Error generating identiy key\n"); + if (!identity_key_valid) { + LOG_PRINTF("Generating identity key...\n"); + if (generate_identity_key(&noise_state)) { + LOG_PRINTF("Error generating identiy key\n"); + } else { + identity_key_valid = 1; + } + } int poll_ctr = 0; while (23) { diff --git a/src/noise.c b/src/noise.c index a30d338..7a969c3 100644 --- a/src/noise.c +++ b/src/noise.c @@ -3,6 +3,9 @@ #include "noise.h" #include "packet_interface.h" +#include "rand_stm32.h" + +#include "crypto/noise-c/src/crypto/blake2/blake2s.h" #define HANDLE_NOISE_ERROR(x, msg) do { \ @@ -20,12 +23,13 @@ volatile uint8_t host_packet_buf[MAX_HOST_PACKET_SIZE]; volatile int host_packet_length = 0; -void noise_state_init(struct NoiseState *st, uint8_t *remote_key_reference) { +void noise_state_init(struct NoiseState *st, uint8_t *remote_key_reference, uint8_t *local_key) { st->handshake_state = HANDSHAKE_UNINITIALIZED; st->handshake = NULL; st->tx_cipher = NULL; st->rx_cipher = NULL; st->remote_key_reference = remote_key_reference; + st->local_key = local_key; st->failed_handshakes = 0; } @@ -51,7 +55,7 @@ int start_protocol_handshake(struct NoiseState *st) { HANDLE_NOISE_ERROR(noise_handshakestate_new_by_name(&handshake, "Noise_XX_25519_ChaChaPoly_BLAKE2s", NOISE_ROLE_RESPONDER), "instantiating handshake pattern"); NoiseDHState *dh = noise_handshakestate_get_local_keypair_dh(handshake); - HANDLE_NOISE_ERROR(noise_dhstate_set_keypair_private(dh, st->local_key, sizeof(st->local_key)), "loading local private keys"); + HANDLE_NOISE_ERROR(noise_dhstate_set_keypair_private(dh, st->local_key, CURVE25519_KEY_LEN), "loading local private keys"); HANDLE_NOISE_ERROR(noise_handshakestate_start(handshake), "starting handshake"); @@ -74,7 +78,7 @@ int generate_identity_key(struct NoiseState *st) { uint8_t unused[CURVE25519_KEY_LEN]; /* the noise api is a bit bad here. */ memset(st->local_key, 0, sizeof(st->local_key)); - HANDLE_NOISE_ERROR(noise_dhstate_get_keypair(dh, st->local_key, sizeof(st->local_key), unused, sizeof(unused)), "saving key pair"); + HANDLE_NOISE_ERROR(noise_dhstate_get_keypair(dh, st->local_key, CURVE25519_KEY_LEN, unused, sizeof(unused)), "saving key pair"); return 0; errout: @@ -146,7 +150,14 @@ int try_continue_noise_handshake(struct NoiseState *st, uint8_t *buf, size_t len HANDLE_NOISE_ERROR(noise_dhstate_get_public_key(remote_dh, st->remote_key, sizeof(st->remote_key)), "getting remote pubkey"); - if (!memcmp(st->remote_key, st->remote_key_reference, sizeof(st->remote_key))) { /* keys match */ + /* TODO support list of known remote hosts here instead of just one */ + uint8_t remote_fp[BLAKE2S_HASH_SIZE]; + BLAKE2s_context_t bc; + BLAKE2s_reset(&bc); + BLAKE2s_update(&bc, st->remote_key, sizeof(st->remote_key)); + BLAKE2s_finish(&bc, remote_fp); + + if (!memcmp(remote_fp, st->remote_key_reference, sizeof(remote_fp))) { /* keys match */ uint8_t response = REPORT_PAIRING_SUCCESS; if (send_encrypted_message(st, &response, sizeof(response))) LOG_PRINTF("Error sending pairing response packet\n"); @@ -177,7 +188,10 @@ errout: } void persist_remote_key(struct NoiseState *st) { - memcpy(st->remote_key_reference, st->remote_key, sizeof(st->remote_key)); + BLAKE2s_context_t bc; + BLAKE2s_reset(&bc); + BLAKE2s_update(&bc, st->remote_key, sizeof(st->remote_key)); + BLAKE2s_finish(&bc, st->remote_key_reference); st->handshake_state = HANDSHAKE_DONE_KNOWN_HOST; } diff --git a/src/noise.h b/src/noise.h index a4c1e6e..92acdcf 100644 --- a/src/noise.h +++ b/src/noise.h @@ -30,7 +30,7 @@ struct NoiseState { NoiseHandshakeState *handshake; enum handshake_state handshake_state; NoiseCipherState *tx_cipher, *rx_cipher; - uint8_t local_key[CURVE25519_KEY_LEN]; + uint8_t *local_key; uint8_t remote_key[CURVE25519_KEY_LEN]; uint8_t *remote_key_reference; uint8_t handshake_hash[BLAKE2S_HASH_SIZE]; @@ -39,7 +39,7 @@ struct NoiseState { void uninit_handshake(struct NoiseState *st, enum handshake_state new_state); -void noise_state_init(struct NoiseState *st, uint8_t *remote_key_reference); +void noise_state_init(struct NoiseState *st, uint8_t *remote_key_reference, uint8_t *local_key); void persist_remote_key(struct NoiseState *st); int start_protocol_handshake(struct NoiseState *st); int reset_protocol_handshake(struct NoiseState *st); -- cgit