Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace15_mtpm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ CONFIG_DMA_DW_LLI_POOL_SIZE=50
CONFIG_DMA_DW_SUSPEND_DRAIN=y
CONFIG_INTEL_MODULES=y
CONFIG_LIBRARY_MANAGER=y
CONFIG_LIBRARY_AUTH_SUPPORT=y
CONFIG_INTEL_ADSP_TIMER=y
CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y
CONFIG_AMS=y
Expand Down
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace20_lnl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ CONFIG_DMA=y
CONFIG_DMA_INTEL_ADSP_GPDMA=n
CONFIG_INTEL_MODULES=y
CONFIG_LIBRARY_MANAGER=y
CONFIG_LIBRARY_AUTH_SUPPORT=y
CONFIG_INTEL_ADSP_TIMER=y
CONFIG_MM_DRV_INTEL_ADSP_TLB_REMAP_UNUSED_RAM=y
CONFIG_AMS=y
Expand Down
149 changes: 149 additions & 0 deletions src/include/sof/auth_api_iface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2022 Intel Corporation. All rights reserved.
*
* Author: Jaroslaw Stelter <jaroslaw.stelter@intel.com>
* Pawel Dobrowolski <pawelx.dobrowolski@intel.com>
*/
#ifndef __AUTH_API_IFACE_H__
#define __AUTH_API_IFACE_H__

#include <auth/intel_status_logger_iface.h>
#include <stdint.h>
#include <stddef.h>

#define AUTH_API_VERSION_MAJOR (2)
#define AUTH_API_VERSION_MINOR (0)
#define AUTH_API_VERSION_PATCH (0)

#define AUTH_SCRATCH_BUFF_SZ (0xA000) // 40kB

/*
* Return codes supported by authentication engine:
* ADSP_AUTH_IMAGE_UNTRUSTED = 9040,
* ADSP_AUTH_CANNOT_ALLOCATE_SCRATCH_BUFF = 9041,
* ADSP_AUTH_INVALID_AUTH_API_CTX_PTR = 9042,
* ADSP_AUTH_SVN_VERIFICATION_FAIL = 9043,
* ADSP_AUTH_IFWI_PARTITION_FAIL = 9044,
* ADSP_AUTH_VERIFY_IMAGE_TYPE_FAIL = 9045,
* ADSP_AUTH_UNSUPPORTED_VERSION = 9046,
* ADSP_AUTH_INCOMPATIBLE_MANIFEST_VERSION = 9047,
*/

struct auth_api_version_num {
uint8_t patch;
uint8_t minor;
uint8_t major;
uint8_t rsvd;
} __packed __aligned(4);

enum auth_phase {
AUTH_PHASE_FIRST = 0,
AUTH_PHASE_MID = 1,
AUTH_PHASE_LAST = 2
};

enum auth_result {
AUTH_NOT_COMPLETED = 0,
AUTH_IMAGE_TRUSTED = 1,
AUTH_IMAGE_UNTRUSTED = 2
};

enum auth_image_type {
IMG_TYPE_ROM_EXT = 0,
IMG_TYPE_MAIN_FW = 1,
IMG_TYPE_LIB = 2
};

struct auth_api_ctx;

struct auth_api_version {
/* Interface to return authentication API version.
* Return value: version number represented by auth_api_version_num structure.
*/
struct auth_api_version_num (*version)();
};

struct auth_api {
/* Interface to initialize authentication API and context.
* Parameters:
* ctx - pointer to the context instance of type auth_api_ctx.
* scratch_buff - pointer to scratch buffer.
* Scratch buffer must be located in L2 Local Memory (SHA Engine limitation).
* Caller is responsible to power up necessary L2 Local Memory banks.
* Address alignment must correspond to SHA384_IO_BUF_ALIGNMENT.
* scratch_buff_size – size must be the same as AUTH_SCRATCH_BUFF_SZ.
* Return value:
* ADSP_SUCCESS - successful initialization.
*/
int (*init)(struct auth_api_ctx *ctx, void *scratch_buff, size_t scratch_buff_size,
enum auth_image_type image_type);

/* Interface to cleanup authentication API.
* Parameters:
* ctx - pointer to the context instance of type AuthApiCtx.
*/
void (*cleanup)(struct auth_api_ctx *ctx);

/* Interface for initiating signed FW image (async) authentication process.
* Parameters:
* ctx - pointer to the context instance of type AuthApiCtx.
* chunk - pointer to the chunk of signed FW image.
* chunk_size - chunk size in bytes.
* phase - authentication phase.
* Must corresponds to one of the AuthPhase values.
* In case of one time FW authentication, where signed FW image size must be
* less or equal to scratch_buff_size, the caller must pass AUTH_PHASE_LAST.
* Return value: ADSP_SUCCESS when authentication process has been initiated
* successfully, or one of ADSP_FLV_* error codes in case of failure.
*/
int (*init_auth_proc)(struct auth_api_ctx *ctx, const void *chunk, size_t chunk_size,
enum auth_phase phase);

/* Interface to return if authentication process is busy.
* Parameters:
* ctx - pointer to the context instance of type AuthApiCtx.
* This function can be used for authentication process synchronization.
* Return value: true if authentication process is busy.
*/
bool (*busy)(struct auth_api_ctx *ctx);

/* Interface to return authentication result
* Parameters:
* ctx - pointer to the context instance of type AuthApiCtx.
* Return value:
* AUTH_NOT_COMPLETED - authentication is not completed,
* AUTH_IMAGE_TRUSTED - authentication completed and signed FW image is
* trusted,
* AUTH_IMAGE_UNTRUSTED - authentication completed, but signed FW image is
* untrusted.
*/
enum auth_result (*result)(struct auth_api_ctx *ctx);

/* Interface to register status/error code logger.
* Parameters:
* ctx - pointer to the context instance of type AuthApiCtx.
* sts_logger - pointer to status logger.
* Return value: ADSP_SUCCESS when logger has been registered successfully.
*/
int (*register_status_logger)(struct auth_api_ctx *ctx,
struct status_logger_ctx *status_logger);

/* Interface to unregister status/error code logger.
* Parameters:
* ctx - pointer to the context instance of type AuthApiCtx.
*/
void (*unregister_status_logger)(struct auth_api_ctx *ctx);
};

struct auth_api_ctx {
struct auth_api_version *version_api;
void *scratch_buff;
size_t scratch_buff_size;
enum auth_result result;
struct auth_api *auth_api;
enum auth_image_type image_type;
struct status_logger_ctx *status_logger;
};

#endif /* __SOF_LIB_MANAGER_H__ */
7 changes: 7 additions & 0 deletions src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 */
Expand Down
9 changes: 8 additions & 1 deletion src/library_manager/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
105 changes: 104 additions & 1 deletion src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

free the scratch buffer

}

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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this also needed in the LAST stage? A bit asymmetric

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how reference code uses this API.


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!");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

untrusted

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jxstelter can we fix the typo in a follow up?

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
Expand Down Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is this related? Can we add a comment in a follow-up? Or, if this wasn't intended, revert this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication engine in ROM_EXT requires page aligned buffer. Otherwise it fails.

if (!man_tmp_buffer) {
ret = -ENOMEM;
goto cleanup;
Expand All @@ -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) {
Expand Down
Loading