1 /* Copyright (c) 2024 Nordic Semiconductor
2 * SPDX-License-Identifier: Apache-2.0
3 */
4 #include <zephyr/secure_storage/its/transform/aead_get.h>
5 #include <zephyr/drivers/hwinfo.h>
6 #include <zephyr/init.h>
7 #include <zephyr/logging/log.h>
8 #include <psa/crypto.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <mbedtls/platform_util.h>
12
13 LOG_MODULE_DECLARE(secure_storage, CONFIG_SECURE_STORAGE_LOG_LEVEL);
14
15 #ifdef CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_SCHEME_AES_GCM
16 #define PSA_KEY_TYPE PSA_KEY_TYPE_AES
17 #define PSA_ALG PSA_ALG_GCM
18 #elif defined(CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_SCHEME_CHACHA20_POLY1305)
19 #define PSA_KEY_TYPE PSA_KEY_TYPE_CHACHA20
20 #define PSA_ALG PSA_ALG_CHACHA20_POLY1305
21 #endif
22 #ifndef CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_SCHEME_CUSTOM
secure_storage_its_transform_aead_get_scheme(psa_key_type_t * key_type,psa_algorithm_t * alg)23 void secure_storage_its_transform_aead_get_scheme(psa_key_type_t *key_type, psa_algorithm_t *alg)
24 {
25 *key_type = PSA_KEY_TYPE;
26 *alg = PSA_ALG;
27 }
28 #endif /* !CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_SCHEME_CUSTOM */
29
30 #ifndef CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER_CUSTOM
31
32 #define SHA256_OUTPUT_SIZE 32
33 BUILD_ASSERT(SHA256_OUTPUT_SIZE == PSA_HASH_LENGTH(PSA_ALG_SHA_256));
34 BUILD_ASSERT(SHA256_OUTPUT_SIZE >= CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE);
35
hash_data_into_key(size_t data_len,const void * data,uint8_t key[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE])36 static psa_status_t hash_data_into_key(
37 size_t data_len, const void *data,
38 uint8_t key[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE])
39 {
40 size_t hash_len;
41
42 #if CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE == SHA256_OUTPUT_SIZE
43 /* Save stack usage and avoid unnecessary memory operations.*/
44 return psa_hash_compute(PSA_ALG_SHA_256, data, data_len, key,
45 CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE, &hash_len);
46 #else
47 uint8_t hash_output[SHA256_OUTPUT_SIZE];
48 const psa_status_t ret = psa_hash_compute(PSA_ALG_SHA_256, data, data_len, hash_output,
49 sizeof(hash_output), &hash_len);
50
51 if (ret == PSA_SUCCESS) {
52 memcpy(key, hash_output, CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE);
53 mbedtls_platform_zeroize(hash_output, sizeof(hash_output));
54 }
55 return ret;
56 #endif
57 }
58
59 #ifdef CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER_DEVICE_ID_HASH
60
61 #define WARNING "Using a potentially insecure PSA ITS encryption key provider."
62
secure_storage_its_transform_aead_get_key(secure_storage_its_uid_t uid,uint8_t key[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE])63 psa_status_t secure_storage_its_transform_aead_get_key(
64 secure_storage_its_uid_t uid,
65 uint8_t key[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE])
66 {
67 psa_status_t ret;
68 ssize_t hwinfo_ret;
69 struct {
70 uint8_t device_id[8];
71 secure_storage_its_uid_t uid; /* acts as a salt */
72 } __packed data;
73
74 hwinfo_ret = hwinfo_get_device_eui64(data.device_id);
75 if (hwinfo_ret != 0) {
76 hwinfo_ret = hwinfo_get_device_id(data.device_id, sizeof(data.device_id));
77 if (hwinfo_ret <= 0) {
78 return PSA_ERROR_HARDWARE_FAILURE;
79 }
80 if (hwinfo_ret < sizeof(data.device_id)) {
81 memset(data.device_id + hwinfo_ret, 0, sizeof(data.device_id) - hwinfo_ret);
82 }
83 }
84 data.uid = uid;
85 ret = hash_data_into_key(sizeof(data), &data, key);
86
87 mbedtls_platform_zeroize(data.device_id, sizeof(data.device_id));
88 return ret;
89 }
90
91 #elif defined(CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER_ENTRY_UID_HASH)
92
93 #define WARNING "Using an insecure PSA ITS encryption key provider."
94
secure_storage_its_transform_aead_get_key(secure_storage_its_uid_t uid,uint8_t key[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE])95 psa_status_t secure_storage_its_transform_aead_get_key(
96 secure_storage_its_uid_t uid,
97 uint8_t key[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_SIZE])
98 {
99 return hash_data_into_key(sizeof(uid), &uid, key);
100 }
101
102 #endif /* CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER */
103
104 #ifndef CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NO_INSECURE_KEY_WARNING
105
warn_insecure_key(void)106 static int warn_insecure_key(void)
107 {
108 printk("WARNING: %s\n", WARNING);
109 LOG_WRN("%s", WARNING);
110 return 0;
111 }
112 SYS_INIT(warn_insecure_key, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
113
114 #endif /* !CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NO_INSECURE_KEY_WARNING */
115
116 #endif /* !CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_KEY_PROVIDER_CUSTOM */
117
118 #ifdef CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_PROVIDER_DEFAULT
119
secure_storage_its_transform_aead_get_nonce(uint8_t nonce[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE])120 psa_status_t secure_storage_its_transform_aead_get_nonce(
121 uint8_t nonce[static CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE])
122 {
123 psa_status_t ret;
124 static uint8_t s_nonce[CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_SIZE];
125 static bool s_nonce_initialized;
126
127 if (!s_nonce_initialized) {
128 ret = psa_generate_random(s_nonce, sizeof(s_nonce));
129 if (ret != PSA_SUCCESS) {
130 return ret;
131 }
132 s_nonce_initialized = true;
133 } else {
134 for (unsigned int i = 0; i != sizeof(s_nonce); ++i) {
135 ++s_nonce[i];
136 if (s_nonce[i] != 0) {
137 break;
138 }
139 }
140 }
141
142 memcpy(nonce, &s_nonce, sizeof(s_nonce));
143 return PSA_SUCCESS;
144 }
145 #endif /* CONFIG_SECURE_STORAGE_ITS_TRANSFORM_AEAD_NONCE_PROVIDER_DEFAULT */
146