Skip to content

Commit

Permalink
ESP32: add support to mbedtls RNG
Browse files Browse the repository at this point in the history
Implement sys_mbedtls function for entropy and random context.

Signed-off-by: Davide Bettio <davide@uninstall.it>
  • Loading branch information
bettio committed Nov 27, 2023
1 parent b8202a3 commit db622ed
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/platforms/esp32/components/avm_sys/include/esp32_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@
#include <spi_flash_mmap.h>
#endif

#include <mbedtls/config.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>

#include <sys/poll.h>
#include <stdbool.h>
#include <time.h>

#include "smp.h"

#include "sys.h"

#define REGISTER_PORT_DRIVER(NAME, INIT_CB, DESTROY_CB, CREATE_CB) \
Expand Down Expand Up @@ -94,6 +101,18 @@ struct ESP32PlatformData
EventListener *socket_listener;
struct SyncList sockets;
struct ListHead ready_connections;

#ifndef AVM_NO_SMP
Mutex *entropy_mutex;
#endif
mbedtls_entropy_context entropy_ctx;
bool entropy_is_initialized;

#ifndef AVM_NO_SMP
Mutex *random_mutex;
#endif
mbedtls_ctr_drbg_context random_ctx;
bool random_is_initialized;
};

typedef void (*port_driver_init_t)(GlobalContext *global);
Expand Down
87 changes: 87 additions & 0 deletions src/platforms/esp32/components/avm_sys/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@

#define TAG "sys"

#ifndef AVM_NO_SMP
#define SMP_MUTEX_LOCK(mtx) smp_mutex_lock(mtx)
#define SMP_MUTEX_UNLOCK(mtx) smp_mutex_unlock(mtx)
#else
#define SMP_MUTEX_LOCK(mtx)
#define SMP_MUTEX_UNLOCK(mtx)
#endif

static Context *port_driver_create_port(const char *port_name, GlobalContext *global, term opts);

static void *select_thread_loop(void *);
Expand Down Expand Up @@ -232,6 +240,9 @@ void sys_init_platform(GlobalContext *glb)
AVM_ABORT();
}
#endif

platform->entropy_is_initialized = false;
platform->random_is_initialized = false;
}

void sys_free_platform(GlobalContext *glb)
Expand All @@ -247,6 +258,15 @@ void sys_free_platform(GlobalContext *glb)
AVM_ABORT();
}
}

if (platform->random_is_initialized) {
mbedtls_ctr_drbg_free(&platform->random_ctx);
}

if (platform->entropy_is_initialized) {
mbedtls_entropy_free(&platform->entropy_ctx);
}

free(platform);
}

Expand Down Expand Up @@ -750,3 +770,70 @@ term esp_err_to_term(GlobalContext *glb, esp_err_t status)
return term_from_int(status);
}
}

int sys_mbedtls_entropy_func(void *entropy, unsigned char *buf, size_t size)
{
#ifndef MBEDTLS_THREADING_C
struct ESP32PlatformData *platform
= CONTAINER_OF(entropy, struct ESP32PlatformData, entropy_ctx);
SMP_MUTEX_LOCK(platform->entropy_mutex);
int result = mbedtls_entropy_func(entropy, buf, size);
SMP_MUTEX_UNLOCK(platform->entropy_mutex);

return result;
#else
return mbedtls_entropy_func(entropy, buf, size);
#endif
}

mbedtls_entropy_context *sys_mbedtls_get_entropy_context_lock(GlobalContext *global)
{
struct ESP32PlatformData *platform = global->platform_data;

SMP_MUTEX_LOCK(platform->entropy_mutex);

if (!platform->entropy_is_initialized) {
mbedtls_entropy_init(&platform->entropy_ctx);
platform->entropy_is_initialized = true;
}

return &platform->entropy_ctx;
}

void sys_mbedtls_entropy_context_unlock(GlobalContext *global)
{
struct ESP32PlatformData *platform = global->platform_data;
SMP_MUTEX_UNLOCK(platform->entropy_mutex);
}

mbedtls_ctr_drbg_context *sys_mbedtls_get_ctr_drbg_context_lock(GlobalContext *global)
{
struct ESP32PlatformData *platform = global->platform_data;

SMP_MUTEX_LOCK(platform->random_mutex);

if (!platform->random_is_initialized) {
mbedtls_ctr_drbg_init(&platform->random_ctx);

mbedtls_entropy_context *entropy_ctx = sys_mbedtls_get_entropy_context_lock(global);
// Safe to unlock it now, sys_mbedtls_entropy_func will lock it again later
sys_mbedtls_entropy_context_unlock(global);

const char *seed = "AtomVM ESP32 Mbed-TLS initial seed.";
int seed_len = strlen(seed);
int seed_err = mbedtls_ctr_drbg_seed(&platform->random_ctx, sys_mbedtls_entropy_func,
entropy_ctx, (const unsigned char *) seed, seed_len);
if (UNLIKELY(seed_err != 0)) {
abort();
}
platform->random_is_initialized = true;
}

return &platform->random_ctx;
}

void sys_mbedtls_ctr_drbg_context_unlock(GlobalContext *global)
{
struct ESP32PlatformData *platform = global->platform_data;
SMP_MUTEX_UNLOCK(platform->random_mutex);
}

0 comments on commit db622ed

Please sign in to comment.