-
Notifications
You must be signed in to change notification settings - Fork 349
Add library authentication feature for MTL and LNL #8741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fba1f17
64a132a
abb49d5
55a520a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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__ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this also needed in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)) | ||
| ; | ||
jxstelter marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ret = auth_api_result(&ext_lib->auth_ctx); | ||
|
|
||
| if (ret != AUTH_IMAGE_TRUSTED) { | ||
| tr_err(&lib_manager_tr, "lib_manager_auth_proc() Untrasted library!"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. untrusted
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
|
@@ -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); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
|
|
@@ -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) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
free the scratch buffer