From 76a6b631f4bd6866622f537870bc145c935bef40 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 18 Dec 2019 23:36:25 +0100 Subject: [cc20rng] Revamping the ChaCha20 seeding - chacha20_prng_block() uses counter in the state struct - chacha20_setup() replaces chacha20_prng_reseed() and fills the whole state struct, fixing a bug where only half of the key was being set; as a result of 'counter' being set, a state struct filled with entropy from the TRNG makes reseeding occur after a random number of rounds instead of after a fixed 2^32-1 rounds - decrementing of the block counter is done in chacha20_prng_block() - chacha output is copied to buf _after_ the interrupt driven transmission of buf to UART has finished, to stop the race between reading and refilling of buf --- src/cc20rng/main.c | 55 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) (limited to 'src/cc20rng/main.c') diff --git a/src/cc20rng/main.c b/src/cc20rng/main.c index 88b5144..cc063f4 100644 --- a/src/cc20rng/main.c +++ b/src/cc20rng/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2014, 2015, 2016 NORDUnet A/S + * Copyright (c) 2019 Sunet * All rights reserved. * * Redistribution and use in source and binary forms, with or @@ -32,7 +33,6 @@ #include #include "cc20_prng.h" -#include "main.h" #include "stm_init.h" #define UART_RANDOM_BYTES_PER_CHUNK 8 @@ -79,13 +79,14 @@ static inline volatile uint32_t *get_DMA_read_buf(void); static inline uint32_t safe_get_counter(volatile uint32_t *dmabuf, const uint32_t dmabuf_idx); static void check_uart_rx(UART_HandleTypeDef *this); -static void cc_reseed(struct cc20_state *cc); +static uint32_t cc_reseed(struct cc20_state *cc); void Error_Handler(void); int main() { - uint32_t i, timeout, block_counter = 0; - struct cc20_state cc, out; + uint32_t i, timeout, block_counter; + struct cc20_state cc_state = {0}; + uint8_t cc_result[CHACHA20_BLOCK_SIZE]; HAL_StatusTypeDef res; /* Initialize buffers */ @@ -113,40 +114,32 @@ int main() { HAL_Delay(125); } - /* Generate initial block of random data directly into buf */ - cc_reseed(&cc); - block_counter = RESEED_BLOCKS; - chacha20_prng_block(&cc, block_counter--, (struct cc20_state *)buf.rnd32); + /* Generate initial block of ChaCha20 output directly into buf. */ + block_counter = cc_reseed(&cc_state); + chacha20_prng_block(&cc_state, buf.rnd); + block_counter--; /* Main loop */ while (1) { - if (!(block_counter % 1000)) { + if (!(block_counter % 1000)) HAL_GPIO_TogglePin(LED_PORT, LED_YELLOW); - } - - if (!block_counter) { - cc_reseed(&cc); - block_counter = RESEED_BLOCKS; - } /* Send buf on UART (non blocking interrupt driven send). */ UartReady = RESET; - res = HAL_UART_Transmit_IT(huart, &buf.rnd[0], CHACHA20_BLOCK_SIZE); + res = HAL_UART_Transmit_IT(huart, buf.rnd, CHACHA20_BLOCK_SIZE); /* Generate next block while this block is being transmitted */ - chacha20_prng_block(&cc, block_counter--, &out); - /* Copying using a loop is faster than memcpy on STM32 */ - for (i = 0; i < CHACHA20_NUM_WORDS; i++) { - buf.rnd32[i] = out.i[i]; - } + if (!block_counter) + block_counter = cc_reseed(&cc_state); + chacha20_prng_block(&cc_state, cc_result); + block_counter--; + /* Wait for transfer to complete. */ if (res == HAL_OK) { timeout = 0xffff; - while (UartReady != SET && timeout) { + while (UartReady != SET && timeout) timeout--; - } } - if (UartReady != SET) { /* Failed to send, turn on RED LED for one second */ HAL_GPIO_WritePin(LED_PORT, LED_RED, GPIO_PIN_SET); @@ -154,6 +147,10 @@ int main() { HAL_GPIO_WritePin(LED_PORT, LED_RED, GPIO_PIN_RESET); } + /* Fill buffer with ChaCha20 output. */ + for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) + buf.rnd[i] = cc_result[i]; + /* Check for UART change request */ check_uart_rx(&huart1); check_uart_rx(&huart2); @@ -163,16 +160,18 @@ int main() { /** * @brief Reseed chacha20 state with hardware generated entropy. * @param cc: ChaCha20 state - * @retval None + * @retval ChaCha20 block counter */ -static void cc_reseed(struct cc20_state *cc) { +static uint32_t cc_reseed(struct cc20_state *cc) { HAL_GPIO_WritePin(LED_PORT, LED_BLUE, GPIO_PIN_SET); - get_entropy32(CHACHA20_BLOCK_SIZE / 4, 0); + get_entropy32(CHACHA20_BLOCK_SIZE_WORDS, 0); restart_DMA(); - chacha20_prng_reseed(cc, (uint32_t *)&buf); + memcpy(cc, buf.rnd, CHACHA20_BLOCK_SIZE); HAL_GPIO_WritePin(LED_PORT, LED_BLUE, GPIO_PIN_RESET); + + return cc->s.counter; } /** -- cgit v1.2.3