Skip to content

Commit

Permalink
suit: in-place updateable components
Browse files Browse the repository at this point in the history
Extension of SUIT in-place updateable component module.
Support for an access to IPUC from IPC client added.

Ref: NCSDK-30808

Signed-off-by: Sylwester Konczyk <[email protected]>
  • Loading branch information
SylwesterKonczyk committed Jan 13, 2025
1 parent 509fa66 commit 71c6335
Show file tree
Hide file tree
Showing 40 changed files with 2,219 additions and 876 deletions.
2 changes: 2 additions & 0 deletions subsys/sdfw_services/services/suit_service/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ zephyr_library_sources(suit_mci.c)
zephyr_library_sources(suit_invoke.c)
zephyr_library_sources_ifdef(CONFIG_SUIT_PROCESSOR suit_auth.c)
zephyr_library_sources_ifdef(CONFIG_SUIT_MANIFEST_VARIABLES suit_mfst_var.c)
zephyr_library_sources_ifdef(CONFIG_SUIT_IPUC suit_ipuc.c)

zephyr_library_link_libraries(suit_utils)
zephyr_library_link_libraries_ifdef(CONFIG_SUIT_MANIFEST_VARIABLES suit_manifest_variables)
zephyr_library_link_libraries_ifdef(CONFIG_SUIT_IPUC suit_ipuc)

if(CONFIG_SUIT_STREAM_SOURCE_IPC)
zephyr_library_link_libraries(suit_stream_sources_interface)
Expand Down
195 changes: 195 additions & 0 deletions subsys/sdfw_services/services/suit_service/suit_ipuc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <suit_plat_err.h>
#include <suit_plat_decode_util.h>
#include <suit_ipuc.h>
#include <stdint.h>
#include <sdfw/sdfw_services/suit_service.h>
#include <sdfw/sdfw_services/ssf_client.h>
#include "suit_service_decode.h"
#include "suit_service_encode.h"
#include "suit_service_types.h"
#include "suit_service_utils.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(suit_ipuc, CONFIG_SSF_SUIT_SERVICE_LOG_LEVEL);

extern const struct ssf_client_srvc suit_srvc;

suit_plat_err_t suit_ipuc_get_count(size_t *count)
{
int err;
struct suit_req req = {0};
struct suit_rsp rsp = {0};
struct suit_get_ipuc_count_rsp *rsp_data = NULL;
const uint8_t *rsp_pkt = NULL;

if (count == NULL) {
return SUIT_PLAT_ERR_INVAL;
}

req.suit_req_msg_choice = SSF_SUIT_REQ_CHOICE(get_ipuc_count);
err = ssf_client_send_request(&suit_srvc, &req, &rsp, &rsp_pkt);
if (err != 0) {
LOG_ERR("ssf_client_send_request failed");
return SUIT_PLAT_ERR_IPC;
}

rsp_data = &rsp.SSF_SUIT_RSP(get_ipuc_count);
err = rsp_data->SSF_SUIT_RSP_ARG(get_ipuc_count, ret);
if (err != SUIT_PLAT_SUCCESS) {
ssf_client_decode_done(rsp_pkt);
LOG_ERR("ssf_client response return code: %d", err);
return err;
}

*count = rsp_data->SSF_SUIT_RSP_ARG(get_ipuc_count, count);

ssf_client_decode_done(rsp_pkt);
return err;
}

suit_plat_err_t suit_ipuc_get_info(size_t idx, struct zcbor_string *component_id,
suit_manifest_role_t *role)
{
int err;
struct suit_req req = {0};
struct suit_rsp rsp = {0};
struct suit_get_ipuc_info_req *req_data = NULL;
struct suit_get_ipuc_info_rsp *rsp_data = NULL;
const uint8_t *rsp_pkt = NULL;

if (component_id == NULL || role == NULL) {
return SUIT_PLAT_ERR_INVAL;
}

if (component_id->value == NULL) {
return SUIT_PLAT_ERR_INVAL;
}

req.suit_req_msg_choice = SSF_SUIT_REQ_CHOICE(get_ipuc_info);
req_data = &req.SSF_SUIT_REQ(get_ipuc_info);
req_data->SSF_SUIT_REQ_ARG(get_ipuc_info, idx) = idx;

err = ssf_client_send_request(&suit_srvc, &req, &rsp, &rsp_pkt);
if (err != 0) {
LOG_ERR("ssf_client_send_request failed");
return SUIT_PLAT_ERR_IPC;
}
rsp_data = &rsp.SSF_SUIT_RSP(get_ipuc_info);
err = rsp_data->SSF_SUIT_RSP_ARG(get_ipuc_info, ret);
if (err != SUIT_PLAT_SUCCESS) {
ssf_client_decode_done(rsp_pkt);
LOG_ERR("ssf_client response return code: %d", err);
return err;
}

struct zcbor_string *src_component_id =
&rsp_data->SSF_SUIT_RSP_ARG(get_ipuc_info, component_id);

if (component_id->len < src_component_id->len) {

ssf_client_decode_done(rsp_pkt);
return SUIT_PLAT_ERR_SIZE;
}

memcpy((void *)component_id->value, src_component_id->value, src_component_id->len);
component_id->len = src_component_id->len;
*role = rsp_data->SSF_SUIT_RSP_ARG(get_ipuc_info, role);
ssf_client_decode_done(rsp_pkt);

#if (defined CONFIG_SUIT_LOG_LEVEL_INF || defined CONFIG_SUIT_LOG_LEVEL_DBG)
suit_component_type_t component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;

suit_plat_decode_component_type(component_id, &component_type);

if (component_type == SUIT_COMPONENT_TYPE_MEM) {
uint8_t core_id = 0;
intptr_t run_address = 0;
size_t slot_size = 0;

suit_plat_decode_component_id(component_id, &core_id, &run_address, &slot_size);

LOG_INF("MEM, %08X, %d bytes, core: %d, mfst role: 0x%02X",
(unsigned int)run_address, slot_size, core_id, *role);

} else {
LOG_INF("component_type: %d, mfst role: 0x%02X", component_type, *role);
}
#endif

return err;
}

suit_plat_err_t suit_ipuc_write_setup(struct zcbor_string *component_id,
struct zcbor_string *encryption_info,
struct zcbor_string *compression_info)
{
int err;
struct suit_req req = {0};
struct suit_rsp rsp = {0};
struct suit_setup_write_ipuc_req *req_data = {0};

if (component_id == NULL) {
return SUIT_PLAT_ERR_INVAL;
}

if (encryption_info != NULL || compression_info != NULL) {
/* Encryption and/or Compression are not supported yet
*/
return SUIT_PLAT_ERR_UNSUPPORTED;
}

req.suit_req_msg_choice = SSF_SUIT_REQ_CHOICE(setup_write_ipuc);
req_data = &req.SSF_SUIT_REQ(setup_write_ipuc);

req_data->SSF_SUIT_REQ_ARG(setup_write_ipuc, component_id).value = component_id->value;
req_data->SSF_SUIT_REQ_ARG(setup_write_ipuc, component_id).len = component_id->len;
req_data->SSF_SUIT_REQ_ARG(setup_write_ipuc, encryption_info).value = NULL;
req_data->SSF_SUIT_REQ_ARG(setup_write_ipuc, encryption_info).len = 0;
req_data->SSF_SUIT_REQ_ARG(setup_write_ipuc, compression_info).value = NULL;
req_data->SSF_SUIT_REQ_ARG(setup_write_ipuc, compression_info).len = 0;

err = ssf_client_send_request(&suit_srvc, &req, &rsp, NULL);
if (err != 0) {
LOG_ERR("ssf_client_send_request failed");
return SUIT_PLAT_ERR_IPC;
}

return rsp.SSF_SUIT_RSP(setup_write_ipuc).SSF_SUIT_RSP_ARG(setup_write_ipuc, ret);
}

suit_plat_err_t suit_ipuc_write(struct zcbor_string *component_id, size_t offset, uintptr_t buffer,
size_t chunk_size, bool last_chunk)
{
int err;
struct suit_req req = {0};
struct suit_rsp rsp = {0};
struct suit_write_ipuc_req *req_data = {0};

if (component_id == NULL) {
return SUIT_PLAT_ERR_INVAL;
}

req.suit_req_msg_choice = SSF_SUIT_REQ_CHOICE(write_ipuc);
req_data = &req.SSF_SUIT_REQ(write_ipuc);

req_data->SSF_SUIT_REQ_ARG(write_ipuc, component_id).value = component_id->value;
req_data->SSF_SUIT_REQ_ARG(write_ipuc, component_id).len = component_id->len;
req_data->SSF_SUIT_REQ_ARG(write_ipuc, offset) = offset;
req_data->SSF_SUIT_REQ_ARG(write_ipuc, addr) = buffer;
req_data->SSF_SUIT_REQ_ARG(write_ipuc, size) = chunk_size;
req_data->SSF_SUIT_REQ_ARG(write_ipuc, last_chunk) = last_chunk;

err = ssf_client_send_request(&suit_srvc, &req, &rsp, NULL);
if (err != 0) {
LOG_ERR("ssf_client_send_request failed");
return SUIT_PLAT_ERR_IPC;
}

return rsp.SSF_SUIT_RSP(write_ipuc).SSF_SUIT_RSP_ARG(write_ipuc, ret);
}
58 changes: 58 additions & 0 deletions subsys/sdfw_services/services/suit_service/suit_service.cddl
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,54 @@ suit_authorize_process_dependency_rsp = (
ret: int,
)

; In-place updateable components
suit_get_ipuc_count_req = (
30,
)

suit_get_ipuc_count_rsp = (
30,
ret: int,
count: uint
)

suit_get_ipuc_info_req = (
31,
idx: uint
)

suit_get_ipuc_info_rsp = (
31,
ret: int,
component_id: bstr,
role: int,
)

suit_setup_write_ipuc_req = (
32,
component_id: bstr,
encryption_info: bstr,
compression_info: bstr,
)

suit_setup_write_ipuc_rsp = (
32,
ret: int,
)

suit_write_ipuc_req = (
33,
component_id: bstr,
offset: uint,
last_chunk: bool,
addr: uint,
size: uint,
)

suit_write_ipuc_rsp = (
33,
ret: int,
)

; Missing image event notification message
suit_evt_sub_req = (
Expand Down Expand Up @@ -397,6 +445,11 @@ suit_req = [
suit_get_supported_manifest_info_req /
suit_authorize_process_dependency_req /

suit_get_ipuc_count_req /
suit_get_ipuc_info_req /
suit_setup_write_ipuc_req /
suit_write_ipuc_req /

suit_get_manifest_var_req /
suit_set_manifest_var_req /

Expand Down Expand Up @@ -428,6 +481,11 @@ suit_rsp = [
suit_get_supported_manifest_info_rsp /
suit_authorize_process_dependency_rsp /

suit_get_ipuc_count_rsp /
suit_get_ipuc_info_rsp /
suit_setup_write_ipuc_rsp /
suit_write_ipuc_rsp /

suit_get_manifest_var_rsp /
suit_set_manifest_var_rsp /

Expand Down
Loading

0 comments on commit 71c6335

Please sign in to comment.