1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/init.h>
13
14 #include <zephyr/fff.h>
15
16 #include <zephyr/net/wifi_credentials.h>
17
18 #include "wifi_credentials_internal.h"
19 #include "psa/crypto_types.h"
20 #include "psa/crypto_values.h"
21
22 #define SSID1 "test1"
23 #define PSK1 "super secret"
24 #define SECURITY1 WIFI_SECURITY_TYPE_PSK
25 #define BSSID1 "abcdef"
26 #define FLAGS1 WIFI_CREDENTIALS_FLAG_BSSID
27
28 #define SSID2 "test2"
29 #define PSK2 NULL
30 #define SECURITY2 WIFI_SECURITY_TYPE_NONE
31 #define BSSID2 NULL
32 #define FLAGS2 0
33
34 #define WIFI_CREDENTIALS_BACKEND_PSA_KEY_ID_USER_MIN \
35 (PSA_KEY_ID_USER_MIN + CONFIG_WIFI_CREDENTIALS_BACKEND_PSA_OFFSET)
36
37 DEFINE_FFF_GLOBALS;
38
39 K_MUTEX_DEFINE(wifi_credentials_mutex);
40
41 FAKE_VOID_FUNC(wifi_credentials_cache_ssid, size_t, const struct wifi_credentials_header *);
42 FAKE_VALUE_FUNC(psa_status_t, psa_export_key, mbedtls_svc_key_id_t, uint8_t *, size_t, size_t *);
43 FAKE_VALUE_FUNC(psa_status_t, psa_import_key, psa_key_attributes_t *, uint8_t *, size_t,
44 mbedtls_svc_key_id_t *);
45 FAKE_VALUE_FUNC(psa_status_t, psa_destroy_key, mbedtls_svc_key_id_t);
46 FAKE_VOID_FUNC(psa_set_key_id, psa_key_attributes_t *, uint32_t);
47 FAKE_VOID_FUNC(psa_set_key_usage_flags, psa_key_attributes_t *, psa_key_usage_t);
48 FAKE_VOID_FUNC(psa_set_key_lifetime, psa_key_attributes_t *, psa_key_lifetime_t);
49 FAKE_VOID_FUNC(psa_set_key_algorithm, psa_key_attributes_t *, psa_algorithm_t);
50 FAKE_VOID_FUNC(psa_set_key_type, psa_key_attributes_t *, psa_key_type_t);
51 FAKE_VOID_FUNC(psa_set_key_bits, psa_key_attributes_t *, size_t);
52
53 static const struct wifi_credentials_personal example1 = {
54 .header = {
55 .ssid = SSID1,
56 .ssid_len = strlen(SSID1),
57 .type = SECURITY1,
58 .bssid = BSSID1,
59 .flags = FLAGS1,
60 },
61 .password = PSK1,
62 .password_len = strlen(PSK1),
63 };
64
65 static const struct wifi_credentials_personal example2 = {
66 .header = {
67 .ssid = SSID2,
68 .ssid_len = strlen(SSID2),
69 .type = SECURITY2,
70 .flags = FLAGS2,
71 },
72 };
73
74 static size_t idx;
75
custom_psa_export_key(mbedtls_svc_key_id_t key,uint8_t * data,size_t data_size,size_t * data_length)76 psa_status_t custom_psa_export_key(mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size,
77 size_t *data_length)
78 {
79 /* confirm that we read the requested amount of data */
80 *data_length = data_size;
81 return PSA_SUCCESS;
82 }
83
custom_psa_set_key_id(psa_key_attributes_t * attributes,mbedtls_svc_key_id_t key)84 static void custom_psa_set_key_id(psa_key_attributes_t *attributes, mbedtls_svc_key_id_t key)
85 {
86 zassert_equal(idx + WIFI_CREDENTIALS_BACKEND_PSA_KEY_ID_USER_MIN, key, "Key ID mismatch");
87 }
88
custom_psa_set_key_bits(psa_key_attributes_t * attributes,size_t bits)89 void custom_psa_set_key_bits(psa_key_attributes_t *attributes, size_t bits)
90 {
91 zassert_equal(sizeof(struct wifi_credentials_personal) * 8, bits, "Key bits mismatch");
92 }
93
custom_psa_set_key_type(psa_key_attributes_t * attributes,psa_key_type_t type)94 void custom_psa_set_key_type(psa_key_attributes_t *attributes, psa_key_type_t type)
95 {
96 zassert_equal(PSA_KEY_TYPE_RAW_DATA, type, "Key type mismatch");
97 }
98
custom_psa_set_key_algorithm(psa_key_attributes_t * attributes,psa_algorithm_t alg)99 void custom_psa_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg)
100 {
101 zassert_equal(PSA_ALG_NONE, alg, "Key algorithm mismatch");
102 }
103
custom_psa_set_key_lifetime(psa_key_attributes_t * attributes,psa_key_lifetime_t lifetime)104 void custom_psa_set_key_lifetime(psa_key_attributes_t *attributes, psa_key_lifetime_t lifetime)
105 {
106 zassert_equal(PSA_KEY_LIFETIME_PERSISTENT, lifetime, "Key lifetime mismatch");
107 }
108
custom_psa_set_key_usage_flags(psa_key_attributes_t * attributes,psa_key_usage_t usage_flags)109 void custom_psa_set_key_usage_flags(psa_key_attributes_t *attributes, psa_key_usage_t usage_flags)
110 {
111 zassert_equal(PSA_KEY_USAGE_EXPORT, usage_flags, "Key usage flags mismatch");
112 }
113
wifi_credentials_backend_psa_setup(void * _unused)114 static void wifi_credentials_backend_psa_setup(void *_unused)
115 {
116 RESET_FAKE(wifi_credentials_cache_ssid);
117 RESET_FAKE(psa_export_key);
118 RESET_FAKE(psa_import_key);
119 RESET_FAKE(psa_destroy_key);
120 psa_export_key_fake.custom_fake = custom_psa_export_key;
121 psa_set_key_id_fake.custom_fake = custom_psa_set_key_id;
122 psa_set_key_usage_flags_fake.custom_fake = custom_psa_set_key_usage_flags;
123 psa_set_key_lifetime_fake.custom_fake = custom_psa_set_key_lifetime;
124 psa_set_key_algorithm_fake.custom_fake = custom_psa_set_key_algorithm;
125 psa_set_key_type_fake.custom_fake = custom_psa_set_key_type;
126 psa_set_key_bits_fake.custom_fake = custom_psa_set_key_bits;
127 idx = 0;
128 }
129
ZTEST(wifi_credentials_backend_psa,test_init)130 ZTEST(wifi_credentials_backend_psa, test_init)
131 {
132 int ret;
133
134 ret = wifi_credentials_backend_init();
135
136 zassert_equal(0, ret, "Initialization failed");
137 zassert_equal(psa_export_key_fake.call_count, CONFIG_WIFI_CREDENTIALS_MAX_ENTRIES,
138 "Export key call count mismatch");
139 zassert_equal(wifi_credentials_cache_ssid_fake.call_count,
140 CONFIG_WIFI_CREDENTIALS_MAX_ENTRIES, "Cache SSID call count mismatch");
141 }
142
ZTEST(wifi_credentials_backend_psa,test_add)143 ZTEST(wifi_credentials_backend_psa, test_add)
144 {
145 int ret = wifi_credentials_store_entry(idx, &example1,
146 sizeof(struct wifi_credentials_personal));
147
148 zassert_equal(0, ret, "Store entry failed");
149 zassert_equal_ptr(psa_import_key_fake.arg1_val, &example1, "Import key arg1 mismatch");
150 zassert_equal(psa_import_key_fake.arg2_val, sizeof(struct wifi_credentials_personal),
151 "Import key arg2 mismatch");
152
153 idx++;
154
155 ret = wifi_credentials_store_entry(idx, &example2,
156 sizeof(struct wifi_credentials_personal));
157
158 zassert_equal(0, ret, "Store entry failed");
159 zassert_equal_ptr(psa_import_key_fake.arg1_val, &example2, "Import key arg1 mismatch");
160 zassert_equal(psa_import_key_fake.arg2_val, sizeof(struct wifi_credentials_personal),
161 "Import key arg2 mismatch");
162
163 zassert_equal(psa_import_key_fake.call_count, 2, "Import key call count mismatch");
164 zassert_equal(psa_set_key_id_fake.call_count, 2, "Set key ID call count mismatch");
165 zassert_equal(psa_set_key_usage_flags_fake.call_count, 2,
166 "Set key usage flags call count mismatch");
167 zassert_equal(psa_set_key_lifetime_fake.call_count, 2,
168 "Set key lifetime call count mismatch");
169 zassert_equal(psa_set_key_algorithm_fake.call_count, 2,
170 "Set key algorithm call count mismatch");
171 zassert_equal(psa_set_key_type_fake.call_count, 2, "Set key type call count mismatch");
172 zassert_equal(psa_set_key_bits_fake.call_count, 2, "Set key bits call count mismatch");
173 }
174
ZTEST(wifi_credentials_backend_psa,test_get)175 ZTEST(wifi_credentials_backend_psa, test_get)
176 {
177 int ret;
178 psa_key_id_t key_id = idx + WIFI_CREDENTIALS_BACKEND_PSA_KEY_ID_USER_MIN;
179 uint8_t buf[ENTRY_MAX_LEN];
180
181 ret = wifi_credentials_load_entry(idx, buf, ARRAY_SIZE(buf));
182
183 zassert_equal(0, ret, "Load entry failed");
184 zassert_equal(psa_export_key_fake.arg0_val, key_id, "Export key arg0 mismatch");
185 zassert_equal_ptr(psa_export_key_fake.arg1_val, buf, "Export key arg1 mismatch");
186 zassert_equal(psa_export_key_fake.arg2_val, ARRAY_SIZE(buf), "Export key arg2 mismatch");
187
188 idx++;
189 key_id = idx + WIFI_CREDENTIALS_BACKEND_PSA_KEY_ID_USER_MIN;
190
191 ret = wifi_credentials_load_entry(idx, buf, ARRAY_SIZE(buf));
192
193 zassert_equal(0, ret, "Load entry failed");
194 zassert_equal(psa_export_key_fake.arg0_val, key_id, "Export key arg0 mismatch");
195 zassert_equal_ptr(psa_export_key_fake.arg1_val, buf, "Export key arg1 mismatch");
196 zassert_equal(psa_export_key_fake.arg2_val, ARRAY_SIZE(buf), "Export key arg2 mismatch");
197
198 zassert_equal(psa_export_key_fake.call_count, 2, "Export key call count mismatch");
199 }
200
ZTEST(wifi_credentials_backend_psa,test_delete)201 ZTEST(wifi_credentials_backend_psa, test_delete)
202 {
203 int ret;
204
205 ret = wifi_credentials_delete_entry(idx);
206
207 zassert_equal(0, ret, "Delete entry failed");
208 zassert_equal(psa_destroy_key_fake.arg0_val, WIFI_CREDENTIALS_BACKEND_PSA_KEY_ID_USER_MIN,
209 "Destroy key arg0 mismatch");
210
211 idx++;
212
213 ret = wifi_credentials_delete_entry(1);
214
215 zassert_equal(0, ret, "Delete entry failed");
216 zassert_equal(psa_destroy_key_fake.arg0_val,
217 idx + WIFI_CREDENTIALS_BACKEND_PSA_KEY_ID_USER_MIN,
218 "Destroy key arg0 mismatch");
219
220 zassert_equal(psa_destroy_key_fake.call_count, 2, "Destroy key call count mismatch");
221 }
222
223 ZTEST_SUITE(wifi_credentials_backend_psa, NULL, NULL, wifi_credentials_backend_psa_setup, NULL,
224 NULL);
225