-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: add tests for KMU and keys provisioning
Add two test applications with test scenarios automated with pytest. Keys are provisioned with the `west ncs-provision` command. The tests verify if the applications boot and if the keys are correct. Signed-off-by: Grzegorz Chwierut <[email protected]>
- Loading branch information
Showing
20 changed files
with
469 additions
and
0 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(hello_for_kmu) | ||
|
||
target_sources(app PRIVATE src/main.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# nothing here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="\${APPLICATION_CONFIG_DIR}/../keys/root-ed25519-2.pem" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="\${APPLICATION_CONFIG_DIR}/../keys/root-ed25519-w.pem" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA. | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#include <stdio.h> | ||
|
||
int main(void) | ||
{ | ||
printf("Hello World! %s\n", CONFIG_BOARD_TARGET); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
SB_CONFIG_BOOTLOADER_MCUBOOT=y | ||
SB_CONFIG_BOOT_SIGNATURE_TYPE_ED25519=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
CONFIG_NRF_SECURITY=y | ||
CONFIG_MBEDTLS=n | ||
CONFIG_BOOT_ED25519_PSA=y | ||
CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x10000 | ||
CONFIG_BOOT_SIGNATURE_USING_KMU=y | ||
|
||
# can be removed after merging #18487 | ||
CONFIG_MBEDTLS_THREADING_C=n |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
common: | ||
sysbuild: true | ||
timeout: 180 | ||
tags: pytest mcuboot kmu | ||
platform_allow: | ||
- nrf54l15dk/nrf54l15/cpuapp | ||
harness: pytest | ||
harness_config: | ||
pytest_dut_scope: session | ||
pytest_root: | ||
- "../pytest/test_kmu_with_mcuboot.py" | ||
tests: | ||
mcuboot.kmu.west.provision.default_key: {} | ||
mcuboot.kmu.west.provision.secondary_key: | ||
extra_args: | ||
- SB_EXTRA_CONF_FILE=sb_secondary_key.conf | ||
mcuboot.kmu.west.provision.wrong_key: | ||
extra_args: | ||
- SB_EXTRA_CONF_FILE=sb_wrong_key.conf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
-----BEGIN PRIVATE KEY----- | ||
MC4CAQAwBQYDK2VwBCIEIG5zv1wuAZJttuHXngrRJfi1w536UDDKra71UXroQ5z/ | ||
-----END PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
-----BEGIN PRIVATE KEY----- | ||
MC4CAQAwBQYDK2VwBCIEII9wFheJa4Lw7fAtmjp1GkonRMknzfJFEdZkTf94jyak | ||
-----END PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
-----BEGIN PRIVATE KEY----- | ||
MC4CAQAwBQYDK2VwBCIEIAGMROMZRAwsLq7pWKOsumPPKOKVfEjAydgAhaaVOi7s | ||
-----END PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
from __future__ import annotations | ||
|
||
import logging | ||
import shlex | ||
import subprocess | ||
|
||
from pathlib import Path | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
APP_KEYS_FOR_KMU = Path(__file__).resolve().parent.parent / 'keys' | ||
|
||
|
||
def run_command(command: list[str], timeout: int = 30): | ||
logger.info(f"CMD: {shlex.join(command)}") | ||
ret: subprocess.CompletedProcess = subprocess.run( | ||
command, text=True, stdout=subprocess.PIPE, | ||
stderr=subprocess.STDOUT, timeout=timeout) | ||
if ret.returncode: | ||
logger.error(f"Failed command: {shlex.join(command)}") | ||
logger.error(ret.stdout) | ||
raise subprocess.CalledProcessError(ret.returncode, command) | ||
|
||
|
||
def erase_board(dev_id: str | None): | ||
command = [ | ||
'nrfutil', 'device', 'erase' | ||
] | ||
if dev_id: | ||
command.extend(['--serial-number', dev_id]) | ||
run_command(command) | ||
|
||
|
||
def flash_board(build_dir: Path | str, dev_id: str | None, erase: bool = False): | ||
logger.info("Flash the board.") | ||
command = [ | ||
'west', 'flash', '--skip-rebuild', | ||
'-d', str(build_dir) | ||
] | ||
if dev_id: | ||
command.extend(['--dev-id', dev_id]) | ||
if erase: | ||
command.extend(['--erase']) | ||
run_command(command) | ||
|
||
|
||
def provision_keys_for_kmu(dev_id: str | None, key1: str | Path, | ||
key2: str | Path | None = None, | ||
key3: str | Path | None = None): | ||
logger.info("Provision keys using west command. Erase the board first") | ||
erase_board(dev_id) | ||
command = [ | ||
'west', 'ncs-provision', 'upload', | ||
'--soc', 'nrf54l15', | ||
'--key', str(key1) | ||
] | ||
if key2: | ||
command.extend(['--key', str(key2)]) | ||
if key3: | ||
command.extend(['--key', str(key3)]) | ||
if dev_id: | ||
command.extend(['--dev-id', dev_id]) | ||
run_command(command) | ||
logger.info("Keys provisioned successfully") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
import pytest | ||
import logging | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
@pytest.fixture(scope='function', autouse=True) | ||
def test_log(request: pytest.FixtureRequest): | ||
logging.info("========= Test '{}' STARTED".format(request.node.nodeid)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
from __future__ import annotations | ||
|
||
import logging | ||
|
||
from pathlib import Path | ||
from twister_harness import DeviceAdapter | ||
from twister_harness.helpers.utils import match_lines, find_in_config | ||
from common import ( | ||
provision_keys_for_kmu, | ||
flash_board, | ||
APP_KEYS_FOR_KMU | ||
) | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def test_kmu_correct_keys_uploaded(dut: DeviceAdapter): | ||
""" | ||
Upload valid keys to DUT using west ncs-provission command | ||
and verify it in application. | ||
""" | ||
zephyr_base = find_in_config(dut.device_config.build_dir / 'CMakeCache.txt', 'ZEPHYR_BASE:PATH') | ||
default_key = Path(zephyr_base).parent / 'bootloader' / 'mcuboot' / 'root-ed25519.pem' | ||
provision_keys_for_kmu(dut.device_config.id, | ||
key1=default_key, | ||
key2=APP_KEYS_FOR_KMU / 'root-ed25519-1.pem', | ||
key3=APP_KEYS_FOR_KMU / 'root-ed25519-2.pem') | ||
|
||
logger.info("Flash the board once again and check if keys are verified") | ||
dut.clear_buffer() | ||
flash_board(dut.device_config.build_dir, dut.device_config.id) | ||
|
||
lines = dut.readlines_until( | ||
regex='Key 2 failed|Key 2 verified|PSA crypto init failed', | ||
print_output=True, timeout=20) | ||
|
||
match_lines(lines, [ | ||
'Default key verified', | ||
'Key 1 verified', | ||
'Key 2 verified' | ||
]) | ||
|
||
|
||
def test_kmu_wrong_keys_uploaded(dut: DeviceAdapter): | ||
""" | ||
Upload two wrong keys to DUT using west ncs-provission command | ||
and verify it in application. | ||
""" | ||
provision_keys_for_kmu(dut.device_config.id, | ||
key1=APP_KEYS_FOR_KMU / 'root-ed25519-w.pem', | ||
key2=APP_KEYS_FOR_KMU / 'root-ed25519-1.pem', | ||
key3=APP_KEYS_FOR_KMU / 'root-ed25519-w.pem') | ||
|
||
logger.info("Flash the board once again and check if keys are verified") | ||
dut.clear_buffer() | ||
flash_board(dut.device_config.build_dir, dut.device_config.id) | ||
|
||
lines = dut.readlines_until( | ||
regex='Key 2 failed|Key 2 verified|PSA crypto init failed', | ||
print_output=True, timeout=20) | ||
|
||
match_lines(lines, [ | ||
'Default key failed', | ||
'Key 1 verified', | ||
'Key 2 failed' | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
from __future__ import annotations | ||
|
||
import logging | ||
|
||
from pathlib import Path | ||
from twister_harness import DeviceAdapter | ||
from twister_harness.helpers.utils import match_lines, find_in_config | ||
from common import ( | ||
provision_keys_for_kmu, | ||
flash_board, | ||
APP_KEYS_FOR_KMU | ||
) | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def test_kmu_use_key_from_config(dut: DeviceAdapter): | ||
""" | ||
Upload proper key using west ncs-provision command, | ||
verify that the application boots successfully. | ||
""" | ||
logger.info("Provision same key that was used during building") | ||
signature_key_file = find_in_config(Path(dut.device_config.build_dir) / 'mcuboot' / 'zephyr' / '.config', | ||
'CONFIG_BOOT_SIGNATURE_KEY_FILE') | ||
provision_keys_for_kmu(dut.device_config.id, key1=signature_key_file) | ||
|
||
dut.clear_buffer() | ||
flash_board(dut.device_config.build_dir, dut.device_config.id) | ||
|
||
lines = dut.readlines_until( | ||
regex='Unable to find bootable image|Jumping to the first image slot', | ||
print_output=True, timeout=20) | ||
|
||
match_lines(lines, ['Jumping to the first image slot']) | ||
logger.info("Passed: Booted succesvully after provisioning the same key that was used during building") | ||
|
||
|
||
def test_kmu_use_predefined_keys(dut: DeviceAdapter): | ||
""" | ||
Upload keys using west ncs-provision command, | ||
verify that the application boots successfully if the keys are correct, | ||
and does not boot if the keys are incorrect. | ||
""" | ||
signature_key_file = find_in_config(Path(dut.device_config.build_dir) / 'mcuboot' / 'zephyr' / '.config', | ||
'CONFIG_BOOT_SIGNATURE_KEY_FILE') | ||
zephyr_base = find_in_config(dut.device_config.build_dir / 'CMakeCache.txt', 'ZEPHYR_BASE:PATH') | ||
default_key = Path(zephyr_base).parent / 'bootloader' / 'mcuboot' / 'root-ed25519.pem' | ||
provision_keys_for_kmu(dut.device_config.id, | ||
key1=default_key, | ||
key2=APP_KEYS_FOR_KMU / 'root-ed25519-1.pem', | ||
key3=APP_KEYS_FOR_KMU / 'root-ed25519-2.pem') | ||
|
||
dut.clear_buffer() | ||
flash_board(dut.device_config.build_dir, dut.device_config.id) | ||
|
||
lines = dut.readlines_until( | ||
regex='Unable to find bootable image|Jumping to the first image slot', | ||
print_output=True, timeout=20) | ||
|
||
if 'root-ed25519-w.pem' in signature_key_file: | ||
match_lines(lines, [ | ||
'ED25519 signature verification failed', | ||
'Image in the primary slot is not valid', | ||
'Unable to find bootable image' | ||
]) | ||
logger.info("Passed: Not booted when used wrong keys") | ||
else: | ||
match_lines(lines, ['Jumping to the first image slot']) | ||
logger.info("Passed: Booted with correct keys") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(verify_west_ncs_provision) | ||
|
||
target_sources(app PRIVATE src/main.c) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
CONFIG_NRF_SECURITY=y | ||
CONFIG_PSA_WANT_ALG_PURE_EDDSA=y | ||
CONFIG_PSA_WANT_ALG_SHA_512=y | ||
CONFIG_PSA_WANT_ECC_TWISTED_EDWARDS_255=y | ||
CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT=y | ||
CONFIG_MBEDTLS=n | ||
CONFIG_MBEDTLS_ENABLE_HEAP=y | ||
CONFIG_MBEDTLS_HEAP_SIZE=2048 | ||
CONFIG_PSA_WANT_ALG_GCM=y | ||
CONFIG_PSA_WANT_KEY_TYPE_AES=y | ||
CONFIG_PSA_WANT_AES_KEY_SIZE_256=y | ||
CONFIG_PSA_WANT_ALG_SP800_108_COUNTER_CMAC=y | ||
CONFIG_PSA_WANT_ALG_CMAC=y | ||
CONFIG_PSA_WANT_ALG_ECB_NO_PADDING=y | ||
CONFIG_MAIN_STACK_SIZE=8192 |
Oops, something went wrong.