library_manager: auth: Add library authentication mechanizm

This patch adds usage of authentication API to check
library signature. If feature enabled it will block loading of
library without valid signature.

Signed-off-by: Jaroslaw Stelter <Jaroslaw.Stelter@intel.com>
This commit is contained in:
Jaroslaw Stelter 2024-01-12 13:46:30 +01:00 committed by Liam Girdwood
parent 1819200cb8
commit f9fda66821
3 changed files with 119 additions and 2 deletions

View File

@ -64,6 +64,9 @@
#include <stdint.h> #include <stdint.h>
#include <rimage/sof/user/manifest.h> #include <rimage/sof/user/manifest.h>
#if CONFIG_LIBRARY_AUTH_SUPPORT
#include <sof/auth_api_iface.h>
#endif
#define LIB_MANAGER_MAX_LIBS 16 #define LIB_MANAGER_MAX_LIBS 16
#define LIB_MANAGER_LIB_ID_SHIFT 12 #define LIB_MANAGER_LIB_ID_SHIFT 12
@ -88,6 +91,10 @@ struct ext_library {
uint32_t lib_notif_count; uint32_t lib_notif_count;
void *runtime_data; void *runtime_data;
#if CONFIG_LIBRARY_AUTH_SUPPORT
struct auth_api_ctx auth_ctx;
void *auth_buffer;
#endif
}; };
/* lib manager context, used by lib_notification */ /* lib manager context, used by lib_notification */

View File

@ -14,7 +14,6 @@ config LIBRARY_MANAGER
could be used if enabled. could be used if enabled.
If unsure say N. If unsure say N.
config LIBCODE_MODULE_SUPPORT config LIBCODE_MODULE_SUPPORT
bool "Add support for libcode modules" bool "Add support for libcode modules"
default n default n
@ -24,6 +23,14 @@ config LIBCODE_MODULE_SUPPORT
as lib_code. This modules contains code shared by as lib_code. This modules contains code shared by
a multiple modules. This option adds support for modules a multiple modules. This option adds support for modules
of this type. of this type.
config LIBRARY_AUTH_SUPPORT
bool "Library Authentication Support"
default n
help
This is support for dynamic modules authentication.
Externally developed modules both for SOF and Zephyr
could be used if enabled.
If unsure say N. If unsure say N.
endmenu endmenu

View File

@ -25,6 +25,10 @@
#include <zephyr/cache.h> #include <zephyr/cache.h>
#include <zephyr/drivers/mm/system_mm.h> #include <zephyr/drivers/mm/system_mm.h>
#if CONFIG_LIBRARY_AUTH_SUPPORT
#include <auth/intel_auth_api.h>
#endif
#include <errno.h> #include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
@ -47,6 +51,74 @@ struct lib_manager_dma_ext {
static struct ext_library loader_ext_lib; static struct ext_library loader_ext_lib;
#if CONFIG_LIBRARY_AUTH_SUPPORT
static int lib_manager_auth_init(void)
{
struct ext_library *ext_lib = ext_lib_get();
int ret;
if (auth_api_version().major != AUTH_API_VERSION_MAJOR)
return -EINVAL;
ext_lib->auth_buffer = rballoc_align(0, SOF_MEM_CAPS_RAM,
AUTH_SCRATCH_BUFF_SZ, CONFIG_MM_DRV_PAGE_SIZE);
if (!ext_lib->auth_buffer)
return -ENOMEM;
ret = auth_api_init(&ext_lib->auth_ctx, ext_lib->auth_buffer,
AUTH_SCRATCH_BUFF_SZ, IMG_TYPE_LIB);
if (ret != 0) {
tr_err(&lib_manager_tr, "lib_manager_auth_init() failed with error: %d", ret);
rfree(ext_lib->auth_buffer);
ret = -EACCES;
}
return ret;
}
static void lib_manager_auth_deinit(void)
{
struct ext_library *ext_lib = ext_lib_get();
if (ext_lib->auth_buffer)
memset(ext_lib->auth_buffer, 0, AUTH_SCRATCH_BUFF_SZ);
rfree(ext_lib->auth_buffer);
ext_lib->auth_buffer = NULL;
memset(&ext_lib->auth_ctx, 0, sizeof(struct auth_api_ctx));
}
static int lib_manager_auth_proc(const void *buffer_data,
size_t buffer_size, enum auth_phase phase)
{
struct ext_library *ext_lib = ext_lib_get();
int ret;
ret = auth_api_init_auth_proc(&ext_lib->auth_ctx, buffer_data, buffer_size, phase);
if (ret != 0) {
tr_err(&lib_manager_tr, "lib_manager_auth_proc() failed with error: %d", ret);
return -ENOTSUP;
}
/* The auth_api_busy() will timeouts internally in case of failure */
while (auth_api_busy(&ext_lib->auth_ctx))
;
ret = auth_api_result(&ext_lib->auth_ctx);
if (ret != AUTH_IMAGE_TRUSTED) {
tr_err(&lib_manager_tr, "lib_manager_auth_proc() Untrasted library!");
return -EACCES;
}
if (phase == AUTH_PHASE_LAST)
auth_api_cleanup(&ext_lib->auth_ctx);
return 0;
}
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */
#if IS_ENABLED(CONFIG_MM_DRV) #if IS_ENABLED(CONFIG_MM_DRV)
#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE #define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
@ -623,6 +695,16 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext,
tr_dbg(&lib_manager_tr, "lib_manager_store_library(): pointer: %p", tr_dbg(&lib_manager_tr, "lib_manager_store_library(): pointer: %p",
(__sparse_force void *)library_base_address); (__sparse_force void *)library_base_address);
#if CONFIG_LIBRARY_AUTH_SUPPORT
/* AUTH_PHASE_FIRST - checks library manifest only. */
ret = lib_manager_auth_proc((__sparse_force void *)man_buffer,
MAN_MAX_SIZE_V1_8, AUTH_PHASE_FIRST);
if (ret < 0) {
rfree((__sparse_force void *)library_base_address);
return ret;
}
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */
/* Copy data from temp_mft_buf to destination memory (pointed by library_base_address) */ /* Copy data from temp_mft_buf to destination memory (pointed by library_base_address) */
memcpy_s((__sparse_force void *)library_base_address, MAN_MAX_SIZE_V1_8, memcpy_s((__sparse_force void *)library_base_address, MAN_MAX_SIZE_V1_8,
(__sparse_force void *)man_buffer, MAN_MAX_SIZE_V1_8); (__sparse_force void *)man_buffer, MAN_MAX_SIZE_V1_8);
@ -635,6 +717,16 @@ static int lib_manager_store_library(struct lib_manager_dma_ext *dma_ext,
return ret; return ret;
} }
#if CONFIG_LIBRARY_AUTH_SUPPORT
/* AUTH_PHASE_LAST - do final library authentication checks */
ret = lib_manager_auth_proc((__sparse_force void *)library_base_address,
preload_size - MAN_MAX_SIZE_V1_8, AUTH_PHASE_LAST);
if (ret < 0) {
rfree((__sparse_force void *)library_base_address);
return ret;
}
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */
/* Now update sof context with new library */ /* Now update sof context with new library */
lib_manager_update_sof_ctx((__sparse_force void *)library_base_address, lib_id); lib_manager_update_sof_ctx((__sparse_force void *)library_base_address, lib_id);
@ -744,7 +836,7 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type)
/* allocate temporary manifest buffer */ /* allocate temporary manifest buffer */
man_tmp_buffer = (__sparse_force void __sparse_cache *) man_tmp_buffer = (__sparse_force void __sparse_cache *)
rballoc_align(0, SOF_MEM_CAPS_DMA, rballoc_align(0, SOF_MEM_CAPS_DMA,
MAN_MAX_SIZE_V1_8, dma_ext->addr_align); MAN_MAX_SIZE_V1_8, CONFIG_MM_DRV_PAGE_SIZE);
if (!man_tmp_buffer) { if (!man_tmp_buffer) {
ret = -ENOMEM; ret = -ENOMEM;
goto cleanup; goto cleanup;
@ -755,8 +847,19 @@ int lib_manager_load_library(uint32_t dma_id, uint32_t lib_id, uint32_t type)
if (ret < 0) if (ret < 0)
goto stop_dma; goto stop_dma;
#if CONFIG_LIBRARY_AUTH_SUPPORT
/* Initialize authentication support */
ret = lib_manager_auth_init();
if (ret < 0)
goto stop_dma;
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */
ret = lib_manager_store_library(dma_ext, man_tmp_buffer, lib_id); ret = lib_manager_store_library(dma_ext, man_tmp_buffer, lib_id);
#if CONFIG_LIBRARY_AUTH_SUPPORT
lib_manager_auth_deinit();
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */
stop_dma: stop_dma:
ret2 = dma_stop(dma_ext->chan->dma->z_dev, dma_ext->chan->index); ret2 = dma_stop(dma_ext->chan->dma->z_dev, dma_ext->chan->index);
if (ret2 < 0) { if (ret2 < 0) {