mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
refactor(esp_hw_support): Linux esp_random impl now returns true random numbers
This commit is contained in:
parent
3cca8ff905
commit
d297845126
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user