From 204da36c54de9c24b52c06ad35e7afb78f842cfc Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Mon, 9 Sep 2024 13:10:24 +0200 Subject: [PATCH] sdfw_services: Fix cache handling in SUIT service Fix cache handling in SUIT SSF services. Ref: NCSDK-28992 Signed-off-by: Tomasz Chyrowicz --- .../services/suit_service/suit_auth.c | 22 ++++++++++++++++++- .../services/suit_service/suit_update.c | 4 ++++ .../src/suit_ipc_streamer_requestor.c | 11 +++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/subsys/sdfw_services/services/suit_service/suit_auth.c b/subsys/sdfw_services/services/suit_service/suit_auth.c index 9ebf79ebd66..eda8ab2ef47 100644 --- a/subsys/sdfw_services/services/suit_service/suit_auth.c +++ b/subsys/sdfw_services/services/suit_service/suit_auth.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "suit_service_types.h" @@ -15,6 +16,12 @@ #include LOG_MODULE_REGISTER(suit_srvc_auth, CONFIG_SSF_SUIT_SERVICE_LOG_LEVEL); +#ifdef CONFIG_DCACHE_LINE_SIZE +#define CACHE_ALIGNMENT CONFIG_DCACHE_LINE_SIZE +#else +#define CACHE_ALIGNMENT 4 +#endif + extern const struct ssf_client_srvc suit_srvc; int suit_plat_authenticate_manifest(struct zcbor_string *manifest_component_id, @@ -25,6 +32,8 @@ int suit_plat_authenticate_manifest(struct zcbor_string *manifest_component_id, struct suit_req req; struct suit_rsp rsp; struct suit_authenticate_manifest_req *req_data; + uint8_t aligned_auth_data[ROUND_UP(SUIT_SUIT_SIG_STRUCTURE1_MAX_LENGTH, + CACHE_ALIGNMENT)] __ALIGNED(CACHE_ALIGNMENT) = {0}; if (manifest_component_id == NULL || key_id == NULL || signature == NULL || data == NULL) { return SUIT_ERR_DECODING; @@ -39,9 +48,20 @@ int suit_plat_authenticate_manifest(struct zcbor_string *manifest_component_id, req_data->SSF_SUIT_REQ_ARG(authenticate_manifest, alg_id) = alg_id; req_data->SSF_SUIT_REQ_ARG(authenticate_manifest, key_id) = *key_id; req_data->SSF_SUIT_REQ_ARG(authenticate_manifest, signature) = *signature; - req_data->SSF_SUIT_REQ_ARG(authenticate_manifest, data_addr) = (uintptr_t)data->value; + + memcpy(aligned_auth_data, data->value, data->len); + req_data->SSF_SUIT_REQ_ARG(authenticate_manifest, data_addr) = (uintptr_t)aligned_auth_data; req_data->SSF_SUIT_REQ_ARG(authenticate_manifest, data_size) = data->len; + ret = sys_cache_data_flush_range((void *)aligned_auth_data, sizeof(aligned_auth_data)); + /* + * EAGAIN means that the cache is not enabled. + * ENOTSUP means there is no cache in the system. + */ + if (ret != 0 && ret != -EAGAIN && ret != -ENOTSUP) { + return SUIT_ERR_CRASH; + } + ret = ssf_client_send_request(&suit_srvc, &req, &rsp, NULL); if (ret != 0) { return SUIT_ERR_CRASH; diff --git a/subsys/sdfw_services/services/suit_service/suit_update.c b/subsys/sdfw_services/services/suit_service/suit_update.c index fdb7fb1624e..704d3e6fca6 100644 --- a/subsys/sdfw_services/services/suit_service/suit_update.c +++ b/subsys/sdfw_services/services/suit_service/suit_update.c @@ -159,6 +159,8 @@ suit_ssf_err_t suit_get_installed_manifest_info(suit_manifest_class_id_t *manife *seq_num = rsp_data->SSF_SUIT_RSP_ARG(get_installed_manifest_info, seq_num); if (version != NULL) { + memset(version, 0, sizeof(*version)); + if (rsp_data->SSF_SUIT_RSP_ARG(get_installed_manifest_info, semver_int_count) > ARRAY_SIZE(version->raw)) { ssf_client_decode_done(rsp_pkt); @@ -242,6 +244,8 @@ suit_ssf_err_t suit_get_install_candidate_info(suit_manifest_class_id_t *manifes } if (version != NULL) { + memset(version, 0, sizeof(*version)); + if (rsp_data->SSF_SUIT_RSP_ARG(get_install_candidate_info, semver_int_count) > ARRAY_SIZE(version->raw)) { ssf_client_decode_done(rsp_pkt); diff --git a/subsys/suit/stream/stream_sources/src/suit_ipc_streamer_requestor.c b/subsys/suit/stream/stream_sources/src/suit_ipc_streamer_requestor.c index 1496f46ae0d..c12e72505f9 100644 --- a/subsys/suit/stream/stream_sources/src/suit_ipc_streamer_requestor.c +++ b/subsys/suit/stream/stream_sources/src/suit_ipc_streamer_requestor.c @@ -477,7 +477,16 @@ suit_plat_err_t suit_ipc_streamer_chunk_enqueue(uint32_t stream_session_id, uint err = SUIT_PLAT_ERR_INVAL; } - int result = sys_cache_data_flush_range(address, aligned_size); + /* + * It is assumed that even if the data length is not aligned to the cache + * lines, the client side allocates a bigger, aligned buffer and passes a + * pointer to it's beginning with size set to the part used. + * That way it is safe to invalidate the whole range, as it matches with + * the allocated buffer size. + * + * See: suit_ipc_streamer_provider.c, buffer_info_t type definition. + */ + int result = sys_cache_data_invd_range(address, aligned_size); /* * EAGAIN means that the cache is not enabled.