Skip to content

Commit

Permalink
suit: Decryption KEY ID validation
Browse files Browse the repository at this point in the history
This commit adds validation of the key ID used for
decryption - it is checked if the given manifest should
be allowed to use the given key.

Signed-off-by: Artur Hadasz <[email protected]>
  • Loading branch information
ahasztag authored and jukkar committed Dec 13, 2024
1 parent b685e78 commit b8a8b74
Show file tree
Hide file tree
Showing 14 changed files with 299 additions and 21 deletions.
16 changes: 16 additions & 0 deletions subsys/suit/mci/include/suit_mci.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,22 @@ mci_err_t suit_mci_signing_key_id_validate(const suit_manifest_class_id_t *class
mci_err_t suit_mci_signing_key_id_get(const suit_manifest_class_id_t *class_id, uint32_t *key_id);
#endif /* CONFIG_ZTEST */

/**
* @brief Verifying whether specific key_id is valid for decrypting firmware orchestrated
* by a manifest of a specific class
*
* @param[in] class_id Manifest class id
* @param[in] key_id Identifier of key utilized for firmware decryption.
*
* @retval SUIT_PLAT_SUCCESS on success
* @retval SUIT_PLAT_ERR_INVAL invalid parameter, i.e. null pointer
* @retval MCI_ERR_MANIFESTCLASSID manifest class id unsupported
* @retval MCI_ERR_WRONGKEYID provided key ID is invalid for decryption
* for provided manifest class
*/
mci_err_t suit_mci_fw_encryption_key_id_validate(const suit_manifest_class_id_t *class_id,
uint32_t key_id);

/**
* @brief Verifies if manifest with specific class id is entitled to start (invoke) code on specific
* processor
Expand Down
52 changes: 52 additions & 0 deletions subsys/suit/mci/src/suit_mci_nrf54h20.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
#define MANIFEST_PUBKEY_RADIO_GEN0 0x40032100
#define MANIFEST_PUBKEY_GEN_RANGE 2

#define FWENC_APPLICATION_GEN0 0x40022000
#define FWENC_RADIOCORE_GEN0 0x40032000
#define FWENC_SYSCTRL_GEN0 0x40082000
#define FWENC_GEN_RANGE 1

LOG_MODULE_REGISTER(suit_mci_nrf54h20, CONFIG_SUIT_LOG_LEVEL);

mci_err_t suit_mci_supported_manifest_class_ids_get(suit_manifest_class_info_t *class_info,
Expand Down Expand Up @@ -311,6 +316,53 @@ mci_err_t suit_mci_signing_key_id_validate(const suit_manifest_class_id_t *class
return MCI_ERR_WRONGKEYID;
}

mci_err_t suit_mci_fw_encryption_key_id_validate(const suit_manifest_class_id_t *class_id,
uint32_t key_id)
{
suit_manifest_role_t role = SUIT_MANIFEST_UNKNOWN;

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

if (suit_storage_mpi_role_get(class_id, &role) != SUIT_PLAT_SUCCESS) {
return MCI_ERR_MANIFESTCLASSID;
}

switch (role) {
case SUIT_MANIFEST_SEC_SYSCTRL:
if (key_id >= FWENC_SYSCTRL_GEN0 &&
key_id <= FWENC_SYSCTRL_GEN0 + FWENC_GEN_RANGE) {
return SUIT_PLAT_SUCCESS;
}
break;

case SUIT_MANIFEST_APP_RECOVERY:
case SUIT_MANIFEST_APP_LOCAL_1:
case SUIT_MANIFEST_APP_LOCAL_2:
case SUIT_MANIFEST_APP_LOCAL_3:
if (key_id >= FWENC_APPLICATION_GEN0 &&
key_id <= FWENC_APPLICATION_GEN0 + FWENC_GEN_RANGE) {
return SUIT_PLAT_SUCCESS;
}
break;

case SUIT_MANIFEST_RAD_RECOVERY:
case SUIT_MANIFEST_RAD_LOCAL_1:
case SUIT_MANIFEST_RAD_LOCAL_2:
if (key_id >= FWENC_RADIOCORE_GEN0 &&
key_id <= FWENC_RADIOCORE_GEN0 + FWENC_GEN_RANGE) {
return SUIT_PLAT_SUCCESS;
}
break;

default:
break;
}

return MCI_ERR_WRONGKEYID;
}

mci_err_t suit_mci_processor_start_rights_validate(const suit_manifest_class_id_t *class_id,
int processor_id)
{
Expand Down
22 changes: 18 additions & 4 deletions subsys/suit/platform/sdfw/src/suit_plat_copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ int suit_plat_check_copy(suit_component_t dst_handle, suit_component_t src_handl
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
(void)manifest_component_id;

/*
* Validate streaming operation.
Expand Down Expand Up @@ -97,7 +96,15 @@ int suit_plat_check_copy(suit_component_t dst_handle, suit_component_t src_handl
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down Expand Up @@ -154,7 +161,6 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle,
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
(void)manifest_component_id;

/*
* Validate streaming operation.
Expand Down Expand Up @@ -225,7 +231,15 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle,
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down
22 changes: 18 additions & 4 deletions subsys/suit/platform/sdfw/src/suit_plat_write.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ int suit_plat_check_write(suit_component_t dst_handle, struct zcbor_string *cont
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
(void)manifest_component_id;

/*
* Validate streaming operation.
Expand Down Expand Up @@ -79,7 +78,15 @@ int suit_plat_check_write(suit_component_t dst_handle, struct zcbor_string *cont
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down Expand Up @@ -112,7 +119,6 @@ int suit_plat_write(suit_component_t dst_handle, struct zcbor_string *content,
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
(void)manifest_component_id;

/*
* Validate streaming operation.
Expand Down Expand Up @@ -154,7 +160,15 @@ int suit_plat_write(suit_component_t dst_handle, struct zcbor_string *content,
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down
49 changes: 45 additions & 4 deletions subsys/suit/platform/src/suit_plat_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ int suit_plat_check_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
struct stream_sink dst_sink = {0};
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
(void)manifest_component_id;
#endif

/*
* Validate streaming operation.
Expand All @@ -118,7 +120,15 @@ int suit_plat_check_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down Expand Up @@ -151,7 +161,9 @@ int suit_plat_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
(void)manifest_component_id;
#endif

/*
* Validate streaming operation.
Expand All @@ -170,7 +182,15 @@ int suit_plat_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down Expand Up @@ -234,7 +254,9 @@ int suit_plat_check_fetch_integrated(suit_component_t dst_handle, struct zcbor_s
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
(void)manifest_component_id;
#endif

/*
* Validate streaming operation.
Expand Down Expand Up @@ -270,7 +292,15 @@ int suit_plat_check_fetch_integrated(suit_component_t dst_handle, struct zcbor_s
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down Expand Up @@ -303,7 +333,10 @@ int suit_plat_fetch_integrated(suit_component_t dst_handle, struct zcbor_string
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
int ret = SUIT_SUCCESS;
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
(void)manifest_component_id;
#endif


/*
* Validate streaming operation.
Expand Down Expand Up @@ -339,7 +372,15 @@ int suit_plat_fetch_integrated(suit_component_t dst_handle, struct zcbor_string
/* Append decryption filter if encryption info is provided. */
if (enc_info != NULL) {
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
suit_manifest_class_id_t *class_id = NULL;

if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
SUIT_PLAT_SUCCESS) {
LOG_ERR("Component ID is not a manifest class");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Selecting decryption filter failed: %i", ret);
}
Expand Down
1 change: 1 addition & 0 deletions subsys/suit/stream/stream_filters/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ zephyr_library_sources_ifdef(CONFIG_SUIT_AES_KW_MANUAL src/suit_aes_key_unwrap_m

zephyr_library_link_libraries(suit_stream_filters_interface)
zephyr_library_link_libraries(suit_utils)
zephyr_library_link_libraries(suit_mci)
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <suit_sink.h>
#include <suit_types.h>
#include <suit_metadata.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -18,13 +19,15 @@ extern "C" {
* @brief Get decrypt filter object
*
* @param[out] dec_sink Pointer to destination sink_stream to pass decrypted data
* @param[in] end_info Pointer to the structure with encryption info.
* @param[in] enc_info Pointer to the structure with encryption info.
* @param[in] class_id Pointer to the manifest class ID of the destination component
* @param[in] enc_sink Pointer to source sink_stream to be filled with encrypted data
*
* @return SUIT_PLAT_SUCCESS if success otherwise error code
*/
suit_plat_err_t suit_decrypt_filter_get(struct stream_sink *dec_sink,
struct suit_encryption_info *enc_info,
const suit_manifest_class_id_t *class_id,
struct stream_sink *enc_sink);

#ifdef __cplusplus
Expand Down
Loading

0 comments on commit b8a8b74

Please sign in to comment.