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