From 41eb060367b91415aadea26f63efc3db8fdbc92b Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 18 Dec 2019 23:35:46 +0100 Subject: [cc20rng] Code formatting changes Keep indentation level 2 in main.c to minimise changes. --- src/cc20rng/main.c | 118 ++++++++++++++++++++++++----------------------------- 1 file changed, 53 insertions(+), 65 deletions(-) (limited to 'src/cc20rng/main.c') diff --git a/src/cc20rng/main.c b/src/cc20rng/main.c index e478409..88b5144 100644 --- a/src/cc20rng/main.c +++ b/src/cc20rng/main.c @@ -31,12 +31,12 @@ */ #include +#include "cc20_prng.h" #include "main.h" #include "stm_init.h" -#include "cc20_prng.h" -#define UART_RANDOM_BYTES_PER_CHUNK 8 -#define RESEED_BLOCKS CHACHA20_MAX_BLOCK_COUNTER +#define UART_RANDOM_BYTES_PER_CHUNK 8 +#define RESEED_BLOCKS CHACHA20_MAX_BLOCK_COUNTER extern DMA_HandleTypeDef hdma_tim; @@ -44,19 +44,22 @@ static UART_HandleTypeDef *huart; static __IO ITStatus UartReady = RESET; static union { - uint8_t rnd[257]; /* 256 bytes + 1 for use in the POST */ + uint8_t rnd[257]; /* 256 bytes + 1 for use in the POST */ uint32_t rnd32[64]; } buf; -/* First DMA value (DMA_counters[0]) is unreliable, leftover in DMA FIFO perhaps? */ -#define FIRST_DMA_IDX_USED 3 +/* First DMA value (DMA_counters[0]) is unreliable, leftover in DMA FIFO + * perhaps? */ +#define FIRST_DMA_IDX_USED 3 /* * Number of counters used to produce 8 bits of entropy is: - * 8 * 4 - four flanks are used to produce two (hopefully) uncorrelated bits (a and b) + * 8 * 4 - four flanks are used to produce two (hopefully) uncorrelated bits + * (a and b) * * 2 - von Neumann will on average discard 1/2 of the bits 'a' and 'b' */ -#define DMA_COUNTERS_NUM ((UART_RANDOM_BYTES_PER_CHUNK * 8 * 4 * 2) + FIRST_DMA_IDX_USED + 1) +#define DMA_COUNTERS_NUM \ + ((UART_RANDOM_BYTES_PER_CHUNK * 8 * 4 * 2) + FIRST_DMA_IDX_USED + 1) struct DMA_params { volatile uint32_t buf0[DMA_COUNTERS_NUM]; volatile uint32_t buf1[DMA_COUNTERS_NUM]; @@ -64,28 +67,23 @@ struct DMA_params { }; static struct DMA_params DMA = { - {}, - {}, - 0, + {}, {}, 0, }; - /* The main work horse functions */ static void get_entropy32(uint32_t num_bytes, uint32_t buf_idx); /* Various support functions */ static inline uint32_t get_one_bit(void) __attribute__((__always_inline__)); static volatile uint32_t *restart_DMA(void); 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 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); void Error_Handler(void); - -int -main() -{ +int main() { uint32_t i, timeout, block_counter = 0; struct cc20_state cc, out; HAL_StatusTypeDef res; @@ -97,10 +95,10 @@ main() DMA.buf1[i] = 0xffff0100 + i; } - stm_init((uint32_t *) &DMA.buf0, DMA_COUNTERS_NUM); + stm_init((uint32_t *)&DMA.buf0, DMA_COUNTERS_NUM); - if (! chacha20_prng_self_test()) { - Error_Handler(); + if (!chacha20_prng_self_test()) { + Error_Handler(); } /* Ensure there is actual Timer IC counters in both DMA buffers. */ @@ -110,29 +108,25 @@ main() huart = &huart1; /* Toggle GREEN LED to show we've initialized */ - { - for (i = 0; i < 10; i++) { - HAL_GPIO_TogglePin(LED_PORT, LED_GREEN); - HAL_Delay(125); - } + for (i = 0; i < 10; i++) { + HAL_GPIO_TogglePin(LED_PORT, LED_GREEN); + 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); + chacha20_prng_block(&cc, block_counter--, (struct cc20_state *)buf.rnd32); - /* - * Main loop - */ + /* 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; + if (!block_counter) { + cc_reseed(&cc); + block_counter = RESEED_BLOCKS; } /* Send buf on UART (non blocking interrupt driven send). */ @@ -143,12 +137,14 @@ main() 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]; + buf.rnd32[i] = out.i[i]; } if (res == HAL_OK) { timeout = 0xffff; - while (UartReady != SET && timeout) { timeout--; } + while (UartReady != SET && timeout) { + timeout--; + } } if (UartReady != SET) { @@ -164,22 +160,19 @@ main() } } - /** * @brief Reseed chacha20 state with hardware generated entropy. * @param cc: ChaCha20 state * @retval None */ -static void -cc_reseed(struct cc20_state *cc) -{ - HAL_GPIO_WritePin(LED_PORT, LED_BLUE, GPIO_PIN_SET); +static void cc_reseed(struct cc20_state *cc) { + HAL_GPIO_WritePin(LED_PORT, LED_BLUE, GPIO_PIN_SET); - get_entropy32(CHACHA20_BLOCK_SIZE / 4, 0); - restart_DMA(); - chacha20_prng_reseed(cc, (uint32_t *) &buf); + get_entropy32(CHACHA20_BLOCK_SIZE / 4, 0); + restart_DMA(); + chacha20_prng_reseed(cc, (uint32_t *)&buf); - HAL_GPIO_WritePin(LED_PORT, LED_BLUE, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LED_PORT, LED_BLUE, GPIO_PIN_RESET); } /** @@ -188,16 +181,14 @@ cc_reseed(struct cc20_state *cc) * @param start: Start index value into buf.rnd32. * @retval None */ -static inline void get_entropy32(uint32_t count, const uint32_t start) -{ +static inline void get_entropy32(uint32_t count, const uint32_t start) { uint32_t i, bits, buf_idx; buf_idx = start; do { bits = 0; - /* Get 32 bits of entropy. - */ + /* Get 32 bits of entropy. */ for (i = 32; i; i--) { bits <<= 1; bits += get_one_bit(); @@ -213,8 +204,7 @@ static inline void get_entropy32(uint32_t count, const uint32_t start) * @param None * @retval One bit, in the LSB of an uint32_t since this is a 32 bit MCU. */ -static inline uint32_t get_one_bit() -{ +static inline uint32_t get_one_bit() { register uint32_t a, b, temp; /* Start at end of buffer so restart_DMA() is called. */ static uint32_t dmabuf_idx = DMA_COUNTERS_NUM - 1; @@ -264,8 +254,7 @@ static inline uint32_t get_one_bit() * @param None * @retval Pointer to buffer currently being read from. */ -static inline volatile uint32_t *get_DMA_read_buf(void) -{ +static inline volatile uint32_t *get_DMA_read_buf(void) { return DMA.write_buf ? DMA.buf0 : DMA.buf1; } @@ -274,8 +263,7 @@ static inline volatile uint32_t *get_DMA_read_buf(void) * @param None * @retval Pointer to buffer currently being written to. */ -static inline volatile uint32_t *get_DMA_write_buf(void) -{ +static inline volatile uint32_t *get_DMA_write_buf(void) { return DMA.write_buf ? DMA.buf1 : DMA.buf0; } @@ -284,16 +272,17 @@ static inline volatile uint32_t *get_DMA_write_buf(void) * @param None * @retval Pointer to buffer full of Timer IC values ready to be consumed. */ -static volatile uint32_t *restart_DMA(void) -{ +static volatile uint32_t *restart_DMA(void) { /* Wait for transfer complete flag to become SET. Trying to change the * M0AR register while the DMA is running is a no-no. */ - while(__HAL_DMA_GET_FLAG(&hdma_tim, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_tim)) == RESET) { ; } + while (__HAL_DMA_GET_FLAG(&hdma_tim, + __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_tim)) == RESET) + ; /* Switch buffer being written to */ DMA.write_buf ^= 1; - hdma_tim.Instance->M0AR = (uint32_t) get_DMA_write_buf(); + hdma_tim.Instance->M0AR = (uint32_t)get_DMA_write_buf(); /* Start at 0 to help manual inspection */ TIM2->CNT = 0; @@ -311,7 +300,8 @@ static volatile uint32_t *restart_DMA(void) * @param dmabuf_idx: Word index into `dmabuf'. * @retval One Timer IC counter value. */ -static inline uint32_t safe_get_counter(volatile uint32_t *dmabuf, const uint32_t dmabuf_idx) { +static inline uint32_t safe_get_counter(volatile uint32_t *dmabuf, + const uint32_t dmabuf_idx) { register uint32_t a; /* Prevent re-use of values. DMA stored values are <= 0xffff. */ do { @@ -322,8 +312,7 @@ static inline uint32_t safe_get_counter(volatile uint32_t *dmabuf, const uint32_ } /* UART transmit complete callback */ -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UH) -{ +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UH) { if ((UH->Instance == USART1 && huart->Instance == USART1) || (UH->Instance == USART2 && huart->Instance == USART2)) { /* Signal UART transmit complete to the code in the main loop. */ @@ -350,10 +339,9 @@ static void check_uart_rx(UART_HandleTypeDef *this) { * @param None * @retval None */ - -void Error_Handler(void) -{ +void Error_Handler(void) { /* Turn on RED LED and then loop indefinitely */ HAL_GPIO_WritePin(LED_PORT, LED_RED, GPIO_PIN_SET); - while(1) { ; } + while (1) + ; } -- cgit v1.2.3 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