add encrypting for save files
add libhydrogen for encrypting and decrypting #9
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
static bool
|
||||
hydro_random_rbit(uint16_t x)
|
||||
{
|
||||
uint8_t x8;
|
||||
|
||||
x8 = ((uint8_t) (x >> 8)) ^ (uint8_t) x;
|
||||
x8 = (x8 >> 4) ^ (x8 & 0xf);
|
||||
x8 = (x8 >> 2) ^ (x8 & 0x3);
|
||||
x8 = (x8 >> 1) ^ x8;
|
||||
|
||||
return (bool) (x8 & 1);
|
||||
}
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
uint16_t tc;
|
||||
bool a, b;
|
||||
|
||||
cli();
|
||||
MCUSR = 0;
|
||||
WDTCSR |= _BV(WDCE) | _BV(WDE);
|
||||
WDTCSR = _BV(WDIE);
|
||||
sei();
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
delay(1);
|
||||
tc = TCNT1;
|
||||
hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc);
|
||||
a = hydro_random_rbit(tc);
|
||||
delay(1);
|
||||
tc = TCNT1;
|
||||
b = hydro_random_rbit(tc);
|
||||
hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc);
|
||||
if (a == b) {
|
||||
continue;
|
||||
}
|
||||
hydro_hash_update(&st, (const uint8_t *) &b, sizeof b);
|
||||
ebits++;
|
||||
}
|
||||
|
||||
cli();
|
||||
MCUSR = 0;
|
||||
WDTCSR |= _BV(WDCE) | _BV(WDE);
|
||||
WDTCSR = 0;
|
||||
sei();
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ISR(WDT_vect)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#if defined(CH32V30x_D8) || defined(CH32V30x_D8C)
|
||||
# include <ch32v30x_rng.h>
|
||||
#else
|
||||
# error CH32 implementation missing!
|
||||
#endif
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
|
||||
// Enable RNG clock source
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_RNG, ENABLE);
|
||||
|
||||
// RNG Peripheral enable
|
||||
RNG_Cmd(ENABLE);
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET)
|
||||
;
|
||||
uint32_t r = RNG_GetRandomNumber();
|
||||
|
||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
||||
ebits += 32;
|
||||
}
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
uint32_t rand_32();
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
uint32_t r = rand_32();
|
||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
||||
ebits += 32;
|
||||
}
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Declarations from ChibiOS HAL TRNG module */
|
||||
|
||||
extern struct hal_trng_driver TRNGD1;
|
||||
|
||||
void trngStart(struct hal_trng_driver *, const void *);
|
||||
bool trngGenerate(struct hal_trng_driver *, size_t size, uint8_t *);
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
trngStart(&TRNGD1, NULL);
|
||||
|
||||
if (trngGenerate(&TRNGD1, sizeof hydro_random_context.state, hydro_random_context.state)) {
|
||||
return -1;
|
||||
}
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Important: RF *must* be activated on ESP board
|
||||
// https://techtutorialsx.com/2017/12/22/esp32-arduino-random-number-generation/
|
||||
#ifdef ESP32
|
||||
# include <esp_system.h>
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO
|
||||
# include <Arduino.h>
|
||||
#endif
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
uint32_t r = esp_random();
|
||||
|
||||
delay(10);
|
||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
||||
ebits += 32;
|
||||
}
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
get_random_bytes(hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
|
||||
#if defined(MBEDTLS_ENTROPY_C)
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
mbedtls_entropy_context entropy;
|
||||
uint16_t pos = 0;
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
|
||||
// Pull data directly out of the entropy pool for the state, as it's small enough.
|
||||
if (mbedtls_entropy_func(&entropy, (uint8_t *) &hydro_random_context.counter,
|
||||
sizeof hydro_random_context.counter) != 0) {
|
||||
return -1;
|
||||
}
|
||||
// mbedtls_entropy_func can't provide more than MBEDTLS_ENTROPY_BLOCK_SIZE in one go.
|
||||
// This constant depends of mbedTLS configuration (whether the PRNG is backed by SHA256/SHA512
|
||||
// at this time) Therefore, if necessary, we get entropy multiple times.
|
||||
|
||||
do {
|
||||
const uint8_t dataLeftToConsume = gimli_BLOCKBYTES - pos;
|
||||
const uint8_t currentChunkSize = (dataLeftToConsume > MBEDTLS_ENTROPY_BLOCK_SIZE)
|
||||
? MBEDTLS_ENTROPY_BLOCK_SIZE
|
||||
: dataLeftToConsume;
|
||||
|
||||
// Forces mbedTLS to fetch fresh entropy, then get some to feed libhydrogen.
|
||||
if (mbedtls_entropy_gather(&entropy) != 0 ||
|
||||
mbedtls_entropy_func(&entropy, &hydro_random_context.state[pos], currentChunkSize) !=
|
||||
0) {
|
||||
return -1;
|
||||
}
|
||||
pos += MBEDTLS_ENTROPY_BLOCK_SIZE;
|
||||
} while (pos < gimli_BLOCKBYTES);
|
||||
|
||||
mbedtls_entropy_free(&entropy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# error Need an entropy source
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
// Important: The SoftDevice *must* be activated to enable reading from the RNG
|
||||
// http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Frng.html
|
||||
|
||||
#include <nrf_soc.h>
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
const uint8_t total_bytes = 32;
|
||||
uint8_t remaining_bytes = total_bytes;
|
||||
uint8_t available_bytes;
|
||||
uint8_t rand_buffer[32];
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
for (;;) {
|
||||
if (sd_rand_application_bytes_available_get(&available_bytes) != NRF_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
if (available_bytes > 0) {
|
||||
if (available_bytes > remaining_bytes) {
|
||||
available_bytes = remaining_bytes;
|
||||
}
|
||||
if (sd_rand_application_vector_get(rand_buffer, available_bytes) != NRF_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
hydro_hash_update(&st, rand_buffer, available_bytes);
|
||||
remaining_bytes -= available_bytes;
|
||||
}
|
||||
if (remaining_bytes <= 0) {
|
||||
break;
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Note: All particle platforms except for the Spark Core have a HW RNG. Only allow building on
|
||||
// supported platforms for now. PLATFORM_ID definitions:
|
||||
// https://github.com/particle-iot/device-os/blob/mesh-develop/hal/shared/platforms.h
|
||||
|
||||
#include <Particle.h>
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
uint32_t r = HAL_RNG_GetRandomNumber();
|
||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
||||
ebits += 32;
|
||||
}
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef RANDOM_PICO_H_
|
||||
#define RANDOM_PICO_H_
|
||||
|
||||
#include "pico/rand.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
uint32_t r = get_rand_32();
|
||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
||||
ebits += 32;
|
||||
}
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RANDOM_PICO_H_ */
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <random.h>
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
random_bytes(hydro_random_context.state, sizeof(hydro_random_context.state));
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <hw_rng.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#define DBG_TAG "libhydrogen"
|
||||
#define DBG_LVL DBG_LOG
|
||||
#include <rtdbg.h>
|
||||
|
||||
static int
|
||||
hydrogen_init(void)
|
||||
{
|
||||
if (hydro_init() != 0) {
|
||||
abort();
|
||||
}
|
||||
LOG_I("libhydrogen initialized");
|
||||
return 0;
|
||||
}
|
||||
INIT_APP_EXPORT(hydrogen_init);
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
uint32_t r = rt_hwcrypto_rng_update();
|
||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
||||
ebits += 32;
|
||||
}
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
// Use hardware RNG peripheral
|
||||
// Working with HAL, LL Driver (untested)
|
||||
#if defined(STM32F4) || defined(STM32L4)
|
||||
|
||||
# if defined(STM32F4)
|
||||
# include "stm32f4xx.h"
|
||||
# elif defined(STM32L4)
|
||||
# include "stm32l4xx_hal_rng.h"
|
||||
|
||||
static RNG_HandleTypeDef RngHandle;
|
||||
# endif
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
|
||||
hydro_hash_state st;
|
||||
uint16_t ebits = 0;
|
||||
|
||||
__IO uint32_t tmpreg;
|
||||
|
||||
# if defined(STM32F4)
|
||||
// Enable RNG clock source
|
||||
SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN);
|
||||
|
||||
// Delay after an RCC peripheral clock enabling
|
||||
tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN);
|
||||
UNUSED(tmpreg);
|
||||
|
||||
// RNG Peripheral enable
|
||||
SET_BIT(RNG->CR, RNG_CR_RNGEN);
|
||||
# elif defined(STM32L4)
|
||||
RngHandle.Instance = RNG;
|
||||
HAL_RNG_Init(&RngHandle);
|
||||
# endif
|
||||
|
||||
hydro_hash_init(&st, ctx, NULL);
|
||||
|
||||
while (ebits < 256) {
|
||||
uint32_t r = 0;
|
||||
# if defined(STM32F4)
|
||||
while (!(READ_BIT(RNG->SR, RNG_SR_DRDY))) {
|
||||
}
|
||||
|
||||
r = RNG->DR;
|
||||
# elif defined(STM32L4)
|
||||
if (HAL_RNG_GenerateRandomNumber(&RngHandle, &r) != HAL_OK) {
|
||||
continue;
|
||||
}
|
||||
# endif
|
||||
hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
|
||||
ebits += 32;
|
||||
}
|
||||
|
||||
hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# error SMT32 implementation missing!
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef __linux__
|
||||
# include <poll.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __linux__
|
||||
static int
|
||||
hydro_random_block_on_dev_random(void)
|
||||
{
|
||||
struct pollfd pfd;
|
||||
int fd;
|
||||
int pret;
|
||||
|
||||
fd = open("/dev/random", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN;
|
||||
pfd.revents = 0;
|
||||
do {
|
||||
pret = poll(&pfd, 1, -1);
|
||||
} while (pret < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (pret != 1) {
|
||||
(void) close(fd);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
return close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t
|
||||
hydro_random_safe_read(const int fd, void *const buf_, size_t len)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *) buf_;
|
||||
ssize_t readnb;
|
||||
|
||||
do {
|
||||
while ((readnb = read(fd, buf, len)) < (ssize_t) 0 && (errno == EINTR || errno == EAGAIN)) {
|
||||
}
|
||||
if (readnb < (ssize_t) 0) {
|
||||
return readnb;
|
||||
}
|
||||
if (readnb == (ssize_t) 0) {
|
||||
break;
|
||||
}
|
||||
len -= (size_t) readnb;
|
||||
buf += readnb;
|
||||
} while (len > (ssize_t) 0);
|
||||
|
||||
return (ssize_t) (buf - (unsigned char *) buf_);
|
||||
}
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
uint8_t tmp[gimli_BLOCKBYTES + 8];
|
||||
int fd;
|
||||
int ret = -1;
|
||||
|
||||
#ifdef __linux__
|
||||
if (hydro_random_block_on_dev_random() != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd == -1 && errno != EINTR) {
|
||||
return -1;
|
||||
}
|
||||
} while (fd == -1);
|
||||
if (hydro_random_safe_read(fd, tmp, sizeof tmp) == (ssize_t) sizeof tmp) {
|
||||
memcpy(hydro_random_context.state, tmp, gimli_BLOCKBYTES);
|
||||
memcpy(&hydro_random_context.counter, tmp + gimli_BLOCKBYTES, 8);
|
||||
hydro_memzero(tmp, sizeof tmp);
|
||||
ret = 0;
|
||||
}
|
||||
ret |= close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <unistd.h>
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
if (getentropy(hydro_random_context.state, sizeof hydro_random_context.state) != 0) {
|
||||
return -1;
|
||||
}
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <windows.h>
|
||||
#define RtlGenRandom SystemFunction036
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
BOOLEAN NTAPI
|
||||
RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
|
||||
#pragma comment(lib, "advapi32.lib")
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
if (!RtlGenRandom((PVOID) hydro_random_context.state,
|
||||
(ULONG) sizeof hydro_random_context.state)) {
|
||||
return -1;
|
||||
}
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <zephyr/random/random.h>
|
||||
|
||||
static int
|
||||
hydro_random_init(void)
|
||||
{
|
||||
if (sys_csrand_get(&hydro_random_context.state, sizeof hydro_random_context.state) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user