|
| 1 | +/* Copyright (c) 2024 Nordic Semiconductor |
| 2 | + * SPDX-License-Identifier: Apache-2.0 |
| 3 | + */ |
| 4 | +#include <zephyr/secure_storage/its/store.h> |
| 5 | +#include <zephyr/logging/log.h> |
| 6 | +#include <zephyr/fs/zms.h> |
| 7 | +#include <zephyr/storage/flash_map.h> |
| 8 | +#ifdef CONFIG_SECURE_STORAGE_ITS_IMPLEMENTATION_ZEPHYR |
| 9 | +#include <zephyr/secure_storage/its/transform.h> |
| 10 | +#endif |
| 11 | + |
| 12 | +LOG_MODULE_DECLARE(secure_storage, CONFIG_SECURE_STORAGE_LOG_LEVEL); |
| 13 | + |
| 14 | +BUILD_ASSERT(CONFIG_SECURE_STORAGE_ITS_STORE_ZMS_SECTOR_SIZE |
| 15 | + > 2 * CONFIG_SECURE_STORAGE_ITS_MAX_DATA_SIZE); |
| 16 | + |
| 17 | +#define PARTITION_DT_NODE DT_CHOSEN(secure_storage_its_partition) |
| 18 | + |
| 19 | +static struct zms_fs s_zms = { |
| 20 | + .flash_device = FIXED_PARTITION_NODE_DEVICE(PARTITION_DT_NODE), |
| 21 | + .offset = FIXED_PARTITION_NODE_OFFSET(PARTITION_DT_NODE), |
| 22 | + .sector_size = CONFIG_SECURE_STORAGE_ITS_STORE_ZMS_SECTOR_SIZE, |
| 23 | +}; |
| 24 | + |
| 25 | +static int init_zms(void) |
| 26 | +{ |
| 27 | + int ret; |
| 28 | + |
| 29 | + s_zms.sector_count = FIXED_PARTITION_NODE_SIZE(PARTITION_DT_NODE) / s_zms.sector_size; |
| 30 | + |
| 31 | + ret = zms_mount(&s_zms); |
| 32 | + if (ret) { |
| 33 | + LOG_DBG("Failed. (%d)", ret); |
| 34 | + } |
| 35 | + return ret; |
| 36 | +} |
| 37 | +SYS_INIT(init_zms, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); |
| 38 | + |
| 39 | +/* Bit position of the ITS caller ID in the ZMS entry ID. */ |
| 40 | +#define ITS_CALLER_ID_POS 30 |
| 41 | +/* Make sure that every ITS caller ID fits in ZMS entry IDs at the defined position. */ |
| 42 | +BUILD_ASSERT(1 << (32 - ITS_CALLER_ID_POS) >= SECURE_STORAGE_ITS_CALLER_COUNT); |
| 43 | + |
| 44 | +static bool has_forbidden_bits_set(secure_storage_its_uid_t uid) |
| 45 | +{ |
| 46 | + if (uid.uid & GENMASK64(63, ITS_CALLER_ID_POS)) { |
| 47 | + LOG_DBG("UID %u/0x%llx cannot be used as it has bits set past " |
| 48 | + "the first " STRINGIFY(ITS_CALLER_ID_POS) " ones.", |
| 49 | + uid.caller_id, (unsigned long long)uid.uid); |
| 50 | + return true; |
| 51 | + } |
| 52 | + return false; |
| 53 | +} |
| 54 | + |
| 55 | +static uint32_t zms_id_from(secure_storage_its_uid_t uid) |
| 56 | +{ |
| 57 | + return (uint32_t)uid.uid | (uid.caller_id << ITS_CALLER_ID_POS); |
| 58 | +} |
| 59 | + |
| 60 | +psa_status_t secure_storage_its_store_set(secure_storage_its_uid_t uid, |
| 61 | + size_t data_length, const void *data) |
| 62 | +{ |
| 63 | + psa_status_t psa_ret; |
| 64 | + ssize_t zms_ret; |
| 65 | + const uint32_t zms_id = zms_id_from(uid); |
| 66 | + |
| 67 | + if (has_forbidden_bits_set(uid)) { |
| 68 | + return PSA_ERROR_INVALID_ARGUMENT; |
| 69 | + } |
| 70 | + |
| 71 | + zms_ret = zms_write(&s_zms, zms_id, data, data_length); |
| 72 | + if (zms_ret == data_length) { |
| 73 | + psa_ret = PSA_SUCCESS; |
| 74 | + } else if (zms_ret == -ENOSPC) { |
| 75 | + psa_ret = PSA_ERROR_INSUFFICIENT_STORAGE; |
| 76 | + } else { |
| 77 | + psa_ret = PSA_ERROR_STORAGE_FAILURE; |
| 78 | + } |
| 79 | + LOG_DBG("%s 0x%x with %zu bytes. (%zd)", (psa_ret == PSA_SUCCESS) ? |
| 80 | + "Wrote" : "Failed to write", zms_id, data_length, zms_ret); |
| 81 | + return psa_ret; |
| 82 | +} |
| 83 | + |
| 84 | +psa_status_t secure_storage_its_store_get(secure_storage_its_uid_t uid, size_t data_size, |
| 85 | + void *data, size_t *data_length) |
| 86 | +{ |
| 87 | + psa_status_t psa_ret; |
| 88 | + ssize_t zms_ret; |
| 89 | + const uint32_t zms_id = zms_id_from(uid); |
| 90 | + |
| 91 | + if (has_forbidden_bits_set(uid)) { |
| 92 | + return PSA_ERROR_INVALID_ARGUMENT; |
| 93 | + } |
| 94 | + |
| 95 | + zms_ret = zms_read(&s_zms, zms_id, data, data_size); |
| 96 | + if (zms_ret > 0) { |
| 97 | + *data_length = zms_ret; |
| 98 | + psa_ret = PSA_SUCCESS; |
| 99 | + } else if (zms_ret == -ENOENT) { |
| 100 | + psa_ret = PSA_ERROR_DOES_NOT_EXIST; |
| 101 | + } else { |
| 102 | + psa_ret = PSA_ERROR_STORAGE_FAILURE; |
| 103 | + } |
| 104 | + LOG_DBG("%s 0x%x for up to %zu bytes. (%zd)", (psa_ret != PSA_ERROR_STORAGE_FAILURE) ? |
| 105 | + "Read" : "Failed to read", zms_id, data_size, zms_ret); |
| 106 | + return psa_ret; |
| 107 | +} |
| 108 | + |
| 109 | +psa_status_t secure_storage_its_store_remove(secure_storage_its_uid_t uid) |
| 110 | +{ |
| 111 | + int zms_ret; |
| 112 | + const uint32_t zms_id = zms_id_from(uid); |
| 113 | + |
| 114 | + if (has_forbidden_bits_set(uid)) { |
| 115 | + return PSA_ERROR_INVALID_ARGUMENT; |
| 116 | + } |
| 117 | + |
| 118 | + zms_ret = zms_delete(&s_zms, zms_id); |
| 119 | + LOG_DBG("%s 0x%x. (%d)", zms_ret ? "Failed to delete" : "Deleted", zms_id, zms_ret); |
| 120 | + BUILD_ASSERT(PSA_SUCCESS == 0); |
| 121 | + return zms_ret; |
| 122 | +} |
0 commit comments