1 /* Copyright (c) 2024 Nordic Semiconductor
2 * SPDX-License-Identifier: Apache-2.0
3 */
4 #include <../library/psa_crypto_driver_wrappers.h>
5 #include <zephyr/secure_storage/its/transform.h>
6 #include <zephyr/secure_storage/its/transform/aead_get.h>
7 #include <zephyr/sys/__assert.h>
8 #include <mbedtls/platform_util.h>
9
psa_aead_crypt(psa_key_usage_t operation,secure_storage_its_uid_t uid,const uint8_t nonce[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE],size_t add_data_len,const void * add_data,size_t input_len,const void * input,size_t output_size,void * output,size_t * output_len)10 static psa_status_t psa_aead_crypt(psa_key_usage_t operation, secure_storage_its_uid_t uid,
11 const uint8_t nonce
12 [static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE],
13 size_t add_data_len, const void *add_data, size_t input_len,
14 const void *input, size_t output_size, void *output,
15 size_t *output_len)
16 {
17 psa_status_t ret;
18 psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
19 uint8_t key[CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE];
20 psa_key_type_t key_type;
21 psa_algorithm_t alg;
22 psa_status_t (*aead_crypt)(const psa_key_attributes_t *attributes, const uint8_t *key,
23 size_t key_size, psa_algorithm_t alg, const uint8_t *nonce,
24 size_t nonce_length, const uint8_t *add_data,
25 size_t add_data_len, const uint8_t *input, size_t input_len,
26 uint8_t *output, size_t output_size, size_t *output_len);
27
28 secure_storage_its_transform_aead_get_scheme(&key_type, &alg);
29
30 psa_set_key_usage_flags(&key_attributes, operation);
31 psa_set_key_lifetime(&key_attributes, PSA_KEY_LIFETIME_VOLATILE);
32 psa_set_key_type(&key_attributes, key_type);
33 psa_set_key_algorithm(&key_attributes, alg);
34 psa_set_key_bits(&key_attributes, sizeof(key) * 8);
35
36 /* Avoid calling psa_aead_*crypt() because that would require importing keys into
37 * PSA Crypto. This gets called from PSA Crypto for storing persistent keys so,
38 * even if using PSA_KEY_LIFETIME_VOLATILE, it would corrupt the global key store
39 * which holds all the active keys in the PSA Crypto core.
40 */
41 aead_crypt = (operation == PSA_KEY_USAGE_ENCRYPT) ?
42 psa_driver_wrapper_aead_encrypt : psa_driver_wrapper_aead_decrypt;
43
44 ret = secure_storage_its_transform_aead_get_key(uid, key);
45 if (ret != PSA_SUCCESS) {
46 return ret;
47 }
48
49 ret = aead_crypt(&key_attributes, key, sizeof(key), alg, nonce,
50 CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE, add_data,
51 add_data_len, input, input_len, output, output_size, output_len);
52
53 mbedtls_platform_zeroize(key, sizeof(key));
54 return ret;
55 }
56
57 enum { CIPHERTEXT_MAX_SIZE
58 = PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(CONFIG_SECURE_STORAGE_ITS_MAX_DATA_SIZE) };
59
60 BUILD_ASSERT(CONFIG_SECURE_STORAGE_ITS_TRANSFORM_OUTPUT_OVERHEAD
61 == CIPHERTEXT_MAX_SIZE - CONFIG_SECURE_STORAGE_ITS_MAX_DATA_SIZE
62 + CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE);
63
64 BUILD_ASSERT(SECURE_STORAGE_ALL_CREATE_FLAGS
65 <= (1 << (8 * sizeof(secure_storage_packed_create_flags_t))) - 1);
66
67 struct stored_entry {
68 secure_storage_packed_create_flags_t create_flags;
69 uint8_t nonce[CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE];
70 uint8_t ciphertext[CIPHERTEXT_MAX_SIZE]; /* Keep last as this is variable in size. */
71 } __packed;
72 BUILD_ASSERT(sizeof(struct stored_entry) == SECURE_STORAGE_ITS_TRANSFORM_MAX_STORED_DATA_SIZE);
73
74 /** @return The length of a `struct stored_entry` whose `ciphertext` is `len` bytes long. */
75 #define STORED_ENTRY_LEN(len) (sizeof(struct stored_entry) - CIPHERTEXT_MAX_SIZE + len)
76
77 struct additional_data {
78 secure_storage_its_uid_t uid;
79 secure_storage_packed_create_flags_t create_flags;
80 } __packed;
81
secure_storage_its_transform_to_store(secure_storage_its_uid_t uid,size_t data_len,const void * data,secure_storage_packed_create_flags_t create_flags,uint8_t stored_data[static SECURE_STORAGE_ITS_TRANSFORM_MAX_STORED_DATA_SIZE],size_t * stored_data_len)82 psa_status_t secure_storage_its_transform_to_store(
83 secure_storage_its_uid_t uid, size_t data_len, const void *data,
84 secure_storage_packed_create_flags_t create_flags,
85 uint8_t stored_data[static SECURE_STORAGE_ITS_TRANSFORM_MAX_STORED_DATA_SIZE],
86 size_t *stored_data_len)
87 {
88 psa_status_t ret;
89 struct stored_entry *stored_entry = (struct stored_entry *)stored_data;
90 const struct additional_data add_data = {.uid = uid, .create_flags = create_flags};
91 size_t ciphertext_len;
92
93 stored_entry->create_flags = create_flags;
94
95 ret = secure_storage_its_transform_aead_get_nonce(stored_entry->nonce);
96 if (ret != PSA_SUCCESS) {
97 return ret;
98 }
99
100 ret = psa_aead_crypt(PSA_KEY_USAGE_ENCRYPT, uid, stored_entry->nonce, sizeof(add_data),
101 &add_data, data_len, data, sizeof(stored_entry->ciphertext),
102 &stored_entry->ciphertext, &ciphertext_len);
103 if (ret == PSA_SUCCESS) {
104 *stored_data_len = STORED_ENTRY_LEN(ciphertext_len);
105 }
106 return ret;
107 }
108
secure_storage_its_transform_from_store(secure_storage_its_uid_t uid,size_t stored_data_len,const uint8_t stored_data[static SECURE_STORAGE_ITS_TRANSFORM_MAX_STORED_DATA_SIZE],size_t data_size,void * data,size_t * data_len,psa_storage_create_flags_t * create_flags)109 psa_status_t secure_storage_its_transform_from_store(
110 secure_storage_its_uid_t uid, size_t stored_data_len,
111 const uint8_t stored_data[static SECURE_STORAGE_ITS_TRANSFORM_MAX_STORED_DATA_SIZE],
112 size_t data_size, void *data, size_t *data_len,
113 psa_storage_create_flags_t *create_flags)
114 {
115 if (stored_data_len < STORED_ENTRY_LEN(0)) {
116 return PSA_ERROR_STORAGE_FAILURE;
117 }
118
119 psa_status_t ret;
120 struct stored_entry *stored_entry = (struct stored_entry *)stored_data;
121 const struct additional_data add_data = {.uid = uid,
122 .create_flags = stored_entry->create_flags};
123 const size_t ciphertext_len = stored_data_len - STORED_ENTRY_LEN(0);
124
125 ret = psa_aead_crypt(PSA_KEY_USAGE_DECRYPT, uid, stored_entry->nonce, sizeof(add_data),
126 &add_data, ciphertext_len, stored_entry->ciphertext, data_size, data,
127 data_len);
128 if (ret == PSA_SUCCESS) {
129 *create_flags = stored_entry->create_flags;
130 }
131 return ret;
132 }
133