Skip to content
Snippets Groups Projects

Add CSPRNG

Merged schneider requested to merge schneider/rng into master
All threads resolved!
1 file
+ 23
31
Compare changes
  • Side-by-side
  • Inline
+ 97
0
#include "epicardium.h"
#include "modules.h"
#include "MAX77650-Arduino-Library.h"
#include "tiny-AES-c/aes.h"
#include "SHA256/mark2/sha256.h"
#include "mxc_sys.h"
#include "adc.h"
#include "mxc_delay.h"
#include "rtc.h"
#include "trng.h"
#include <string.h>
static struct AES_ctx aes_ctx;
int epic_trng_read(uint8_t *dest, size_t size)
{
if (dest == NULL)
return -EFAULT;
TRNG_Init(NULL);
TRNG_Read(MXC_TRNG, dest, size);
return 0;
}
int epic_csprng_read(uint8_t *dest, size_t size)
{
if (size >= AES_BLOCKLEN) {
int block_count = size / AES_BLOCKLEN;
AES_CTR_xcrypt_buffer(
&aes_ctx, dest, block_count * AES_BLOCKLEN
);
size -= block_count * AES_BLOCKLEN;
dest += block_count * AES_BLOCKLEN;
}
if (size > 0) {
uint8_t out[AES_BLOCKLEN];
AES_CTR_xcrypt_buffer(&aes_ctx, out, sizeof(out));
memcpy(dest, out, size);
}
return 0;
}
void rng_init(void)
{
uint8_t key[AES_BLOCKLEN];
uint8_t iv[AES_BLOCKLEN];
uint8_t hash[32];
sha256_context ctx;
int i;
sha256_init(&ctx);
/* Seed from TRNG.
* Takes about 10 ms. */
for (i = 0; i < 256; i++) {
uint8_t entropy[AES_BLOCKLEN];
epic_trng_read(entropy, AES_BLOCKLEN);
sha256_hash(&ctx, entropy, AES_BLOCKLEN);
}
// Seed from RTC
uint32_t sec, subsec;
while (RTC_GetTime(&sec, &subsec) == E_BUSY) {
mxc_delay(4000);
}
sha256_hash(&ctx, &sec, sizeof(sec));
sha256_hash(&ctx, &subsec, sizeof(subsec));
// Seed from SysTick
uint32_t systick = SysTick->VAL;
+1
sha256_hash(&ctx, &systick, sizeof(systick));
/* Seed from ADC.
* Takes about 50 ms */
ADC_Init(0x9, NULL);
GPIO_Config(&gpio_cfg_adc0);
MAX77650_setMUX_SEL(PMIC_AMUX_BATT_U);
for (i = 0; i < 256; i++) {
uint16_t adc_data;
ADC_StartConvert(ADC_CH_0, 0, 0);
ADC_GetData(&adc_data);
sha256_hash(&ctx, &adc_data, sizeof(adc_data));
}
MAX77650_setMUX_SEL(PMIC_AMUX_DISABLED);
sha256_done(&ctx, hash);
memcpy(key, hash, AES_BLOCKLEN);
memcpy(iv, hash + AES_BLOCKLEN, AES_BLOCKLEN);
AES_init_ctx_iv(&aes_ctx, key, iv);
}
Loading