-
Notifications
You must be signed in to change notification settings - Fork 1.4k
nrf_security: Add key policy for the Cracen builtin keys #25458
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
base: main
Are you sure you want to change the base?
Conversation
Vge0rge
commented
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds access control policies for Cracen builtin keys (IKG and KMU) when used with TF-M, restricting key access to specifically allowed users based on owner ID encoded in key attributes.
Key changes:
- Implements a policy framework with user-to-key-slot mappings for both IKG and KMU builtin keys
- Adds permission checks across all key management operations to enforce the policy
- Provides no-op implementation when TF-M is not enabled
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| cracen_builtin_key_policy.c | New file implementing policy enforcement logic with allowlists for IKG and KMU keys |
| cracen_psa_builtin_key_policy.h | New header defining policy data structures and the permission check API |
| key_management.c | Adds permission checks to all key management functions |
| cracen_psa.h | Removes unused TF-M header include |
| cracenpsa.cmake | Adds new policy source file to build (duplicated entry) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
subsys/nrf_security/src/drivers/cracen/cracenpsa/cracenpsa.cmake
Outdated
Show resolved
Hide resolved
subsys/nrf_security/src/drivers/cracen/cracenpsa/src/cracen_builtin_key_policy.c
Outdated
Show resolved
Hide resolved
subsys/nrf_security/src/drivers/cracen/cracenpsa/src/cracen_builtin_key_policy.c
Outdated
Show resolved
Hide resolved
CI InformationTo view the history of this post, click the 'edited' button above Inputs:Sources:sdk-nrf: PR head: 59a9b82de74b9aeb8922a35cf2b5ace49b76ac25 more detailssdk-nrf:
Github labels
List of changed files detected by CI (5)Outputs:ToolchainVersion: df3cc9d822 Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped;
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add logic which allows to specifically define who can use the builtin keys (IKG and KMU one) for Cracen when used with TF-M. This includes a list of specifically allowed users for the builtin keys and any other access is denied. This is only relevant for a TF-M enabled application since that is currently the only way to encode ownership in the key attributes. Ref: NCSDK-35736 Signed-off-by: Georgios Vasilakis <georgios.vasilakis@nordicsemi.no>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| PSA_KEY_LOCATION_CRACEN) { | ||
|
|
||
| slot_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(psa_get_key_id(attributes)); | ||
| if (!cracen_builtin_ikg_user_allowed(owner, slot_id, attributes)) { |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here always returns false if the IKG check fails, but should return true if the check passes to allow the key operation. The early return on line 117 prevents the function from returning true when access is allowed for IKG keys. This should be: if (cracen_builtin_ikg_user_allowed(owner, slot_id, attributes)) { return true; }
| if (!cracen_builtin_ikg_user_allowed(owner, slot_id, attributes)) { | |
| if (cracen_builtin_ikg_user_allowed(owner, slot_id, attributes)) { | |
| return true; | |
| } else { |
| slot_id = CRACEN_PSA_GET_KMU_SLOT( | ||
| MBEDTLS_SVC_KEY_ID_GET_KEY_ID(psa_get_key_id(attributes))); | ||
| if (!cracen_builtin_kmu_user_allowed(owner, slot_id, attributes)) { | ||
| return false; | ||
| } |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic here always returns false if the KMU check fails, but should return true if the check passes. The early return on line 128 prevents the function from returning true when access is allowed for KMU keys. This should be: if (cracen_builtin_kmu_user_allowed(owner, slot_id, attributes)) { return true; }
The tfm_builtin_key_loader.h defines the symbol: TFM_BUILTIN_KEY_LOADER_KEY_LOCATION which is also defined in the tfm_builtin_key_ids.h when Cracen is enabled. To avoid this remove including the default key loader and only keep the Cracen one. Signed-off-by: Georgios Vasilakis <georgios.vasilakis@nordicsemi.no>
1849194 to
59a9b82
Compare
| #include "psa_manifest/pid.h" | ||
| #include "tfm_builtin_key_ids.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use angle brackets
| #ifndef CRACEN_BUILTIN_KEY_POLICY_H | ||
| #define CRACEN_BUILTIN_KEY_POLICY_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
header guard mismatch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't call this source file cracen to follow convention in this directory?
| #ifndef CRACEN_BUILTIN_KEY_POLICY_H | ||
| #define CRACEN_BUILTIN_KEY_POLICY_H | ||
|
|
||
| #include "common.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #include "common.h" | |
| #include <common.h> |
| #ifndef CRACEN_BUILTIN_KEY_POLICY_H | ||
| #define CRACEN_BUILTIN_KEY_POLICY_H | ||
|
|
||
| #include "common.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this even including?
| mbedtls_key_owner_id_t user; | ||
| psa_drv_slot_number_t key_slot_start; | ||
| psa_drv_slot_number_t key_slot_end; | ||
| cracen_kmu_entry_type_t kmu_entry_type; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me this field is not actually useful and we could just do with key_slot_start and key_slot_end alone? For the KMU_ENTRY_SLOT_SINGLE case you would just have key_slot_start == key_slot_end.
| mbedtls_key_owner_id_t owner = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(psa_get_key_id(attributes)); | ||
| psa_drv_slot_number_t slot_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also have a variable which holds MBEDTLS_SVC_KEY_ID_GET_KEY_ID(psa_get_key_id(attributes)) to avoid repetition.
| mbedtls_key_owner_id_t owner = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(psa_get_key_id(attributes)); | ||
| psa_drv_slot_number_t slot_id; | ||
|
|
||
| if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes)) == |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a switch instead?
| if (!cracen_builtin_ikg_user_allowed(owner, slot_id, attributes)) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just
| if (!cracen_builtin_ikg_user_allowed(owner, slot_id, attributes)) { | |
| return false; | |
| } | |
| return cracen_builtin_ikg_user_allowed(owner, slot_id, attributes) |
?
| if (g_builtin_ikg_policy[i].user == owner && | ||
| g_builtin_ikg_policy[i].key_slot == slot_number) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Terminology is not aligned (user/owner, key_slot/slot_number). Maybe align?