known device/sram data persistence working
This commit is contained in:
parent
66f9e82c5c
commit
eb481f1cda
5 changed files with 53 additions and 14 deletions
|
|
@ -33,6 +33,17 @@ MEMORY
|
||||||
/* Include the common ld script. */
|
/* Include the common ld script. */
|
||||||
INCLUDE libopencm3_stm32f4.ld
|
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_start = ORIGIN(ram));
|
||||||
PROVIDE(_ram_end = ORIGIN(ram) + LENGTH(ram));
|
PROVIDE(_ram_end = ORIGIN(ram) + LENGTH(ram));
|
||||||
PROVIDE(_rom_start = ORIGIN(rom));
|
PROVIDE(_rom_start = ORIGIN(rom));
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import threading
|
||||||
import binascii
|
import binascii
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
import serial
|
import serial
|
||||||
import gi
|
import gi
|
||||||
|
|
@ -136,11 +137,11 @@ def run_pairing_gui(port, baudrate, debug=False):
|
||||||
raise SystemError('Unknown noise error')
|
raise SystemError('Unknown noise error')
|
||||||
|
|
||||||
with open(known_devices_file, 'a') as f:
|
with open(known_devices_file, 'a') as f:
|
||||||
f.write(noise.remote_fingerprint)
|
f.write(f'{noise.remote_fingerprint} # added {time.ctime()}\n')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
with open(known_devices_file) as f:
|
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:
|
if noise.remote_fingerprint not in known_devices:
|
||||||
raise ValueError('Remote host is untrusted but seems to trust us.')
|
raise ValueError('Remote host is untrusted but seems to trust us.')
|
||||||
|
|
|
||||||
23
src/demo.c
23
src/demo.c
|
|
@ -38,6 +38,7 @@
|
||||||
#include <libopencm3/stm32/timer.h>
|
#include <libopencm3/stm32/timer.h>
|
||||||
#include <libopencm3/stm32/otg_hs.h>
|
#include <libopencm3/stm32/otg_hs.h>
|
||||||
#include <libopencm3/stm32/otg_fs.h>
|
#include <libopencm3/stm32/otg_fs.h>
|
||||||
|
#include <libopencm3/stm32/pwr.h>
|
||||||
#include <libopencm3/stm32/dma.h>
|
#include <libopencm3/stm32/dma.h>
|
||||||
#include <libopencm3/cm3/nvic.h>
|
#include <libopencm3/cm3/nvic.h>
|
||||||
#include <libopencmsis/core_cm3.h>
|
#include <libopencmsis/core_cm3.h>
|
||||||
|
|
@ -56,7 +57,9 @@
|
||||||
|
|
||||||
|
|
||||||
static struct NoiseState noise_state;
|
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);
|
void _fini(void);
|
||||||
|
|
@ -81,6 +84,9 @@ static void clock_setup(void) {
|
||||||
rcc_periph_clock_enable(RCC_DMA2);
|
rcc_periph_clock_enable(RCC_DMA2);
|
||||||
rcc_periph_clock_enable(RCC_DMA1);
|
rcc_periph_clock_enable(RCC_DMA1);
|
||||||
|
|
||||||
|
rcc_periph_clock_enable(RCC_PWR);
|
||||||
|
rcc_periph_clock_enable(RCC_BKPSRAM);
|
||||||
|
|
||||||
rcc_periph_clock_enable(RCC_RNG);
|
rcc_periph_clock_enable(RCC_RNG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,6 +419,8 @@ int main(void)
|
||||||
{
|
{
|
||||||
clock_setup();
|
clock_setup();
|
||||||
gpio_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 */
|
/* provides time_curr_us to usbh_poll function */
|
||||||
tim6_setup();
|
tim6_setup();
|
||||||
|
|
@ -447,12 +455,17 @@ int main(void)
|
||||||
LOG_PRINTF("Initializing RNG...\n");
|
LOG_PRINTF("Initializing RNG...\n");
|
||||||
rand_init();
|
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 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. */
|
/* 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 (!identity_key_valid) {
|
||||||
if (generate_identity_key(&noise_state))
|
LOG_PRINTF("Generating identity key...\n");
|
||||||
LOG_PRINTF("Error generating identiy key\n");
|
if (generate_identity_key(&noise_state)) {
|
||||||
|
LOG_PRINTF("Error generating identiy key\n");
|
||||||
|
} else {
|
||||||
|
identity_key_valid = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int poll_ctr = 0;
|
int poll_ctr = 0;
|
||||||
while (23) {
|
while (23) {
|
||||||
|
|
|
||||||
24
src/noise.c
24
src/noise.c
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include "noise.h"
|
#include "noise.h"
|
||||||
#include "packet_interface.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 { \
|
#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;
|
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_state = HANDSHAKE_UNINITIALIZED;
|
||||||
st->handshake = NULL;
|
st->handshake = NULL;
|
||||||
st->tx_cipher = NULL;
|
st->tx_cipher = NULL;
|
||||||
st->rx_cipher = NULL;
|
st->rx_cipher = NULL;
|
||||||
st->remote_key_reference = remote_key_reference;
|
st->remote_key_reference = remote_key_reference;
|
||||||
|
st->local_key = local_key;
|
||||||
st->failed_handshakes = 0;
|
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");
|
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);
|
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");
|
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. */
|
uint8_t unused[CURVE25519_KEY_LEN]; /* the noise api is a bit bad here. */
|
||||||
memset(st->local_key, 0, sizeof(st->local_key));
|
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;
|
return 0;
|
||||||
errout:
|
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");
|
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;
|
uint8_t response = REPORT_PAIRING_SUCCESS;
|
||||||
if (send_encrypted_message(st, &response, sizeof(response)))
|
if (send_encrypted_message(st, &response, sizeof(response)))
|
||||||
LOG_PRINTF("Error sending pairing response packet\n");
|
LOG_PRINTF("Error sending pairing response packet\n");
|
||||||
|
|
@ -177,7 +188,10 @@ errout:
|
||||||
}
|
}
|
||||||
|
|
||||||
void persist_remote_key(struct NoiseState *st) {
|
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;
|
st->handshake_state = HANDSHAKE_DONE_KNOWN_HOST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ struct NoiseState {
|
||||||
NoiseHandshakeState *handshake;
|
NoiseHandshakeState *handshake;
|
||||||
enum handshake_state handshake_state;
|
enum handshake_state handshake_state;
|
||||||
NoiseCipherState *tx_cipher, *rx_cipher;
|
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[CURVE25519_KEY_LEN];
|
||||||
uint8_t *remote_key_reference;
|
uint8_t *remote_key_reference;
|
||||||
uint8_t handshake_hash[BLAKE2S_HASH_SIZE];
|
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 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);
|
void persist_remote_key(struct NoiseState *st);
|
||||||
int start_protocol_handshake(struct NoiseState *st);
|
int start_protocol_handshake(struct NoiseState *st);
|
||||||
int reset_protocol_handshake(struct NoiseState *st);
|
int reset_protocol_handshake(struct NoiseState *st);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue