refactor(esp_hw_support): Linux esp_random impl now returns true random numbers

pull/13651/head
Jakob Hasse 2024-04-05 14:43:13 +02:00
rodzic 3cca8ff905
commit d297845126
2 zmienionych plików z 75 dodań i 25 usunięć

Wyświetl plik

@ -1,40 +1,38 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <time.h>
#include <stddef.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
#include <sys/param.h>
#include <unistd.h>
#include "esp_log.h"
static const char* TAG = "esp-random";
#define GETENTROPY_MAX_LEN 256
static void __attribute__((constructor)) esp_random_init(void)
{
srand(time(NULL));
ESP_LOGW(TAG, "esp_random do not provide a cryptographically secure numbers on Linux, and should never be used for anything security related");
}
static void __attribute__((constructor)) esp_random_init(void) { }
uint32_t esp_random(void)
{
/* Adding INT32_MAX to shift the results such that after conversion to uint32_t we still get 32 bits of random data */
return (rand() + INT32_MAX);
uint32_t random_number;
assert(getentropy(&random_number, sizeof(random_number)) == 0);
return random_number;
}
void esp_fill_random(void *buf, size_t len)
{
assert(buf != NULL);
uint8_t *buf_bytes = (uint8_t *)buf;
while (len > 0) {
uint32_t word = esp_random();
uint32_t to_copy = MIN(sizeof(word), len);
memcpy(buf_bytes, &word, to_copy);
buf_bytes += to_copy;
len -= to_copy;
// Note that we can't use getentropy() with len > 256 directly (see getentropy man page),
// hence reading in chunks
const size_t FULL_CHUNKS_NUM = (len / GETENTROPY_MAX_LEN);
const size_t REST_CHUNK_SIZE = len % GETENTROPY_MAX_LEN;
for (size_t chunk_num = 0; chunk_num < FULL_CHUNKS_NUM; chunk_num++) {
assert(getentropy(buf + chunk_num * GETENTROPY_MAX_LEN, GETENTROPY_MAX_LEN) == 0);
}
assert(getentropy(buf + FULL_CHUNKS_NUM * GETENTROPY_MAX_LEN, REST_CHUNK_SIZE) == 0);
}

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -8,13 +8,13 @@
#include "unity.h"
#include "esp_random.h"
/* Note: these are just sanity tests, the implementation of esp_random do not produce cryptographically secure numbers on Linux
/* Note: these are just sanity tests, the implementation of esp_random() relies on getentropy() on Linux.
*/
const size_t NUM_RANDOM = 128; /* in most cases this is massive overkill */
TEST_CASE("call esp_random()", "[random]")
{
const size_t NUM_RANDOM = 128; /* in most cases this is massive overkill */
uint32_t zeroes = UINT32_MAX;
uint32_t ones = 0;
for (int i = 0; i < NUM_RANDOM - 1; i++) {
@ -69,10 +69,62 @@ TEST_CASE("call esp_fill_random()", "[random]")
}
}
TEST_CASE("esp_fill_random() fills exactly one byte", "[random]")
{
const size_t BUF_SZ = 2;
uint8_t buf[BUF_SZ];
uint8_t one_buf[BUF_SZ];
bzero(one_buf, BUF_SZ);
for (size_t i = 0; i < NUM_RANDOM - 1; i++) {
esp_fill_random(buf, BUF_SZ - 1);
for (size_t j = 0; j < BUF_SZ - 1; j++) {
one_buf[j] |= buf[j];
}
}
TEST_ASSERT_EQUAL(0, one_buf[BUF_SZ - 1]);
TEST_ASSERT_GREATER_THAN(0, one_buf[BUF_SZ - 2]);
}
// The underlying system call accepts max 256 bytes, test that esp_fill_random() can read more
TEST_CASE("esp_fill_random() fills exactly 256 bytes", "[random]")
{
const size_t BUF_SZ = 257;
uint8_t buf[BUF_SZ];
uint8_t one_buf[BUF_SZ];
bzero(one_buf, BUF_SZ);
for (size_t i = 0; i < NUM_RANDOM - 1; i++) {
esp_fill_random(buf, BUF_SZ - 1);
for (size_t j = 0; j < BUF_SZ - 1; j++) {
one_buf[j] |= buf[j];
}
}
TEST_ASSERT_EQUAL(0, one_buf[BUF_SZ - 1]);
TEST_ASSERT_GREATER_THAN(0, one_buf[BUF_SZ - 2]);
TEST_ASSERT_GREATER_THAN(0, one_buf[0]);
}
TEST_CASE("esp_fill_random() fills exactly 257 bytes", "[random]")
{
const size_t BUF_SZ = 258;
uint8_t buf[BUF_SZ];
uint8_t one_buf[BUF_SZ];
bzero(one_buf, BUF_SZ);
for (size_t i = 0; i < NUM_RANDOM - 1; i++) {
esp_fill_random(buf, BUF_SZ - 1);
for (size_t j = 0; j < BUF_SZ - 1; j++) {
one_buf[j] |= buf[j];
}
}
TEST_ASSERT_EQUAL(0, one_buf[BUF_SZ - 1]);
TEST_ASSERT_GREATER_THAN(0, one_buf[BUF_SZ - 2]);
TEST_ASSERT_GREATER_THAN(0, one_buf[0]);
}
void app_main(void)
{
printf("Running heap linux API host test app");
printf("Running hw support linux API host test app");
unity_run_menu();
}