Add Authenticated HTTPS Admin Foundation

This commit is contained in:
2026-08-23 17:37:49 +02:00
parent 0dcc0d20d4
commit 8b5417881c
15 changed files with 2233 additions and 89 deletions
+4 -75
View File
@@ -3,18 +3,13 @@
#include "wifi_config.h"
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include "bootloader_random.h"
#include "esp_mac.h"
#include "esp_random.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "mbedtls/ctr_drbg.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "secure_random.h"
_Static_assert(sizeof(wifi_config_sta_profile_t) == WIFI_CONFIG_STA_PROFILE_BLOB_SIZE,
"Wi-Fi STA profile schema size changed");
@@ -23,67 +18,7 @@ _Static_assert(offsetof(wifi_app_config_t, profiles) == 112U,
_Static_assert(sizeof(wifi_app_config_t) == WIFI_CONFIG_BLOB_SIZE,
"Wi-Fi config schema size changed");
static SemaphoreHandle_t s_drbg_mutex;
static mbedtls_ctr_drbg_context s_drbg;
static bool s_drbg_ready;
static int early_entropy_source(void *context, unsigned char *output, size_t length)
{
(void)context;
/* This callback is used only during the explicit pre-radio initialization. */
bootloader_random_enable();
esp_fill_random(output, length);
bootloader_random_disable();
return 0;
}
esp_err_t wifi_config_entropy_init(void)
{
static const unsigned char personalization[] = "esp32-serial-sak-wifi";
if (s_drbg_ready) {
return ESP_OK;
}
if (s_drbg_mutex == NULL) {
s_drbg_mutex = xSemaphoreCreateMutex();
if (s_drbg_mutex == NULL) {
return ESP_ERR_NO_MEM;
}
}
xSemaphoreTake(s_drbg_mutex, portMAX_DELAY);
esp_err_t error = ESP_OK;
if (!s_drbg_ready) {
mbedtls_ctr_drbg_init(&s_drbg);
int result = mbedtls_ctr_drbg_seed(&s_drbg,
early_entropy_source,
NULL,
personalization,
sizeof(personalization) - 1U);
if (result == 0) {
/* Credential generation is rare; never invoke early entropy after RF starts. */
mbedtls_ctr_drbg_set_reseed_interval(&s_drbg, INT_MAX);
s_drbg_ready = true;
} else {
mbedtls_ctr_drbg_free(&s_drbg);
error = ESP_FAIL;
}
}
xSemaphoreGive(s_drbg_mutex);
return error;
}
static esp_err_t fill_credential_random(uint8_t *output, size_t length)
{
if (!s_drbg_ready || output == NULL) {
return ESP_ERR_INVALID_STATE;
}
xSemaphoreTake(s_drbg_mutex, portMAX_DELAY);
int result = mbedtls_ctr_drbg_random(&s_drbg, output, length);
xSemaphoreGive(s_drbg_mutex);
return result == 0 ? ESP_OK : ESP_FAIL;
}
static bool bytes_are_zero(const uint8_t *data, size_t size)
{
@@ -130,14 +65,8 @@ static bool security_is_valid(wifi_config_security_t security)
void wifi_config_secure_wipe(void *data, size_t size)
{
volatile uint8_t *byte = (volatile uint8_t *)data;
if (byte == NULL) {
return;
}
while (size-- > 0U) {
*byte++ = 0U;
}
/* Keep the existing Wi-Fi API while using the device-wide wipe primitive. */
secure_wipe(data, size);
}
esp_err_t wifi_config_defaults(wifi_app_config_t *config)
@@ -179,7 +108,7 @@ esp_err_t wifi_config_defaults(wifi_app_config_t *config)
* A 64-character alphabet maps six random bits without modulo bias. The
* password is intentionally independent of the public MAC-derived suffix.
*/
err = fill_credential_random(random_bytes, sizeof(random_bytes));
err = secure_random_fill(random_bytes, sizeof(random_bytes));
if (err != ESP_OK) {
wifi_config_secure_wipe(random_bytes, sizeof(random_bytes));
return err;