-
Notifications
You must be signed in to change notification settings - Fork 60
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
[nrfconnect] Add platform crypto for KMU usage #539
base: master
Are you sure you want to change the base?
Conversation
83fa365
to
9017448
Compare
The solution is nice but I wonder if we can avoid this code duplication even more and also make it easier for customers to make a decision what to use the KMU slots for. I have an alternative to propose but I'll let you decide which way to go :).
The benefit is that if customers want to slightly modify the key allocation scheme (because e.g. they have their own keys to store in KMU and they don't care if ICD keys are in KMU or ITS), they don't need to make another copy of the key stores. |
Allow setting session keystore by platform. If any keystore is not set, assign the default one. Signed-off-by: Arkadiusz Balys <[email protected]>
80dccfe
to
4396c21
Compare
@Damian-Nordic I've introduced the new |
4396c21
to
68275de
Compare
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.
Looks great. Some mostly minor suggestions from me.
#include <crypto/PSAKeyAllocator.h> | ||
// Define the number of slots per NOC and ICD key. | ||
#define KMU_MATTER_SLOTS_PER_NOC_KEY 2 | ||
#define KMU_MATTER_SLOTS_PER_ICD_KEY 2 |
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.
technically it's more like ICD slots per fabric than #slots per ICD key but that's fine :)
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.
That's right, but it is consistent with NOC :) I will add a comment there.
if (psa_get_key_algorithm(attrs) == PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8)) | ||
{ | ||
psa_set_key_algorithm(attrs, PSA_ALG_CCM); | ||
psa_set_key_usage_flags(attrs, psa_get_key_usage_flags(attrs) | PSA_KEY_USAGE_EXPORT); |
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 export flag is only needed when creating volatile keys. Is export supported at all when using KMU? Or perhaps, it's not even checked? :)
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.
Even if it is supported in KMU, indeed we should disable it while storing it there :)
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.
I've added a change to the KMUSessionKeystore. Now the attributes for the new KMU keys don't contain these flags.
#define KMU_MATTER_SLOTS_PER_NOC_KEY 2 | ||
#define KMU_MATTER_SLOTS_PER_ICD_KEY 2 | ||
// Define the maximum number of fabrics supported by the KMU. | ||
#if CONFIG_CHIP_ICD_CHECK_IN_SUPPORT |
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.
Wonder if we want to base this scheme on the current configuration. If someone upgrades from non-ICD to ICD device, then the KMU slots will change their meaning. But I'm not sure if this scenario needs to be supported.
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.
I'll discuss it with the team shortly if we even plan such a case.
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.
@kkasperczyk-no @LuDuda what do you think? Should we always reserve slots for ICD to be ready for such a conversion?
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 should somehow allow customer for upgradability (which of course is harder with KMU), even if customer will need to modify manually KMUKeyAllocator implementation to allocate keys from outside of the Matter range . We need to describe it in the documentation thoroughly. If i correctly reading the code, someone would be able to modify the code for it's own purpose and manage key_ids as he wants, right? Even for example to store ICD keys to ITS instead of KMUs (with known side-effects)?
The same issue is also with increasing number of supported Fabrics. So we need to make it clear in documentation later on, that changing these parameters have impact on KMU slot allocation. Wonder.. if we can somehow prevent issues which can be hard to catch during testing.
Not sure if we should always blindly reserve slots which will not be used.. Maybe we need F2F discussion. Is it possible to "move" keys from slot A to slot B?
68275de
to
3a471a8
Compare
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.
Thanks for the changes to reduce the duplicated code! Approving assuming you will be discussing the non-ICD to ICD upgrade in the team.
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.
This is very clean! Great work 👍
Few nits and questions below.
src/crypto/PSAKeyAllocator.h
Outdated
* @brief Allocate a new Intermittently Connected Devices (ICD) key ID. | ||
* | ||
* ICD uses two keys - AES CCM and HMAC(SHA 256). | ||
* Each key must be allocated separately. |
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.
So what is the key_id_t returned here? We are making assumption that HMAC(SHA256) is always returned value + 1? Maybe, we should return some structure here actually?
Just a thought from scalability perspective @ArekBalysNordic @Damian-Nordic ?
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.
There is no such requirement. We save the key_id in zephyr settings, so no matter which slot it gets.
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.
Let's discuss it F2F - not sure I understand how it works then if we want to make operation HMAC(SHA256). On which Key ID we do this? Even if it's stored in settings, how we get it's 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.
During the ICD registration, we create two keys - HMAC(SHA256) and AES CCM. Originally, we put them into RAM and save their key IDs to Zephyr settings. If we need to use them, we get the key id from the specific Zephyr settings entry (used for ICD purposes) and provide it to PSA API. Recently we added moving these keys to PSA ITS (Now to KMU). Now during the ICD registration, we call an additional function "PersistICDKey" on each key and thanks to that we move the keys from RAM to ITS/KMU and we update the key ID saved in settings. So, to sum up, in settings we have something like a look-up table and key IDs assigned to specific ICD settings entries. Therefore, we don't need to take care of a specific slot for those keys, because we already have this information saved in zephyr settings. :)
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.
This part i get, but i don't understand what is the Key ID for AES CCM and what is the Key ID for HMAC(SHA256)? Looking at the code, I assume the AllocateICDKeyId
returns Key ID for AES CCM slot only - so what happens with HMAC(SHA256)? Or this is not needed to be persist?
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.
AllocateICDKeyId
just allocates a key ID from a given range. The caller then uses the key ID to either create AES or HMAC key. It then stores in setting that for a given ICD entry, AES key ID is, say, 0x27 and HMAC key ID is, say, 0x32.
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.
Fortunately, both AES and HMAC costs 1 KMU slot, so we can do it in the same way as for ITS. During the registration both keys are created one by one and uses the same allocate method. So Aes is created, allocate metod returns the first available key id within the given range, then HMAC is created and allocate method returns the next available key id in the same range. The difference is during the key creation. We use different attributes for each key, and then we don't need do check the key type during the allocation, just allocate the following ids.
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.
Oh, right.. Somehow i thought that during allocation of the slot, we also do need to know/set a proper key_type
, but it's more about just get an ID from a range. I think it works then fine.
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.
Still wound't be more scalable to return struct with two key_ids already? As you mentioned it just happened that they both use 1 slot of KMU, what if this change for any reason in future? Else, i would expand the documentation to make it a bit more clear, maybe:
* This method is used to allocate both AES-CCM and HMAC (SHA-256) keys independently.
* The caller is responsible for storing the key ID in non-volatile memory
* and setting the appropriate key 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.
I will change the documentation then, and we can consider changing it to struct as a follow-up because it will require some changes in the Matter stack.
#define KMU_MATTER_SLOTS_PER_NOC_KEY 2 | ||
#define KMU_MATTER_SLOTS_PER_ICD_KEY 2 | ||
// Define the maximum number of fabrics supported by the KMU. | ||
#if CONFIG_CHIP_ICD_CHECK_IN_SUPPORT |
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 should somehow allow customer for upgradability (which of course is harder with KMU), even if customer will need to modify manually KMUKeyAllocator implementation to allocate keys from outside of the Matter range . We need to describe it in the documentation thoroughly. If i correctly reading the code, someone would be able to modify the code for it's own purpose and manage key_ids as he wants, right? Even for example to store ICD keys to ITS instead of KMUs (with known side-effects)?
The same issue is also with increasing number of supported Fabrics. So we need to make it clear in documentation later on, that changing these parameters have impact on KMU slot allocation. Wonder.. if we can somehow prevent issues which can be hard to catch during testing.
Not sure if we should always blindly reserve slots which will not be used.. Maybe we need F2F discussion. Is it possible to "move" keys from slot A to slot B?
3a471a8
to
df432ff
Compare
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.
Looks good for me too. Let's discuss F2F the approach for upgradability.
- Moved the PSA key definitions from CHIPCryptoPALPSA.h file to the newly created PSAKeyAllocator. - The new PSAKeyAllocator class allows for the allocation of keys in secure storage. Users can create their own PSAKeyAllocator implementation and set it to be used by the Matter stack. - If the custom implementation is not provided the default one is used and it works as the legacy solution and the mechanism is about stored keys in the PSA ITS storage. Signed-off-by: Arkadiusz Balys <[email protected]>
KMUKeyAllocator is used to overwrite PSAKeyAllocator for the specific use-cases of KMU driver. This feature is available only on the device which run Cracen. Signed-off-by: Arkadiusz Balys <[email protected]>
We need to overwrite the PersistICDKey method of the PSASessionKeystore because we must export the volatile key first and then import it again into the KMU slot instead of copying it. Currently copying keys from the RAM location to the KMU slot is not supported. Signed-off-by: Arkadiusz Balys <[email protected]>
df432ff
to
4c6c76f
Compare
Let's review the code here first, before pushing it to the upstream repo.
Changes:
PersistICDKey
method of thePSASessionKeystore
class in the KMUSessionKeystore, because currently it is forbidden to use psa_copy_key to copy key from RAM to KMU slot.