Skip to content

Commit b8a8b74

Browse files
ahasztagjukkar
authored andcommitted
suit: Decryption KEY ID validation
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]>
1 parent b685e78 commit b8a8b74

File tree

14 files changed

+299
-21
lines changed

14 files changed

+299
-21
lines changed

subsys/suit/mci/include/suit_mci.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,22 @@ mci_err_t suit_mci_signing_key_id_validate(const suit_manifest_class_id_t *class
179179
mci_err_t suit_mci_signing_key_id_get(const suit_manifest_class_id_t *class_id, uint32_t *key_id);
180180
#endif /* CONFIG_ZTEST */
181181

182+
/**
183+
* @brief Verifying whether specific key_id is valid for decrypting firmware orchestrated
184+
* by a manifest of a specific class
185+
*
186+
* @param[in] class_id Manifest class id
187+
* @param[in] key_id Identifier of key utilized for firmware decryption.
188+
*
189+
* @retval SUIT_PLAT_SUCCESS on success
190+
* @retval SUIT_PLAT_ERR_INVAL invalid parameter, i.e. null pointer
191+
* @retval MCI_ERR_MANIFESTCLASSID manifest class id unsupported
192+
* @retval MCI_ERR_WRONGKEYID provided key ID is invalid for decryption
193+
* for provided manifest class
194+
*/
195+
mci_err_t suit_mci_fw_encryption_key_id_validate(const suit_manifest_class_id_t *class_id,
196+
uint32_t key_id);
197+
182198
/**
183199
* @brief Verifies if manifest with specific class id is entitled to start (invoke) code on specific
184200
* processor

subsys/suit/mci/src/suit_mci_nrf54h20.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
#define MANIFEST_PUBKEY_RADIO_GEN0 0x40032100
2222
#define MANIFEST_PUBKEY_GEN_RANGE 2
2323

24+
#define FWENC_APPLICATION_GEN0 0x40022000
25+
#define FWENC_RADIOCORE_GEN0 0x40032000
26+
#define FWENC_SYSCTRL_GEN0 0x40082000
27+
#define FWENC_GEN_RANGE 1
28+
2429
LOG_MODULE_REGISTER(suit_mci_nrf54h20, CONFIG_SUIT_LOG_LEVEL);
2530

2631
mci_err_t suit_mci_supported_manifest_class_ids_get(suit_manifest_class_info_t *class_info,
@@ -311,6 +316,53 @@ mci_err_t suit_mci_signing_key_id_validate(const suit_manifest_class_id_t *class
311316
return MCI_ERR_WRONGKEYID;
312317
}
313318

319+
mci_err_t suit_mci_fw_encryption_key_id_validate(const suit_manifest_class_id_t *class_id,
320+
uint32_t key_id)
321+
{
322+
suit_manifest_role_t role = SUIT_MANIFEST_UNKNOWN;
323+
324+
if (class_id == NULL) {
325+
return SUIT_PLAT_ERR_INVAL;
326+
}
327+
328+
if (suit_storage_mpi_role_get(class_id, &role) != SUIT_PLAT_SUCCESS) {
329+
return MCI_ERR_MANIFESTCLASSID;
330+
}
331+
332+
switch (role) {
333+
case SUIT_MANIFEST_SEC_SYSCTRL:
334+
if (key_id >= FWENC_SYSCTRL_GEN0 &&
335+
key_id <= FWENC_SYSCTRL_GEN0 + FWENC_GEN_RANGE) {
336+
return SUIT_PLAT_SUCCESS;
337+
}
338+
break;
339+
340+
case SUIT_MANIFEST_APP_RECOVERY:
341+
case SUIT_MANIFEST_APP_LOCAL_1:
342+
case SUIT_MANIFEST_APP_LOCAL_2:
343+
case SUIT_MANIFEST_APP_LOCAL_3:
344+
if (key_id >= FWENC_APPLICATION_GEN0 &&
345+
key_id <= FWENC_APPLICATION_GEN0 + FWENC_GEN_RANGE) {
346+
return SUIT_PLAT_SUCCESS;
347+
}
348+
break;
349+
350+
case SUIT_MANIFEST_RAD_RECOVERY:
351+
case SUIT_MANIFEST_RAD_LOCAL_1:
352+
case SUIT_MANIFEST_RAD_LOCAL_2:
353+
if (key_id >= FWENC_RADIOCORE_GEN0 &&
354+
key_id <= FWENC_RADIOCORE_GEN0 + FWENC_GEN_RANGE) {
355+
return SUIT_PLAT_SUCCESS;
356+
}
357+
break;
358+
359+
default:
360+
break;
361+
}
362+
363+
return MCI_ERR_WRONGKEYID;
364+
}
365+
314366
mci_err_t suit_mci_processor_start_rights_validate(const suit_manifest_class_id_t *class_id,
315367
int processor_id)
316368
{

subsys/suit/platform/sdfw/src/suit_plat_copy.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ int suit_plat_check_copy(suit_component_t dst_handle, suit_component_t src_handl
4949
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
5050
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
5151
int ret = SUIT_SUCCESS;
52-
(void)manifest_component_id;
5352

5453
/*
5554
* Validate streaming operation.
@@ -97,7 +96,15 @@ int suit_plat_check_copy(suit_component_t dst_handle, suit_component_t src_handl
9796
/* Append decryption filter if encryption info is provided. */
9897
if (enc_info != NULL) {
9998
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
100-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
99+
suit_manifest_class_id_t *class_id = NULL;
100+
101+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
102+
SUIT_PLAT_SUCCESS) {
103+
LOG_ERR("Component ID is not a manifest class");
104+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
105+
}
106+
107+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
101108
if (ret != SUIT_PLAT_SUCCESS) {
102109
LOG_ERR("Selecting decryption filter failed: %i", ret);
103110
}
@@ -154,7 +161,6 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle,
154161
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
155162
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
156163
int ret = SUIT_SUCCESS;
157-
(void)manifest_component_id;
158164

159165
/*
160166
* Validate streaming operation.
@@ -225,7 +231,15 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle,
225231
/* Append decryption filter if encryption info is provided. */
226232
if (enc_info != NULL) {
227233
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
228-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
234+
suit_manifest_class_id_t *class_id = NULL;
235+
236+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
237+
SUIT_PLAT_SUCCESS) {
238+
LOG_ERR("Component ID is not a manifest class");
239+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
240+
}
241+
242+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
229243
if (ret != SUIT_PLAT_SUCCESS) {
230244
LOG_ERR("Selecting decryption filter failed: %i", ret);
231245
}

subsys/suit/platform/sdfw/src/suit_plat_write.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ int suit_plat_check_write(suit_component_t dst_handle, struct zcbor_string *cont
4141
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
4242
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
4343
int ret = SUIT_SUCCESS;
44-
(void)manifest_component_id;
4544

4645
/*
4746
* Validate streaming operation.
@@ -79,7 +78,15 @@ int suit_plat_check_write(suit_component_t dst_handle, struct zcbor_string *cont
7978
/* Append decryption filter if encryption info is provided. */
8079
if (enc_info != NULL) {
8180
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
82-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
81+
suit_manifest_class_id_t *class_id = NULL;
82+
83+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
84+
SUIT_PLAT_SUCCESS) {
85+
LOG_ERR("Component ID is not a manifest class");
86+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
87+
}
88+
89+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
8390
if (ret != SUIT_PLAT_SUCCESS) {
8491
LOG_ERR("Selecting decryption filter failed: %i", ret);
8592
}
@@ -112,7 +119,6 @@ int suit_plat_write(suit_component_t dst_handle, struct zcbor_string *content,
112119
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
113120
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
114121
int ret = SUIT_SUCCESS;
115-
(void)manifest_component_id;
116122

117123
/*
118124
* Validate streaming operation.
@@ -154,7 +160,15 @@ int suit_plat_write(suit_component_t dst_handle, struct zcbor_string *content,
154160
/* Append decryption filter if encryption info is provided. */
155161
if (enc_info != NULL) {
156162
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
157-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
163+
suit_manifest_class_id_t *class_id = NULL;
164+
165+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
166+
SUIT_PLAT_SUCCESS) {
167+
LOG_ERR("Component ID is not a manifest class");
168+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
169+
}
170+
171+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
158172
if (ret != SUIT_SUCCESS) {
159173
LOG_ERR("Selecting decryption filter failed: %i", ret);
160174
}

subsys/suit/platform/src/suit_plat_fetch.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ int suit_plat_check_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
100100
struct stream_sink dst_sink = {0};
101101
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
102102
int ret = SUIT_SUCCESS;
103+
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
103104
(void)manifest_component_id;
105+
#endif
104106

105107
/*
106108
* Validate streaming operation.
@@ -118,7 +120,15 @@ int suit_plat_check_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
118120
/* Append decryption filter if encryption info is provided. */
119121
if (enc_info != NULL) {
120122
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
121-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
123+
suit_manifest_class_id_t *class_id = NULL;
124+
125+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
126+
SUIT_PLAT_SUCCESS) {
127+
LOG_ERR("Component ID is not a manifest class");
128+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
129+
}
130+
131+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
122132
if (ret != SUIT_PLAT_SUCCESS) {
123133
LOG_ERR("Selecting decryption filter failed: %i", ret);
124134
}
@@ -151,7 +161,9 @@ int suit_plat_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
151161
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
152162
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
153163
int ret = SUIT_SUCCESS;
164+
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
154165
(void)manifest_component_id;
166+
#endif
155167

156168
/*
157169
* Validate streaming operation.
@@ -170,7 +182,15 @@ int suit_plat_fetch(suit_component_t dst_handle, struct zcbor_string *uri,
170182
/* Append decryption filter if encryption info is provided. */
171183
if (enc_info != NULL) {
172184
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
173-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
185+
suit_manifest_class_id_t *class_id = NULL;
186+
187+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
188+
SUIT_PLAT_SUCCESS) {
189+
LOG_ERR("Component ID is not a manifest class");
190+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
191+
}
192+
193+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
174194
if (ret != SUIT_PLAT_SUCCESS) {
175195
LOG_ERR("Selecting decryption filter failed: %i", ret);
176196
}
@@ -234,7 +254,9 @@ int suit_plat_check_fetch_integrated(suit_component_t dst_handle, struct zcbor_s
234254
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
235255
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
236256
int ret = SUIT_SUCCESS;
257+
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
237258
(void)manifest_component_id;
259+
#endif
238260

239261
/*
240262
* Validate streaming operation.
@@ -270,7 +292,15 @@ int suit_plat_check_fetch_integrated(suit_component_t dst_handle, struct zcbor_s
270292
/* Append decryption filter if encryption info is provided. */
271293
if (enc_info != NULL) {
272294
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
273-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
295+
suit_manifest_class_id_t *class_id = NULL;
296+
297+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
298+
SUIT_PLAT_SUCCESS) {
299+
LOG_ERR("Component ID is not a manifest class");
300+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
301+
}
302+
303+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
274304
if (ret != SUIT_PLAT_SUCCESS) {
275305
LOG_ERR("Selecting decryption filter failed: %i", ret);
276306
}
@@ -303,7 +333,10 @@ int suit_plat_fetch_integrated(suit_component_t dst_handle, struct zcbor_string
303333
suit_component_type_t dst_component_type = SUIT_COMPONENT_TYPE_UNSUPPORTED;
304334
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
305335
int ret = SUIT_SUCCESS;
336+
#if !defined(CONFIG_SUIT_STREAM_FILTER_DECRYPT)
306337
(void)manifest_component_id;
338+
#endif
339+
307340

308341
/*
309342
* Validate streaming operation.
@@ -339,7 +372,15 @@ int suit_plat_fetch_integrated(suit_component_t dst_handle, struct zcbor_string
339372
/* Append decryption filter if encryption info is provided. */
340373
if (enc_info != NULL) {
341374
#ifdef CONFIG_SUIT_STREAM_FILTER_DECRYPT
342-
ret = suit_decrypt_filter_get(&dst_sink, enc_info, &dst_sink);
375+
suit_manifest_class_id_t *class_id = NULL;
376+
377+
if (suit_plat_decode_manifest_class_id(manifest_component_id, &class_id) !=
378+
SUIT_PLAT_SUCCESS) {
379+
LOG_ERR("Component ID is not a manifest class");
380+
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
381+
}
382+
383+
ret = suit_decrypt_filter_get(&dst_sink, enc_info, class_id, &dst_sink);
343384
if (ret != SUIT_PLAT_SUCCESS) {
344385
LOG_ERR("Selecting decryption filter failed: %i", ret);
345386
}

subsys/suit/stream/stream_filters/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ zephyr_library_sources_ifdef(CONFIG_SUIT_AES_KW_MANUAL src/suit_aes_key_unwrap_m
1818

1919
zephyr_library_link_libraries(suit_stream_filters_interface)
2020
zephyr_library_link_libraries(suit_utils)
21+
zephyr_library_link_libraries(suit_mci)

subsys/suit/stream/stream_filters/include/suit_decrypt_filter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <suit_sink.h>
1111
#include <suit_types.h>
12+
#include <suit_metadata.h>
1213

1314
#ifdef __cplusplus
1415
extern "C" {
@@ -18,13 +19,15 @@ extern "C" {
1819
* @brief Get decrypt filter object
1920
*
2021
* @param[out] dec_sink Pointer to destination sink_stream to pass decrypted data
21-
* @param[in] end_info Pointer to the structure with encryption info.
22+
* @param[in] enc_info Pointer to the structure with encryption info.
23+
* @param[in] class_id Pointer to the manifest class ID of the destination component
2224
* @param[in] enc_sink Pointer to source sink_stream to be filled with encrypted data
2325
*
2426
* @return SUIT_PLAT_SUCCESS if success otherwise error code
2527
*/
2628
suit_plat_err_t suit_decrypt_filter_get(struct stream_sink *dec_sink,
2729
struct suit_encryption_info *enc_info,
30+
const suit_manifest_class_id_t *class_id,
2831
struct stream_sink *enc_sink);
2932

3033
#ifdef __cplusplus

0 commit comments

Comments
 (0)