diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/demo.c | 78 | ||||
-rw-r--r-- | src/noise.c | 2 | ||||
-rw-r--r-- | src/noise.h | 3 |
3 files changed, 75 insertions, 8 deletions
@@ -32,6 +32,8 @@ #include "words.h"
#include "tracing.h"
+#include "crypto/noise-c/src/protocol/internal.h"
+
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
@@ -55,11 +57,25 @@ #define MAX_FAILED_HANDSHAKES 5
#endif
-
static struct NoiseState noise_state;
-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;
+static struct {
+ union {
+ struct {
+ uint8_t local_key[CURVE25519_KEY_LEN];
+ uint8_t remote_key_reference[BLAKE2S_HASH_SIZE];
+ };
+ uint32_t all_keys[0];
+ } keys;
+ struct {
+ uint8_t identity_key_valid;
+ uint8_t scrub_backup;
+ uint8_t scrubber_armed;
+ uint32_t old_scrub_pattern;
+ uint32_t new_scrub_pattern;
+ int scrub_idx_read;
+ int scrub_idx_done;
+ } mgmt __attribute__((aligned(4)));
+} keystore __attribute__((section(".backup_sram"))) = {0};
void _fini(void);
@@ -90,15 +106,60 @@ static void clock_setup(void) { rcc_periph_clock_enable(RCC_RNG);
}
+void arm_key_scrubber() {
+ keystore.mgmt.scrubber_armed = 1;
+}
+
+static void finish_scrub(int start_index, uint32_t pattern);
+static void finish_interrupted_scrub(void);
+
+void disarm_key_scrubber() {
+ keystore.mgmt.scrubber_armed = 0;
+ keystore.mgmt.old_scrub_pattern = keystore.mgmt.new_scrub_pattern;
+ keystore.mgmt.new_scrub_pattern = 0x00000000;
+ finish_scrub(0, keystore.mgmt.old_scrub_pattern);
+}
+
+static void finish_scrub(int start_index, uint32_t pattern) {
+ for (size_t i=start_index; i<sizeof(keystore.keys)/sizeof(keystore.keys.all_keys[0]); i++) {
+ keystore.mgmt.scrub_backup = keystore.keys.all_keys[i];
+ keystore.mgmt.scrub_idx_read = i;
+ keystore.keys.all_keys[i] ^= pattern;
+ keystore.mgmt.scrub_idx_done = i;
+ }
+}
+
+static void finish_interrupted_scrub(void) {
+ if (keystore.mgmt.scrub_idx_read != keystore.mgmt.scrub_idx_done)
+ keystore.keys.all_keys[keystore.mgmt.scrub_idx_read] = keystore.mgmt.scrub_backup;
+
+ finish_scrub(keystore.mgmt.scrub_idx_done, keystore.mgmt.old_scrub_pattern ^ keystore.mgmt.new_scrub_pattern);
+}
/* setup 10kHz timer */
static void tim6_setup(void) {
timer_reset(TIM6);
timer_set_prescaler(TIM6, 8400 - 1); // 84Mhz/10kHz - 1
timer_set_period(TIM6, 65535); // Overflow in ~6.5 seconds
+ timer_enable_irq(TIM6, TIM_DIER_UIE);
+ nvic_enable_irq(NVIC_TIM6_DAC_IRQ);
+ nvic_set_priority(NVIC_TIM6_DAC_IRQ, 15<<4); /* really low priority */
timer_enable_counter(TIM6);
}
+void tim6_dac_isr(void) {
+ /* Runs every ~6.5s on timer overrun */
+ timer_clear_flag(TIM6, TIM_SR_UIF);
+
+ if (!keystore.mgmt.scrubber_armed)
+ return;
+
+ keystore.mgmt.old_scrub_pattern = keystore.mgmt.new_scrub_pattern;
+ noise_rand_bytes(&keystore.mgmt.new_scrub_pattern, sizeof(keystore.mgmt.new_scrub_pattern));
+ LOG_PRINTF("Scrubbing keys using pattern %08x\n", keystore.mgmt.new_scrub_pattern);
+ finish_scrub(0, keystore.mgmt.old_scrub_pattern ^ keystore.mgmt.new_scrub_pattern);
+}
+
static uint32_t tim6_get_time_us(void)
{
uint32_t cnt = timer_get_counter(TIM6);
@@ -422,7 +483,8 @@ int main(void) 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 */
+ finish_interrupted_scrub();
+ disarm_key_scrubber();
tim6_setup();
#ifdef USART_DEBUG
@@ -455,15 +517,15 @@ int main(void) LOG_PRINTF("Initializing RNG...\n");
rand_init();
- noise_state_init(&noise_state, remote_key_reference, local_key);
+ noise_state_init(&noise_state, keystore.keys.remote_key_reference, keystore.keys.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. */
- if (!identity_key_valid) {
+ if (!keystore.mgmt.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;
+ keystore.mgmt.identity_key_valid = 1;
}
}
diff --git a/src/noise.c b/src/noise.c index 1ac336b..53e4383 100644 --- a/src/noise.c +++ b/src/noise.c @@ -36,6 +36,7 @@ void noise_state_init(struct NoiseState *st, uint8_t *remote_key_reference, uint int reset_protocol_handshake(struct NoiseState *st) { uninit_handshake(st, HANDSHAKE_UNINITIALIZED); + disarm_key_scrubber(); noise_cipherstate_free(st->tx_cipher); noise_cipherstate_free(st->rx_cipher); st->tx_cipher = NULL; @@ -98,6 +99,7 @@ void uninit_handshake(struct NoiseState *st, enum handshake_state new_state) { noise_handshakestate_free(st->handshake); st->handshake_state = new_state; st->handshake = NULL; + arm_key_scrubber(); } int try_continue_noise_handshake(struct NoiseState *st, uint8_t *buf, size_t len) { diff --git a/src/noise.h b/src/noise.h index 92acdcf..0df397a 100644 --- a/src/noise.h +++ b/src/noise.h @@ -47,4 +47,7 @@ int generate_identity_key(struct NoiseState *st); int try_continue_noise_handshake(struct NoiseState *st, uint8_t *buf, size_t len); int send_encrypted_message(struct NoiseState *st, uint8_t *msg, size_t len); +void arm_key_scrubber(void); +void disarm_key_scrubber(void); + #endif |