mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-06 14:14:33 +02:00
esp32: move hw random
This commit is contained in:
@@ -18,7 +18,6 @@ else()
|
||||
"crosscore_int.c"
|
||||
"dport_access.c"
|
||||
"esp_himem.c"
|
||||
"hw_random.c"
|
||||
"spiram.c"
|
||||
"spiram_psram.c"
|
||||
"system_api_esp32.c")
|
||||
|
@@ -1,69 +0,0 @@
|
||||
// Copyright 2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_attr.h"
|
||||
#include "hal/cpu_hal.h"
|
||||
#include "esp32/clk.h"
|
||||
#include "soc/wdev_reg.h"
|
||||
|
||||
uint32_t IRAM_ATTR esp_random(void)
|
||||
{
|
||||
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
|
||||
* of extra entropy from a hardware randomness source every APB clock cycle
|
||||
* (provided WiFi or BT are enabled). To make sure entropy is not drained
|
||||
* faster than it is added, this function needs to wait for at least 16 APB
|
||||
* clock cycles after reading previous word. This implementation may actually
|
||||
* wait a bit longer due to extra time spent in arithmetic and branch statements.
|
||||
*
|
||||
* As a (probably unncessary) precaution to avoid returning the
|
||||
* RNG state as-is, the result is XORed with additional
|
||||
* WDEV_RND_REG reads while waiting.
|
||||
*/
|
||||
|
||||
/* This code does not run in a critical section, so CPU frequency switch may
|
||||
* happens while this code runs (this will not happen in the current
|
||||
* implementation, but possible in the future). However if that happens,
|
||||
* the number of cycles spent on frequency switching will certainly be more
|
||||
* than the number of cycles we need to wait here.
|
||||
*/
|
||||
uint32_t cpu_to_apb_freq_ratio = esp_clk_cpu_freq() / esp_clk_apb_freq();
|
||||
|
||||
static uint32_t last_ccount = 0;
|
||||
uint32_t ccount;
|
||||
uint32_t result = 0;
|
||||
do {
|
||||
ccount = cpu_hal_get_cycle_count();
|
||||
result ^= REG_READ(WDEV_RND_REG);
|
||||
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16);
|
||||
last_ccount = ccount;
|
||||
return result ^ REG_READ(WDEV_RND_REG);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@@ -18,7 +18,6 @@ else()
|
||||
"esp_hmac.c"
|
||||
"esp_ds.c"
|
||||
"esp_crypto_lock.c"
|
||||
"hw_random.c"
|
||||
"memprot.c"
|
||||
"system_api_esp32c3.c")
|
||||
set(include_dirs "include")
|
||||
|
@@ -1,68 +0,0 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp32c3/clk.h"
|
||||
#include "soc/wdev_reg.h"
|
||||
#include "hal/cpu_hal.h"
|
||||
|
||||
uint32_t IRAM_ATTR esp_random(void)
|
||||
{
|
||||
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
|
||||
* of extra entropy from a hardware randomness source every APB clock cycle
|
||||
* (provided WiFi or BT are enabled). To make sure entropy is not drained
|
||||
* faster than it is added, this function needs to wait for at least 16 APB
|
||||
* clock cycles after reading previous word. This implementation may actually
|
||||
* wait a bit longer due to extra time spent in arithmetic and branch statements.
|
||||
*
|
||||
* As a (probably unncessary) precaution to avoid returning the
|
||||
* RNG state as-is, the result is XORed with additional
|
||||
* WDEV_RND_REG reads while waiting.
|
||||
*/
|
||||
|
||||
/* This code does not run in a critical section, so CPU frequency switch may
|
||||
* happens while this code runs (this will not happen in the current
|
||||
* implementation, but possible in the future). However if that happens,
|
||||
* the number of cycles spent on frequency switching will certainly be more
|
||||
* than the number of cycles we need to wait here.
|
||||
*/
|
||||
uint32_t cpu_to_apb_freq_ratio = esp_clk_cpu_freq() / esp_clk_apb_freq();
|
||||
|
||||
static uint32_t last_ccount = 0;
|
||||
uint32_t ccount;
|
||||
uint32_t result = 0;
|
||||
do {
|
||||
ccount = cpu_hal_get_cycle_count();
|
||||
result ^= REG_READ(WDEV_RND_REG);
|
||||
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16);
|
||||
last_ccount = ccount;
|
||||
return result ^ REG_READ(WDEV_RND_REG);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@@ -16,7 +16,6 @@ else()
|
||||
"clk.c"
|
||||
"crosscore_int.c"
|
||||
"dport_access.c"
|
||||
"hw_random.c"
|
||||
"spiram.c"
|
||||
"spiram_psram.c"
|
||||
"system_api_esp32s2.c"
|
||||
|
@@ -1,66 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
/* Note: these are just sanity tests, not the same as
|
||||
entropy tests
|
||||
*/
|
||||
|
||||
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++) {
|
||||
uint32_t r = esp_random();
|
||||
ones |= r;
|
||||
zeroes &= ~r;
|
||||
}
|
||||
|
||||
/* assuming a 'white' random distribution, we can expect
|
||||
usually at least one time each bit will be zero and at
|
||||
least one time each will be one. Statistically this
|
||||
can still fail, just *very* unlikely to. */
|
||||
TEST_ASSERT_EQUAL_HEX32(0, zeroes);
|
||||
TEST_ASSERT_EQUAL_HEX32(UINT32_MAX, ones);
|
||||
}
|
||||
|
||||
TEST_CASE("call esp_fill_random()", "[random]")
|
||||
{
|
||||
const size_t NUM_BUF = 200;
|
||||
const size_t BUF_SZ = 16;
|
||||
uint8_t buf[NUM_BUF][BUF_SZ];
|
||||
uint8_t zero_buf[BUF_SZ];
|
||||
uint8_t one_buf[BUF_SZ];
|
||||
|
||||
bzero(buf, sizeof(buf));
|
||||
bzero(one_buf, sizeof(zero_buf));
|
||||
memset(zero_buf, 0xFF, sizeof(one_buf));
|
||||
|
||||
for (int i = 0; i < NUM_BUF; i++) {
|
||||
esp_fill_random(buf[i], BUF_SZ);
|
||||
}
|
||||
/* No two 128-bit buffers should be the same
|
||||
(again, statistically this could happen but it's very unlikely) */
|
||||
for (int i = 0; i < NUM_BUF; i++) {
|
||||
for (int j = 0; j < NUM_BUF; j++) {
|
||||
if (i != j) {
|
||||
TEST_ASSERT_NOT_EQUAL(0, memcmp(buf[i], buf[j], BUF_SZ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the same all bits are zero and one at least once test across the buffers */
|
||||
for (int i = 0; i < NUM_BUF; i++) {
|
||||
for (int x = 0; x < BUF_SZ; x++) {
|
||||
zero_buf[x] &= ~buf[i][x];
|
||||
one_buf[x] |= buf[i][x];
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < BUF_SZ; x++) {
|
||||
TEST_ASSERT_EQUAL_HEX8(0, zero_buf[x]);
|
||||
TEST_ASSERT_EQUAL_HEX8(0xFF, one_buf[x]);
|
||||
}
|
||||
}
|
@@ -17,7 +17,6 @@ else()
|
||||
"crosscore_int.c"
|
||||
"dport_access.c"
|
||||
"esp_crypto_lock.c"
|
||||
"hw_random.c"
|
||||
|
||||
"memprot.c"
|
||||
"spiram.c"
|
||||
|
@@ -1,69 +0,0 @@
|
||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_attr.h"
|
||||
#include "hal/cpu_hal.h"
|
||||
#include "esp32s3/clk.h"
|
||||
#include "soc/wdev_reg.h"
|
||||
|
||||
uint32_t IRAM_ATTR esp_random(void)
|
||||
{
|
||||
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
|
||||
* of extra entropy from a hardware randomness source every APB clock cycle
|
||||
* (provided WiFi or BT are enabled). To make sure entropy is not drained
|
||||
* faster than it is added, this function needs to wait for at least 16 APB
|
||||
* clock cycles after reading previous word. This implementation may actually
|
||||
* wait a bit longer due to extra time spent in arithmetic and branch statements.
|
||||
*
|
||||
* As a (probably unncessary) precaution to avoid returning the
|
||||
* RNG state as-is, the result is XORed with additional
|
||||
* WDEV_RND_REG reads while waiting.
|
||||
*/
|
||||
|
||||
/* This code does not run in a critical section, so CPU frequency switch may
|
||||
* happens while this code runs (this will not happen in the current
|
||||
* implementation, but possible in the future). However if that happens,
|
||||
* the number of cycles spent on frequency switching will certainly be more
|
||||
* than the number of cycles we need to wait here.
|
||||
*/
|
||||
uint32_t cpu_to_apb_freq_ratio = esp_clk_cpu_freq() / esp_clk_apb_freq();
|
||||
|
||||
static uint32_t last_ccount = 0;
|
||||
uint32_t ccount;
|
||||
uint32_t result = 0;
|
||||
do {
|
||||
ccount = cpu_hal_get_cycle_count();
|
||||
result ^= REG_READ(WDEV_RND_REG);
|
||||
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16);
|
||||
last_ccount = ccount;
|
||||
return result ^ REG_READ(WDEV_RND_REG);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ endif()
|
||||
|
||||
set(srcs "compare_set.c" "cpu_util.c")
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "clk_ctrl_os.c" "mac_addr.c")
|
||||
list(APPEND srcs "clk_ctrl_os.c" "mac_addr.c" "hw_random.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
|
@@ -19,9 +19,18 @@
|
||||
#include <sys/param.h>
|
||||
#include "esp_attr.h"
|
||||
#include "hal/cpu_hal.h"
|
||||
#include "esp32s2/clk.h"
|
||||
#include "soc/wdev_reg.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/clk.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/clk.h"
|
||||
#endif
|
||||
|
||||
uint32_t IRAM_ATTR esp_random(void)
|
||||
{
|
||||
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
|
Reference in New Issue
Block a user