|
12 | 12 | #include <nrf_security_mutexes.h>
|
13 | 13 | #include <psa/crypto.h>
|
14 | 14 | #include <stdint.h>
|
| 15 | +#include <string.h> |
15 | 16 | #include <sxsymcrypt/internal.h>
|
16 | 17 | #include <hw_unique_key.h>
|
17 | 18 | #include <cracen_psa.h>
|
@@ -210,6 +211,56 @@ static psa_status_t cracen_kmu_decrypt(kmu_metadata *metadata, size_t number_of_
|
210 | 211 |
|
211 | 212 | #endif /* PSA_NEED_CRACEN_KMU_ENCRYPTED_KEYS */
|
212 | 213 |
|
| 214 | +#ifdef CONFIG_CRACEN_PROVISION_PROT_RAM_INV_DATA |
| 215 | +psa_status_t cracen_provision_prot_ram_inv_data(void) |
| 216 | +{ |
| 217 | + uint8_t rng_buffer[2 * CRACEN_KMU_SLOT_KEY_SIZE]; |
| 218 | + bool needs_provisioning; |
| 219 | + psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; |
| 220 | + psa_status_t status; |
| 221 | + int kmu_slot; |
| 222 | + |
| 223 | + needs_provisioning = lib_kmu_is_slot_empty(PROTECTED_RAM_INVALIDATION_DATA_SLOT1) || |
| 224 | + lib_kmu_is_slot_empty(PROTECTED_RAM_INVALIDATION_DATA_SLOT2); |
| 225 | + |
| 226 | + if (!needs_provisioning) { |
| 227 | + return PSA_SUCCESS; |
| 228 | + } |
| 229 | + |
| 230 | + status = cracen_get_random(NULL, rng_buffer, sizeof(rng_buffer)); |
| 231 | + if (status != PSA_SUCCESS) { |
| 232 | + return status; |
| 233 | + } |
| 234 | + |
| 235 | + /* Just use attributes which are suitable for a normal protected RAM |
| 236 | + * key so that the existed KMU provision API can be used. |
| 237 | + */ |
| 238 | + psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT); |
| 239 | + psa_set_key_algorithm(&key_attributes, PSA_ALG_CTR); |
| 240 | + psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES); |
| 241 | + psa_set_key_bits(&key_attributes, 256); |
| 242 | + psa_set_key_lifetime(&key_attributes, |
| 243 | + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( |
| 244 | + PSA_KEY_PERSISTENCE_DEFAULT, PSA_KEY_LOCATION_CRACEN_KMU)); |
| 245 | + |
| 246 | + /* The rng material here is 256 bits so it will occupy 2 KMU slots during |
| 247 | + * the provisioning call. |
| 248 | + */ |
| 249 | + psa_set_key_id(&key_attributes, |
| 250 | + mbedtls_svc_key_id_make(0, PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT( |
| 251 | + CRACEN_KMU_KEY_USAGE_SCHEME_PROTECTED, |
| 252 | + PROTECTED_RAM_INVALIDATION_DATA_SLOT1))); |
| 253 | + |
| 254 | + kmu_slot = CRACEN_PSA_GET_KMU_SLOT( |
| 255 | + MBEDTLS_SVC_KEY_ID_GET_KEY_ID(psa_get_key_id(&key_attributes))); |
| 256 | + |
| 257 | + status = cracen_kmu_provision(&key_attributes, kmu_slot, rng_buffer, sizeof(rng_buffer)); |
| 258 | + safe_memzero(rng_buffer, sizeof(rng_buffer)); |
| 259 | + return status; |
| 260 | +} |
| 261 | +#endif /* CONFIG_CRACEN_PROVISION_PROT_RAM_INV_DATA */ |
| 262 | + |
| 263 | + |
213 | 264 | /* Used internally in sxsymcrypt so we use sx return codes here. */
|
214 | 265 | int cracen_kmu_prepare_key(const uint8_t *user_data)
|
215 | 266 | {
|
@@ -255,7 +306,30 @@ int cracen_kmu_prepare_key(const uint8_t *user_data)
|
255 | 306 |
|
256 | 307 | int cracen_kmu_clean_key(const uint8_t *user_data)
|
257 | 308 | {
|
258 |
| - (void)user_data; |
| 309 | + const kmu_opaque_key_buffer *key = (const kmu_opaque_key_buffer *)user_data; |
| 310 | + bool any_slot_empty; |
| 311 | + |
| 312 | + switch (key->key_usage_scheme) { |
| 313 | + case CRACEN_KMU_KEY_USAGE_SCHEME_PROTECTED: |
| 314 | + any_slot_empty = lib_kmu_is_slot_empty(PROTECTED_RAM_INVALIDATION_DATA_SLOT1) || |
| 315 | + lib_kmu_is_slot_empty(PROTECTED_RAM_INVALIDATION_DATA_SLOT2); |
| 316 | + if (any_slot_empty) { |
| 317 | + return SX_ERR_UNKNOWN_ERROR; |
| 318 | + } |
| 319 | + |
| 320 | + if (lib_kmu_push_slot(PROTECTED_RAM_INVALIDATION_DATA_SLOT1) != LIB_KMU_SUCCESS) { |
| 321 | + return SX_ERR_UNKNOWN_ERROR; |
| 322 | + } |
| 323 | + |
| 324 | + if (lib_kmu_push_slot(PROTECTED_RAM_INVALIDATION_DATA_SLOT2) != LIB_KMU_SUCCESS) { |
| 325 | + return SX_ERR_UNKNOWN_ERROR; |
| 326 | + } |
| 327 | + |
| 328 | + break; |
| 329 | + default: |
| 330 | + break; |
| 331 | + } |
| 332 | + |
259 | 333 | safe_memzero(kmu_push_area, sizeof(kmu_push_area));
|
260 | 334 |
|
261 | 335 | return SX_OK;
|
@@ -632,6 +706,7 @@ static psa_status_t convert_to_psa_attributes(kmu_metadata *metadata,
|
632 | 706 | static psa_status_t convert_from_psa_attributes(const psa_key_attributes_t *key_attr,
|
633 | 707 | kmu_metadata *metadata)
|
634 | 708 | {
|
| 709 | + int kmu_slot; |
635 | 710 | memset(metadata, 0, sizeof(*metadata));
|
636 | 711 | metadata->metadata_version = 0;
|
637 | 712 |
|
@@ -790,7 +865,14 @@ static psa_status_t convert_from_psa_attributes(const psa_key_attributes_t *key_
|
790 | 865 | break;
|
791 | 866 | #endif
|
792 | 867 | default:
|
793 |
| - return PSA_ERROR_NOT_SUPPORTED; |
| 868 | + /* Ignore the algorithm for the protected ram invalidation kmu slot because |
| 869 | + * it will never be used for crypto operations. |
| 870 | + */ |
| 871 | + kmu_slot = CRACEN_PSA_GET_KMU_SLOT( |
| 872 | + MBEDTLS_SVC_KEY_ID_GET_KEY_ID(psa_get_key_id(key_attr))); |
| 873 | + if (kmu_slot != PROTECTED_RAM_INVALIDATION_DATA_SLOT1) { |
| 874 | + return PSA_ERROR_NOT_SUPPORTED; |
| 875 | + } |
794 | 876 | }
|
795 | 877 |
|
796 | 878 | psa_key_usage_t resulting_usage = 0;
|
@@ -1070,6 +1152,12 @@ psa_status_t cracen_kmu_get_builtin_key(psa_drv_slot_number_t slot_number,
|
1070 | 1152 | return status;
|
1071 | 1153 | }
|
1072 | 1154 |
|
| 1155 | + if (slot_number == PROTECTED_RAM_INVALIDATION_DATA_SLOT1 || |
| 1156 | + slot_number == PROTECTED_RAM_INVALIDATION_DATA_SLOT2) { |
| 1157 | + /* The protected ram invalidation slots are not used for crypto operations. */ |
| 1158 | + return PSA_ERROR_INVALID_ARGUMENT; |
| 1159 | + } |
| 1160 | + |
1073 | 1161 | status = clean_up_unfinished_provisioning();
|
1074 | 1162 | if (status != PSA_SUCCESS) {
|
1075 | 1163 | return status;
|
|
0 commit comments