Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tfm: Move TF-M attestation data to provisioned OTP region #17522

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

MarkusLassila
Copy link
Contributor

@MarkusLassila MarkusLassila commented Sep 27, 2024

Optional fields to TF-M attestation were previously stored in tfm_otp_nv_counters region, which we were not able to provision. This moves the psa_certification_reference to the provisioned OTP-region and adds support for accessing the variable data in
bl_storage.h.

Verification service URL and profile may change with device upgrades, for this reason they are added as Kconfigs.

Note that we still need to keep the tfm_otp_nv_counters region when TFM_PARTITION_PROTECTED_STORAGE and TFM_PS_ROLLBACK_PROTECTION are enabled. TF-M will increase monotonic counters every time new data is written and given the limited size of our OTP-region it would not support many updates.

NCSDK-17932

  • bl_storage tests -> Update: Variable data fields are currently only present with TF-M builds. With TF-M build, the application cannot access the provisioned data due provisioned data being secure. So bl_storage_tests are currently not possible.

@MarkusLassila MarkusLassila requested review from a team, nordicjm and tejlmand as code owners September 27, 2024 08:49
@github-actions github-actions bot added the changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. label Sep 27, 2024
@NordicBuilder
Copy link
Contributor

NordicBuilder commented Sep 27, 2024

CI Information

To view the history of this post, clich the 'edited' button above
Build number: 28

Inputs:

Sources:

sdk-nrf: PR head: 760fdc483c9f628a1a610efcbf879e79a6aa9213

more details

sdk-nrf:

PR head: 760fdc483c9f628a1a610efcbf879e79a6aa9213
merge base: 0eff1df3b72d96eef5021da8245852b3c24b3ff8
target head (main): a9f08286f0d3722edab7cac963c2b1af1283acc0
Diff

Github labels

Enabled Name Description
ci-disabled Disable the ci execution
ci-all-test Run all of ci, no test spec filtering will be done
ci-force-downstream Force execution of downstream even if twister fails
ci-run-twister Force run twister
ci-run-zephyr-twister Force run zephyr twister
List of changed files detected by CI (17)
cmake
│  ├── sysbuild
│  │  │ provision_hex.cmake
doc
│  ├── nrf
│  │  ├── releases_and_maturity
│  │  │  ├── releases
│  │  │  │  │ release-notes-changelog.rst
include
│  │ bl_storage.h
modules
│  ├── trusted-firmware-m
│  │  ├── CMakeLists.txt
│  │  ├── Kconfig
│  │  ├── Kconfig.tfm.pm
│  │  ├── tfm_boards
│  │  │  ├── CMakeLists.txt
│  │  │  ├── common
│  │  │  │  │ attest_hal.c
│  │  │  ├── partition
│  │  │  │  │ flash_layout.h
samples
│  ├── tfm
│  │  ├── tfm_psa_template
│  │  │  ├── README.rst
│  │  │  ├── prj.conf
│  │  │  │ sysbuild.conf
scripts
│  ├── bootloader
│  │  │ provision.py
subsys
│  ├── bootloader
│  │  ├── Kconfig
│  │  ├── bl_storage
│  │  │  │ bl_storage.c
sysbuild
│  ├── Kconfig.sysbuild
│  │ Kconfig.tfm

Outputs:

Toolchain

Version: 342151af73
Build docker image: docker-dtr.nordicsemi.no/sw-production/ncs-build:342151af73_912848a074

Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped; ⚠️ Quarantine

  • ◻️ Toolchain - Skipped: existing toolchain is used
  • ✅ Build twister - Skipped: Skipping Build & Test as it succeeded in a previous run: 27
  • ✅ Integration tests
    • ✅ test-sdk-audio - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ desktop52_verification - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-boot
    • ✅ test-fw-nrfconnect-apps - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test_ble_nrf_config - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-ble_mesh - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-ble_samples - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-chip
    • ✅ test-fw-nrfconnect-nfc - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_libmodem-nrf - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_serial_lte_modem - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_zephyr_lwm2m - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_samples - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_lwm2m - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ doc-internal - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_thingy91 - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf_crypto - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-rpc - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-rs - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-fem
    • ✅ test-fw-nrfconnect-tfm - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-thread - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-zigbee - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-find-my - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_mosh - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-nrf-iot_positioning - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-sidewalk - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-wifi - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-low-level - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-pmic-samples - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-mcuboot - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-sdk-dfu - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-fw-nrfconnect-ps - Skipped: Job was skipped as it succeeded in a previous run
    • ✅ test-secdom-samples-public - Skipped: Job was skipped as it succeeded in a previous run
    • ⚠️ test-fw-nrfconnect-fw-update
    • ⚠️ test-fw-nrfconnect-nrf-iot_cloud

Note: This message is automatically posted and updated by the CI

@NordicBuilder
Copy link
Contributor

You can find the documentation preview for this PR at this link. It will be updated about 10 minutes after the documentation build succeeds.

Note: This comment is automatically posted by the Documentation Publishing GitHub Action.

@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from 5f309ff to 956c258 Compare September 27, 2024 09:28
Comment on lines 461 to 574
#if CONFIG_BUILD_WITH_TFM

static uint32_t get_monotonic_counter_collection_size(const struct counter_collection *collection)
{
/* Add only the constant part of the counter_collection. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these functions introduced inside header file? These are not marked as inline. Also, as these are static, it means that multiple implementations might end up in the flash. One for each .c file that uses these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functions are inside header file as they are used both in MCUboot and in application (TF-M). This is how it was previously achieved and I did not change this (yet). Having the functions inside bl_storage.c would mean that the bl_storage.c would be split with functions / headers that are available in MCUboot and functions / headers that are available in TF-M.

I guess we are already kind of doing the same in header file, so if you think that moving this split to bl_storage.c would be an improvement, I can give it a go.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functions moved to bl_storage.c.

Copy link
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise looks OK, but I don't understand why the implementation is inside header file and not in bl_storage.c

Copy link
Contributor

@Vge0rge Vge0rge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good!
Some comments but I don't see anything seriously wrong with this.
Next time if you can please split such a change to more commits so that it is a bit more easy to follow.
I will give a second look to this before I approve.

@@ -0,0 +1,38 @@
# Copyright (c) 2024 Nordic Semiconductor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't that seem a bit out of place here?
I think that placing this in the same file with the rest of the TFM configurations makes it more logical to me:

I am not an expert on sysbuild but is the the only way to have this information to be visible by all the images in the build?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provisioning is done for the MCUboot, so it does not see the Kconfigs of the application. It might be possible to change this to include Kconfigs of the application, but whether this makes sense would need input from @nordicjm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sysbuild files go in sysbuild, this is the correct folder

@@ -336,6 +458,124 @@ NRFX_STATIC_INLINE int update_life_cycle_state(enum lcs next_lcs)
return -EINVALIDLCS;
}

#if CONFIG_BUILD_WITH_TFM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should is be defined in the TFM build I think.

include/bl_storage.h Outdated Show resolved Hide resolved
@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch 6 times, most recently from 12eebf3 to db6ad7e Compare November 13, 2024 13:38
@NordicBuilder
Copy link
Contributor

NordicBuilder commented Nov 13, 2024

Memory footprint analysis revealed the following potential issues

sample.matter.template.debug[nrf7002dk/nrf5340/cpuapp]: High ROM usage: 912202[B] - link (cc: @kkasperczyk-no @ArekBalysNordic @markaj-nordic)
sample.matter.template.release[nrf7002dk/nrf5340/cpuapp]: High ROM usage: 821126[B] - link (cc: @kkasperczyk-no @ArekBalysNordic @markaj-nordic)

Note: This message is automatically posted and updated by the CI (latest/sdk-nrf/PR-17522/27)

@MarkusLassila
Copy link
Contributor Author

sample.matter.template.release

Tried running:
cd /ncs/nrf/samples/matter/template
west build -p -b nrf7002dk/nrf5340/cpuapp . -T sample.matter.template.release

With my commit and without my commits. There was no difference, except saving 14 bytes with b0n, so I think that the space warning is due to other commits on main branch.

I did have to disable the following:
CONFIG_CHIP_FACTORY_DATA=n
CONFIG_CHIP_FACTORY_DATA_BUILD=n
MATTER_FACTORY_DATA_GENERATE=n

@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from db6ad7e to 9e47ba2 Compare November 14, 2024 09:51
@kkasperczyk-no
Copy link
Contributor

so I think that the space warning is due to other commits on main branch.

Yeah, unfortunately it's a little bit useless warning, because we never know which commit it applies to...

Copy link
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks OK in general.
I left few remarks.

include/bl_storage.h Outdated Show resolved Hide resolved
include/bl_storage.h Outdated Show resolved Hide resolved
enum tfm_plat_err_t tfm_attest_hal_get_verification_service(uint32_t *size, uint8_t *buf)
{
const char *url = CONFIG_TFM_ATTEST_VERIFICATION_SERVICE_URL;
uint32_t url_len = strlen(url);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional here that url_len does not contain NUL byte?

Suggested change
uint32_t url_len = strlen(url);
uint32_t url_len = sizeof(CONFIG_TFM_ATTEST_VERIFICATION_SERVICE_URL);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is intentional. The data is fed to be CBOR encoded, which includes the length of the data. The null byte is not needed.

Comment on lines +146 to +147
memcpy(buf, url, url_len);
*size = url_len;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you used strlen( ) in the beginning, then memcpy() would only copy the string without the terminating NUL character.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional.

scripts/bootloader/provision.py Outdated Show resolved Hide resolved
subsys/bootloader/bl_storage/bl_storage.c Outdated Show resolved Hide resolved
Comment on lines 112 to 234
/* Ensure word alignment, since the data is stored in memory region
* with word sized read limitation. Perform both build time and run
* time asserts to catch the issue as soon as possible.
*/
BUILD_ASSERT(offsetof(struct bl_storage_data, key_data) % 4 == 0);
__ASSERT(((uint32_t)p_key % 4 == 0), "Key address is not word aligned");

otp_copy32(p_buf, (volatile uint32_t *restrict)p_key, SB_PUBLIC_KEY_HASH_LEN);
otp_copy(p_buf, p_key, SB_PUBLIC_KEY_HASH_LEN);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really that we cannot guarantee the word alignment anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I restored the check. I thought the check was originally added as the otp_copy32 required the alignment, but now I am unsure about this.

@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from 9e47ba2 to 6b5e913 Compare December 18, 2024 14:28
@NordicBuilder
Copy link
Contributor

You can find the documentation preview for this PR at this link. It will be updated about 10 minutes after the documentation build succeeds.

Note: This comment is automatically posted by the Documentation Publish GitHub Action.

@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from 6b5e913 to ad7a4f0 Compare December 19, 2024 06:35
@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from ad7a4f0 to c15aa85 Compare December 19, 2024 07:23
@MarkusLassila MarkusLassila requested review from a team as code owners December 19, 2024 07:23
@github-actions github-actions bot added doc-required PR must not be merged without tech writer approval. and removed changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. labels Dec 19, 2024
@MarkusLassila
Copy link
Contributor Author

Ping: @Vge0rge, @nrfconnect/ncs-pluto

sysbuild/Kconfig.tfm Outdated Show resolved Hide resolved
include/bl_storage.h Outdated Show resolved Hide resolved
include/bl_storage.h Outdated Show resolved Hide resolved
@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from c15aa85 to 4b311e5 Compare December 19, 2024 08:03
@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from 4b311e5 to 2cf35a2 Compare December 20, 2024 13:48
subsys/bootloader/bl_storage/bl_storage.c Outdated Show resolved Hide resolved
include/bl_storage.h Outdated Show resolved Hide resolved
scripts/bootloader/provision.py Show resolved Hide resolved
@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from 2cf35a2 to 80f74a9 Compare December 23, 2024 12:54
Copy link
Contributor

@greg-fer greg-fer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit.

@@ -151,23 +172,77 @@ def get_hashes(public_key_files, verify_hashes):

return hashes

def get_variable_data(psa_certification_reference):
# Get variable data to be written to the OTP-region.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Get variable data to be written to the OTP-region.
# Get variable data to be written to the OTP region.

@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch 2 times, most recently from 760301e to 1de188d Compare January 14, 2025 10:33
@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch 2 times, most recently from e9e934e to 4fd7c82 Compare January 16, 2025 10:51
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
2 Security Hotspots
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

}
int update_life_cycle_state(enum lcs next_lcs);

#if CONFIG_BUILD_WITH_TFM
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this means doc cannot be generated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that the documentation cannot be generated for the below functions? What would you suggest?

I added the check for TF-M, because it seemed it seemed to save some space on mcuboot on non-tfm builds.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the #ifdef from the header file, it is enough to just have that in the .c file

include/bl_storage.h Show resolved Hide resolved
#elif defined(CONFIG_NRFX_RRAMC)
uint32_t word = nrfx_rramc_otp_word_read(index_from_address(address));

if (!(address & 0x3)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice to replace magic numbers with defines

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not addressed

static void otp_copy32(uint8_t *restrict dst, uint32_t volatile * restrict src,
size_t size)
{
for (int i = 0; i < size / 4; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size / sizeof(uint32_t)

Copy link
Contributor Author

@MarkusLassila MarkusLassila Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is removed in the next commit. Will fix on otp_copy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are things being changed to be changed again in fixup commits?

Comment on lines 176 to 177
static void otp_copy32(uint8_t *restrict dst, uint32_t volatile * restrict src,
size_t size)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

max line length is 100, this fits on one line with space to spare (plus for 2 lines the alignment of the second line is off)

Copy link
Contributor Author

@MarkusLassila MarkusLassila Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is removed in the next commit. Will fix on otp_copy.

Comment on lines 383 to 384
#define STATE_ENTERED 0x0000
#define STATE_NOT_ENTERED 0xFFFF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defines at top of file with other defines

@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch 2 times, most recently from e802768 to 6be875a Compare January 20, 2025 12:59
Add bl_storage.c to TF-M to reduce complexity on bl_storage.h.

Signed-off-by: Markus Lassila <[email protected]>
Optional fields to TF-M attestation were previously stored in
tfm_otp_nv_counters region, which we were not able to provision.
This moves the psa_certification_reference to the provisioned
OTP-region and adds support for accessing the variable data in
bl_storage.h.

Verification service URL and profile may change with device
upgrades, for this reason they are added as Kconfigs.

Note that we still need to keep the tfm_otp_nv_counters region
when TFM_PARTITION_PROTECTED_STORAGE and
TFM_PS_ROLLBACK_PROTECTION are enabled. TF-M will increase
monotonic counters every time new data is written and given the
limited size of our OTP-region it would not support many updates.

NCSDK-17932

Signed-off-by: Markus Lassila <[email protected]>
@MarkusLassila MarkusLassila force-pushed the tfm-remove-deprecated-tf-m-otp-nv-counters branch from 6be875a to 760fdc4 Compare January 21, 2025 09:49
@MarkusLassila
Copy link
Contributor Author

Ping @nordicjm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc-required PR must not be merged without tech writer approval.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants