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 <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_LIB_ID_SHIFT 12
@ -88,6 +91,10 @@ struct ext_library {
uint32_t lib_notif_count;
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 */

View File

@ -14,7 +14,6 @@ config LIBRARY_MANAGER
could be used if enabled.
If unsure say N.
config LIBCODE_MODULE_SUPPORT
bool "Add support for libcode modules"
default n
@ -24,6 +23,14 @@ config LIBCODE_MODULE_SUPPORT
as lib_code. This modules contains code shared by
a multiple modules. This option adds support for modules
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.
endmenu

View File

@ -25,6 +25,10 @@
#include <zephyr/cache.h>
#include <zephyr/drivers/mm/system_mm.h>
#if CONFIG_LIBRARY_AUTH_SUPPORT
#include <auth/intel_auth_api.h>
#endif
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
@ -47,6 +51,74 @@ struct lib_manager_dma_ext {
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)
#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",
(__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) */
memcpy_s((__sparse_force void *)library_base_address, 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;
}
#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 */
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 */
man_tmp_buffer = (__sparse_force void __sparse_cache *)
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) {
ret = -ENOMEM;
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)
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);
#if CONFIG_LIBRARY_AUTH_SUPPORT
lib_manager_auth_deinit();
#endif /* CONFIG_LIBRARY_AUTH_SUPPORT */
stop_dma:
ret2 = dma_stop(dma_ext->chan->dma->z_dev, dma_ext->chan->index);
if (ret2 < 0) {