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