Skip to content

Commit e7c5c43

Browse files
tomchyrlubos
authored andcommitted
tests: Add tests for component compatibility check
Add tests to verify if the component compatibility check correctly denies addressing update candidate area. Ref: NCSDK-29624 Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 5736ed3 commit e7c5c43

File tree

18 files changed

+1011
-3
lines changed

18 files changed

+1011
-3
lines changed

subsys/suit/mci/Kconfig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
menuconfig SUIT_MCI
88
bool "Enable SUIT Manifest Configuration Information module"
99
depends on SUIT_METADATA
10+
depends on SUIT_EXECUTION_MODE
1011

1112
if SUIT_MCI
1213

1314
choice SUIT_MCI_IMPL
1415
prompt "MCI implementation"
16+
default SUIT_MCI_IMPL_NRF54H20_SDFW if SOC_SERIES_NRF54HX
17+
default SUIT_MCI_IMPL_CUSTOM if !SOC_SERIES_NRF54HX
1518

1619
config SUIT_MCI_IMPL_NRF54H20_SDFW
1720
bool "nRF54H20: Secure domain"
18-
depends on SOC_SERIES_NRF54HX
1921
depends on SUIT_PLATFORM_VARIANT_SDFW
2022

2123
config SUIT_MCI_IMPL_CUSTOM

subsys/suit/mci/src/suit_mci_nrf54h20.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include <suit_storage.h>
99
#include <suit_storage_mpi.h>
1010
#include <suit_execution_mode.h>
11+
#ifdef CONFIG_SDFW_LCS
1112
#include <sdfw/lcs.h>
13+
#endif /* CONFIG_SDFW_LCS */
1214
#include <zephyr/logging/log.h>
1315
#include <sdfw/arbiter.h>
1416

subsys/suit/platform/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ config SUIT_PLAT_CHECK_COMPONENT_COMPATIBILITY
8585
bool "Enable component ID check against supported manifest class IDs"
8686
depends on SUIT_UTILS
8787
depends on SUIT_METADATA
88+
depends on SUIT_MCI
8889

8990
config SUIT_PLAT_CHECK_CLASSES
9091
bool "Enable vendor/class/device class ID checks"
91-
depends on SUIT_PLAT_CHECK_COMPONENT_COMPATIBILITY
92+
depends on SUIT_PLAT_CHECK_COMPONENT_COMPATIBILITY || SSF_SUIT_SERVICE_ENABLED

subsys/suit/platform/sdfw/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ zephyr_library_link_libraries_ifdef(CONFIG_SUIT_PLAT_CHECK_COMPONENT_COMPATIBILI
4242
zephyr_library_link_libraries_ifdef(CONFIG_SUIT_STREAM_SOURCE_MEMPTR suit_stream_sources_interface)
4343
zephyr_library_link_libraries_ifdef(CONFIG_SUIT_DEVCONFIG suit_mci)
4444
zephyr_library_link_libraries_ifdef(CONFIG_SUIT_AUTHENTICATE suit_mci)
45+
zephyr_library_link_libraries_ifdef(CONFIG_SUIT_PLAT_CHECK_COMPONENT_COMPATIBILITY suit_mci)
4546
zephyr_library_link_libraries_ifdef(CONFIG_SUIT_STREAM_FILTER_DECRYPT suit_stream_filters_interface)
4647

4748

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
11+
project(integration_suit_component_compatibility_check)
12+
include(../cmake/test_template.cmake)
13+
14+
# Link with the CMake target, that includes SUIT platform internal APIs header
15+
zephyr_library_link_libraries(suit_utils)
16+
zephyr_library_link_libraries(suit_mci)
17+
zephyr_library_link_libraries(suit_storage_interface)
18+
zephyr_library_link_libraries(suit_platform_interface)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
# Include and define MOCK_* Kconfigs
8+
rsource "../mocks/Kconfig"
9+
10+
source "Kconfig.zephyr"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
CONFIG_FLASH_SIMULATOR=y
8+
# Mock processor IDs, defined in nrfx
9+
CONFIG_MOCK_NRFX=y
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
&flash0 {
8+
/* Align erase block size with the nRF54H20 MRAM definition. */
9+
erase-block-size = <16>;
10+
11+
partitions {
12+
compatible = "fixed-partitions";
13+
#address-cells = <1>;
14+
#size-cells = <1>;
15+
16+
/* Use the last 32 kB of SecDom SUIT NVM storage. */
17+
suit_storage_partition: partition@1e9000 {
18+
reg = <0x1e9000 DT_SIZE_K(32)>;
19+
};
20+
21+
/* Use the first 4kB as area reserved for Secure domain. */
22+
cpusec_suit_storage: partition@1eb000 {
23+
reg = <0x1eb000 DT_SIZE_K(4)>;
24+
};
25+
26+
/* Use the next 4kB as area reserved for Radio domain. */
27+
cpurad_suit_storage: partition@1ec000 {
28+
reg = <0x1ec000 DT_SIZE_K(4)>;
29+
};
30+
31+
/* Use the next 8kB as area reserved for Application domain. */
32+
cpuapp_suit_storage: partition@1ed000 {
33+
reg = <0x1ed000 DT_SIZE_K(8)>;
34+
};
35+
};
36+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
CONFIG_ZTEST=y
8+
9+
CONFIG_SUIT=y
10+
CONFIG_SUIT_PROCESSOR=y
11+
CONFIG_SUIT_UTILS=y
12+
CONFIG_SUIT_MEMPTR_STORAGE=y
13+
14+
# Enable component-compatibility checks
15+
CONFIG_SUIT_PLATFORM=y
16+
CONFIG_SUIT_PLATFORM_VARIANT_SDFW=y
17+
CONFIG_SUIT_PLAT_CHECK_COMPONENT_COMPATIBILITY=y
18+
19+
# Force SUIT storage memory layout to match nRF54H20-specific implementation.
20+
CONFIG_SUIT_STORAGE=y
21+
CONFIG_SUIT_STORAGE_LAYOUT_NRF54H20=y
22+
CONFIG_SUIT_METADATA=y
23+
# nRF54H20 storage uses SHA-256 to protect MPI and NVVs:
24+
CONFIG_SUIT_CRYPTO=y
25+
26+
# Use nRF54H20-specific MCI implementation.
27+
CONFIG_SUIT_MCI=y
28+
CONFIG_SUIT_MCI_IMPL_NRF54H20_SDFW=y
29+
CONFIG_SUIT_EXECUTION_MODE=y
30+
31+
CONFIG_ZCBOR=y
32+
CONFIG_ZCBOR_CANONICAL=y
33+
34+
CONFIG_FLASH=y
35+
36+
# Mock SDFW arbiter
37+
CONFIG_MOCK_SDFW_ARBITER=y
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/ztest.h>
8+
#include <suit_storage_mpi.h>
9+
#include <suit_plat_mem_util.h>
10+
#include "test_common.h"
11+
12+
#define SUIT_STORAGE_NORDIC_OFFSET FIXED_PARTITION_OFFSET(cpusec_suit_storage)
13+
#define SUIT_STORAGE_NORDIC_SIZE FIXED_PARTITION_SIZE(cpusec_suit_storage)
14+
#define SUIT_STORAGE_RAD_OFFSET FIXED_PARTITION_OFFSET(cpurad_suit_storage)
15+
#define SUIT_STORAGE_RAD_SIZE FIXED_PARTITION_SIZE(cpurad_suit_storage)
16+
#define SUIT_STORAGE_APP_OFFSET FIXED_PARTITION_OFFSET(cpuapp_suit_storage)
17+
#define SUIT_STORAGE_APP_SIZE FIXED_PARTITION_SIZE(cpuapp_suit_storage)
18+
19+
#define SUIT_STORAGE_APP_MPI_SIZE 0xf0
20+
#define SUIT_STORAGE_RAD_MPI_SIZE 0x90
21+
22+
/* clang-format off */
23+
24+
/* RFC4122 uuid5(uuid.NAMESPACE_DNS, 'nordicsemi.com') */
25+
const suit_manifest_class_id_t nordic_vid = {{
26+
0x76, 0x17, 0xda, 0xa5, 0x71, 0xfd, 0x5a, 0x85,
27+
0x8f, 0x94, 0xe2, 0x8d, 0x73, 0x5c, 0xe9, 0xf4
28+
}};
29+
30+
/* RFC4122 uuid5(nordic_vid, 'nRF54H20_nordic_top') */
31+
const suit_manifest_class_id_t nordic_top_cid = {{
32+
0xf0, 0x3d, 0x38, 0x5e, 0xa7, 0x31, 0x56, 0x05,
33+
0xb1, 0x5d, 0x03, 0x7f, 0x6d, 0xa6, 0x09, 0x7f
34+
}};
35+
36+
/* RFC4122 uuid5(nordic_vid, 'nRF54H20_sec') */
37+
const suit_manifest_class_id_t nordic_sdfw_cid = {{
38+
0xd9, 0x6b, 0x40, 0xb7, 0x09, 0x2b, 0x5c, 0xd1,
39+
0xa5, 0x9f, 0x9a, 0xf8, 0x0c, 0x33, 0x7e, 0xba
40+
}};
41+
42+
/* RFC4122 uuid5(nordic_vid, 'nRF54H20_sys') */
43+
const suit_manifest_class_id_t nordic_scfw_cid = {{
44+
0xc0, 0x8a, 0x25, 0xd7, 0x35, 0xe6, 0x59, 0x2c,
45+
0xb7, 0xad, 0x43, 0xac, 0xc8, 0xd1, 0xd1, 0xc8
46+
}};
47+
48+
/* RFC4122 uuid5(nordic_vid, 'test_sample_root') */
49+
const suit_manifest_class_id_t app_root_cid = {{
50+
0x97, 0x05, 0x48, 0x23, 0x4c, 0x3d, 0x59, 0xa1,
51+
0x89, 0x86, 0xa5, 0x46, 0x60, 0xa1, 0x4b, 0x0a,
52+
}};
53+
54+
/* RFC4122 uuid5(nordic_vid, 'test_sample_app') */
55+
const suit_manifest_class_id_t app_local_cid = {{
56+
0x5b, 0x46, 0x9f, 0xd1, 0x90, 0xee, 0x53, 0x9c,
57+
0xa3, 0x18, 0x68, 0x1b, 0x03, 0x69, 0x5e, 0x36,
58+
}};
59+
60+
/* clang-format on */
61+
62+
void erase_area_nordic(void)
63+
{
64+
/* Clear the whole nordic area */
65+
const struct device *fdev = SUIT_PLAT_INTERNAL_NVM_DEV;
66+
67+
zassert_not_null(fdev, "Unable to find a driver to modify MPI area");
68+
69+
int err = flash_erase(fdev, SUIT_STORAGE_NORDIC_OFFSET, SUIT_STORAGE_NORDIC_SIZE);
70+
71+
zassert_equal(0, err, "Unable to erase nordic area before test execution");
72+
}
73+
74+
void erase_area_rad(void)
75+
{
76+
/* Clear the whole radio area */
77+
const struct device *fdev = SUIT_PLAT_INTERNAL_NVM_DEV;
78+
79+
zassert_not_null(fdev, "Unable to find a driver to modify MPI area");
80+
81+
int err = flash_erase(fdev, SUIT_STORAGE_RAD_OFFSET, SUIT_STORAGE_RAD_SIZE);
82+
83+
zassert_equal(0, err, "Unable to erase radio core area before test execution");
84+
}
85+
86+
void erase_area_app(void)
87+
{
88+
/* Clear the whole application area */
89+
const struct device *fdev = SUIT_PLAT_INTERNAL_NVM_DEV;
90+
91+
zassert_not_null(fdev, "Unable to find a driver to modify MPI area");
92+
93+
int err = flash_erase(fdev, SUIT_STORAGE_APP_OFFSET, SUIT_STORAGE_APP_SIZE);
94+
95+
zassert_equal(0, err, "Unable to erase application area before test execution");
96+
}
97+
98+
void write_area_app(void)
99+
{
100+
/* clang-format off */
101+
uint8_t mpi_root[] = {
102+
/* Application root MPI area */
103+
0x01, /* version */
104+
0x01, /* downgrade prevention disabled */
105+
0x02, /* Independent update allowed */
106+
0x01, /* signature check disabled */
107+
/* reserved (12) */
108+
0xFF, 0xFF, 0xFF, 0xFF,
109+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
110+
/* RFC4122 uuid5(uuid.NAMESPACE_DNS, 'nordicsemi.com') */
111+
0x76, 0x17, 0xda, 0xa5, 0x71, 0xfd, 0x5a, 0x85,
112+
0x8f, 0x94, 0xe2, 0x8d, 0x73, 0x5c, 0xe9, 0xf4,
113+
/* RFC4122 uuid5(nordic_vid, 'test_sample_root') */
114+
0x97, 0x05, 0x48, 0x23, 0x4c, 0x3d, 0x59, 0xa1,
115+
0x89, 0x86, 0xa5, 0x46, 0x60, 0xa1, 0x4b, 0x0a,
116+
/* Application recovery MPI area (48) */
117+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
118+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
119+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
121+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
122+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123+
/* Application local 1 MPI area */
124+
0x01, /* version */
125+
0x01, /* downgrade prevention disabled */
126+
0x01, /* Independent update denied */
127+
0x01, /* signature check disabled */
128+
/* reserved (12) */
129+
0xFF, 0xFF, 0xFF, 0xFF,
130+
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
131+
/* RFC4122 uuid5(uuid.NAMESPACE_DNS, 'nordicsemi.com') */
132+
0x76, 0x17, 0xda, 0xa5, 0x71, 0xfd, 0x5a, 0x85,
133+
0x8f, 0x94, 0xe2, 0x8d, 0x73, 0x5c, 0xe9, 0xf4,
134+
/* RFC4122 uuid5(nordic_vid, 'test_sample_app') */
135+
0x5b, 0x46, 0x9f, 0xd1, 0x90, 0xee, 0x53, 0x9c,
136+
0xa3, 0x18, 0x68, 0x1b, 0x03, 0x69, 0x5e, 0x36,
137+
};
138+
uint8_t app_digest[] = {
139+
0x44, 0xdc, 0x3d, 0xc5, 0xf3, 0xab, 0x75, 0xa5,
140+
0x22, 0xd6, 0x42, 0xce, 0x92, 0xb8, 0xbe, 0xf4,
141+
0x60, 0xcd, 0x7c, 0xab, 0xfa, 0x18, 0x8b, 0x91,
142+
0x69, 0x32, 0x0a, 0x8b, 0x9e, 0x35, 0x28, 0xa9,
143+
};
144+
/* clang-format on */
145+
146+
/* Write the sample application area (just the root MPI) and corresponding digest */
147+
const struct device *fdev = SUIT_PLAT_INTERNAL_NVM_DEV;
148+
149+
zassert_not_null(fdev, "Unable to find a driver to modify MPI area");
150+
151+
int err = flash_write(fdev, SUIT_STORAGE_APP_OFFSET, mpi_root, sizeof(mpi_root));
152+
153+
zassert_equal(0, err,
154+
"Unable to store application root MPI contents before test execution");
155+
156+
err = flash_write(fdev, SUIT_STORAGE_APP_OFFSET + SUIT_STORAGE_APP_MPI_SIZE, app_digest,
157+
sizeof(app_digest));
158+
zassert_equal(0, err, "Unable to store application MPI digest before test execution");
159+
}
160+
161+
void assert_nordic_classes(void)
162+
{
163+
suit_manifest_class_info_t class_infos[CONFIG_SUIT_STORAGE_N_ENVELOPES];
164+
size_t class_infos_len = CONFIG_SUIT_STORAGE_N_ENVELOPES;
165+
166+
/* ASSERT that it is possible to fetch list of supported manifest classes and roles */
167+
int err = suit_storage_mpi_class_ids_get(class_infos, &class_infos_len);
168+
169+
zassert_equal(err, SUIT_PLAT_SUCCESS,
170+
"Failed to fetch list of supported manifest classes (%d).", err);
171+
/* ... and MPI reports at least 3 class IDs */
172+
zassert_true(class_infos_len >= 3,
173+
"Invalid number of supported manifest classes (%d < %d).", class_infos_len, 3);
174+
/* ... and the Nordic top manifest class is supported */
175+
zassert_mem_equal(class_infos[0].vendor_id, &nordic_vid, sizeof(nordic_vid));
176+
zassert_mem_equal(class_infos[0].class_id, &nordic_top_cid, sizeof(nordic_top_cid));
177+
zassert_equal(class_infos[0].role, SUIT_MANIFEST_SEC_TOP, "Invalid class role returned: %d",
178+
class_infos[0].role);
179+
/* ... and the Nordic secure domain update & recovery manifest class is supported */
180+
zassert_mem_equal(class_infos[1].vendor_id, &nordic_vid, sizeof(nordic_vid));
181+
zassert_mem_equal(class_infos[1].class_id, &nordic_sdfw_cid, sizeof(nordic_sdfw_cid));
182+
zassert_equal(class_infos[1].role, SUIT_MANIFEST_SEC_SDFW,
183+
"Invalid class role returned: %d", class_infos[3].role);
184+
/* ... and the Nordic system controller manifest class is supported */
185+
zassert_mem_equal(class_infos[2].vendor_id, &nordic_vid, sizeof(nordic_vid));
186+
zassert_mem_equal(class_infos[2].class_id, &nordic_scfw_cid, sizeof(nordic_scfw_cid));
187+
zassert_equal(class_infos[2].role, SUIT_MANIFEST_SEC_SYSCTRL,
188+
"Invalid class role returned: %d", class_infos[3].role);
189+
}
190+
191+
void assert_sample_app_classes(void)
192+
{
193+
suit_manifest_class_info_t class_infos[CONFIG_SUIT_STORAGE_N_ENVELOPES];
194+
size_t class_infos_len = CONFIG_SUIT_STORAGE_N_ENVELOPES;
195+
196+
/* ASSERT that it is possible to fetch list of supported manifest classes and roles */
197+
int err = suit_storage_mpi_class_ids_get(class_infos, &class_infos_len);
198+
199+
zassert_equal(err, SUIT_PLAT_SUCCESS,
200+
"Failed to fetch list of supported manifest classes (%d).", err);
201+
/* ... and MPI reports 5 supported class IDs */
202+
zassert_equal(class_infos_len, 5,
203+
"Invalid number of supported manifest classes (%d != %d).", class_infos_len,
204+
5);
205+
/* ... and the sample application root manifest class is supported */
206+
zassert_mem_equal(class_infos[3].vendor_id, &nordic_vid, sizeof(nordic_vid));
207+
zassert_mem_equal(class_infos[3].class_id, &app_root_cid, sizeof(app_root_cid));
208+
zassert_equal(class_infos[3].role, SUIT_MANIFEST_APP_ROOT,
209+
"Invalid class role returned: %d", class_infos[4].role);
210+
/* ... and the sample application local manifest class is supported */
211+
zassert_mem_equal(class_infos[4].vendor_id, &nordic_vid, sizeof(nordic_vid));
212+
zassert_mem_equal(class_infos[4].class_id, &app_local_cid, sizeof(app_local_cid));
213+
zassert_equal(class_infos[4].role, SUIT_MANIFEST_APP_LOCAL_1,
214+
"Invalid class role returned: %d", class_infos[4].role);
215+
}

0 commit comments

Comments
 (0)