1 /*
2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifdef CONFIG_WPA3_SAE
8
9 #include <stdio.h>
10 #include <ctype.h>
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <time.h>
14 #include "unity.h"
15 #include <string.h>
16 #include "utils/common.h"
17 #include "utils/includes.h"
18 #include "crypto/crypto.h"
19 #include "../src/common/sae.h"
20 #include "utils/wpabuf.h"
21
22 typedef struct crypto_bignum crypto_bignum;
23
24
wpabuf_alloc2(size_t len)25 static struct wpabuf *wpabuf_alloc2(size_t len)
26 {
27 struct wpabuf *buf = (struct wpabuf *)os_zalloc(sizeof(struct wpabuf) + len);
28 if (buf == NULL)
29 return NULL;
30 buf->size = len;
31 buf->buf = (u8 *) (buf + 1);
32 return buf;
33 }
34
35 /**
36 * * wpabuf_free - Free a wpabuf
37 * * @buf: wpabuf buffer
38 * */
wpabuf_free2(struct wpabuf * buf)39 void wpabuf_free2(struct wpabuf *buf)
40 {
41 if (buf == NULL)
42 return;
43 os_free(buf);
44 }
45
46
47
48
49 TEST_CASE("Test SAE functionality with ECC group", "[wpa3_sae]")
50 {
51 ESP_LOGI("SAE Test", "### Beginning SAE init and deinit ###");
52 {
53 /* Test init and deinit*/
54 struct sae_data sae;
55 memset(&sae, 0, sizeof(sae));
56 TEST_ASSERT(sae_set_group(&sae, IANA_SECP256R1) == 0);
57 sae_clear_temp_data(&sae);
58 sae_clear_data(&sae);
59
60 }
61 ESP_LOGI("SAE Test", "=========== Complete ============");
62
63 ESP_LOGI("SAE Test", "### Beginning SAE commit msg formation and parsing ###");
64 {
65 /* Test SAE commit msg formation and parsing*/
66 struct sae_data sae;
67 u8 addr1[ETH_ALEN] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11};
68 u8 addr2[ETH_ALEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
69 u8 pwd[] = "ESP32-WPA3";
70 struct wpabuf *buf;
71 int default_groups[] = { IANA_SECP256R1, 0 };
72
73 memset(&sae, 0, sizeof(sae));
74
75 TEST_ASSERT(sae_set_group(&sae, IANA_SECP256R1) == 0);
76
77 TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd, strlen((const char *)pwd), NULL, &sae) == 0);
78
79 buf = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
80
81 TEST_ASSERT( buf != NULL);
82
83 sae_write_commit(&sae, buf, NULL, NULL);// No anti-clogging token
84
85 /* Parsing commit created by self will be detected as reflection attack*/
86 TEST_ASSERT(sae_parse_commit(&sae,
87 wpabuf_mhead(buf), buf->used, NULL, 0, default_groups) == SAE_SILENTLY_DISCARD);
88
89 wpabuf_free2(buf);
90 sae_clear_temp_data(&sae);
91 sae_clear_data(&sae);
92
93 }
94 ESP_LOGI("SAE Test", "=========== Complete ============");
95
96 ESP_LOGI("SAE Test", "### Beginning SAE handshake ###");
97 {
98 /* SAE handshake*/
99 struct sae_data sae1; // STA1 data
100 struct sae_data sae2; // STA2 data
101 u8 addr1[ETH_ALEN] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11};
102 u8 addr2[ETH_ALEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
103 u8 pwd[] = "ESP32-WPA3";
104
105 memset(&sae1, 0, sizeof(sae1));
106 memset(&sae2, 0, sizeof(sae2));
107
108 struct wpabuf *buf1, *buf2, *buf3, *buf4;
109 int default_groups[] = { IANA_SECP256R1, 0 };
110
111 TEST_ASSERT(sae_set_group(&sae1, IANA_SECP256R1) == 0);
112 TEST_ASSERT(sae_set_group(&sae2, IANA_SECP256R1) == 0);
113
114 /* STA1 prepares for commit*/
115 TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd, strlen((const char *)pwd), NULL, &sae1) == 0);
116
117 /* STA2 prepares for commit*/
118 TEST_ASSERT(sae_prepare_commit(addr2, addr1, pwd, strlen((const char *)pwd), NULL, &sae2) == 0);
119
120 /* STA1 creates commit msg buffer*/
121 buf1 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
122 TEST_ASSERT( buf1 != NULL);
123 sae_write_commit(&sae1, buf1, NULL, NULL);// No anti-clogging token
124 ESP_LOG_BUFFER_HEXDUMP("SAE: Commit1", wpabuf_mhead_u8(buf1), wpabuf_len(buf1), ESP_LOG_INFO);
125
126
127 /* STA2 creates commit msg buffer*/
128 buf2 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
129 TEST_ASSERT( buf2 != NULL);
130 sae_write_commit(&sae2, buf2, NULL, NULL);// No anti-clogging token
131 ESP_LOG_BUFFER_HEXDUMP("SAE: Commit2", wpabuf_mhead_u8(buf2), wpabuf_len(buf2), ESP_LOG_INFO);
132
133 sae1.state = SAE_COMMITTED;
134 sae2.state = SAE_COMMITTED;
135
136 /* STA1 parses STA2 commit*/
137 TEST_ASSERT(sae_parse_commit(&sae1,
138 wpabuf_mhead(buf2), buf2->used, NULL, 0, default_groups) == 0);
139
140 /* STA2 parses STA1 commit*/
141 TEST_ASSERT(sae_parse_commit(&sae2,
142 wpabuf_mhead(buf1), buf1->used, NULL, 0, default_groups) == 0);
143
144 /* STA1 processes commit*/
145 TEST_ASSERT(sae_process_commit(&sae1) == 0);
146
147 /* STA2 processes commit*/
148 TEST_ASSERT(sae_process_commit(&sae2) == 0);
149
150 /* STA1 creates confirm msg buffer*/
151 buf3 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
152 TEST_ASSERT( buf3 != NULL);
153 sae_write_confirm(&sae1, buf3);
154 ESP_LOG_BUFFER_HEXDUMP("SAE: Confirm1", wpabuf_mhead_u8(buf3), wpabuf_len(buf3), ESP_LOG_INFO);
155
156 /* STA2 creates confirm msg buffer*/
157 buf4 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
158 TEST_ASSERT( buf3 != NULL);
159 sae_write_confirm(&sae2, buf4);
160 ESP_LOG_BUFFER_HEXDUMP("SAE: Confirm2", wpabuf_mhead_u8(buf4), wpabuf_len(buf4), ESP_LOG_INFO);
161
162 /* STA1 checks confirm from STA2*/
163 TEST_ASSERT(sae_check_confirm(&sae1, wpabuf_mhead(buf4), buf4->used) == 0);
164
165 /* STA2 checks confirm from STA1*/
166 TEST_ASSERT(sae_check_confirm(&sae2, wpabuf_mhead(buf3), buf3->used) == 0);
167
168 ESP_LOG_BUFFER_HEXDUMP("SAE: PMK1", sae1.pmk, SAE_PMK_LEN, ESP_LOG_INFO);
169 ESP_LOG_BUFFER_HEXDUMP("SAE: PMK2", sae2.pmk, SAE_PMK_LEN, ESP_LOG_INFO);
170
171 wpabuf_free2(buf1);
172 wpabuf_free2(buf2);
173 wpabuf_free2(buf3);
174 wpabuf_free2(buf4);
175 sae_clear_temp_data(&sae1);
176 sae_clear_temp_data(&sae2);
177 sae_clear_data(&sae1);
178 sae_clear_data(&sae2);
179
180 }
181 ESP_LOGI("SAE Test", "=========== Complete ============");
182
183 ESP_LOGI("SAE Test", "### SAE handshake negative testcase. ###");
184 {
185 /* SAE handshake failure when different passwords are used.*/
186 struct sae_data sae1; // STA1 data
187 struct sae_data sae2; // STA2 data
188 u8 addr1[ETH_ALEN] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x11};
189 u8 addr2[ETH_ALEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
190 u8 pwd1[] = "abcd1234";
191 u8 pwd2[] = "wxyz5678";
192
193 memset(&sae1, 0, sizeof(sae1));
194 memset(&sae2, 0, sizeof(sae2));
195
196 struct wpabuf *buf1, *buf2, *buf3, *buf4;
197 int default_groups[] = { IANA_SECP256R1, 0 };
198
199 TEST_ASSERT(sae_set_group(&sae1, IANA_SECP256R1) == 0);
200 TEST_ASSERT(sae_set_group(&sae2, IANA_SECP256R1) == 0);
201
202 /* STA1 prepares for commit*/
203 TEST_ASSERT(sae_prepare_commit(addr1, addr2, pwd1, strlen((const char *)pwd1), NULL, &sae1) == 0);
204
205 /* STA2 prepares for commit*/
206 TEST_ASSERT(sae_prepare_commit(addr2, addr1, pwd2, strlen((const char *)pwd2), NULL, &sae2) == 0);
207
208 /* STA1 creates commit msg buffer*/
209 buf1 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
210 TEST_ASSERT( buf1 != NULL);
211 sae_write_commit(&sae1, buf1, NULL, NULL);// No anti-clogging token
212
213 /* STA2 creates commit msg buffer*/
214 buf2 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
215 TEST_ASSERT( buf2 != NULL);
216 sae_write_commit(&sae2, buf2, NULL, NULL);// No anti-clogging token
217
218 sae1.state = SAE_COMMITTED;
219 sae2.state = SAE_COMMITTED;
220
221 /* STA1 parses STA2 commit*/
222 TEST_ASSERT(sae_parse_commit(&sae1,
223 wpabuf_mhead(buf2), buf2->used, NULL, 0, default_groups) == 0);
224
225 /* STA2 parses STA1 commit*/
226 TEST_ASSERT(sae_parse_commit(&sae2,
227 wpabuf_mhead(buf1), buf1->used, NULL, 0, default_groups) == 0);
228
229 /* STA1 processes commit*/
230 TEST_ASSERT(sae_process_commit(&sae1) == 0);
231
232 /* STA2 processes commit*/
233 TEST_ASSERT(sae_process_commit(&sae2) == 0);
234
235 /* STA1 creates confirm msg buffer*/
236 buf3 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
237 TEST_ASSERT( buf3 != NULL);
238 sae_write_confirm(&sae1, buf3);
239
240 /* STA2 creates confirm msg buffer*/
241 buf4 = wpabuf_alloc2(SAE_COMMIT_MAX_LEN);
242 TEST_ASSERT( buf3 != NULL);
243 sae_write_confirm(&sae2, buf4);
244
245 /* STA1 checks confirm from STA2 and the check fails*/
246 TEST_ASSERT(sae_check_confirm(&sae1, wpabuf_mhead(buf4), buf4->used) != 0);
247
248 /* STA2 checks confirm from STA1 and the check fails*/
249 TEST_ASSERT(sae_check_confirm(&sae2, wpabuf_mhead(buf3), buf3->used) != 0);
250
251 wpabuf_free2(buf1);
252 wpabuf_free2(buf2);
253 wpabuf_free2(buf3);
254 wpabuf_free2(buf4);
255 sae_clear_temp_data(&sae1);
256 sae_clear_temp_data(&sae2);
257 sae_clear_data(&sae1);
258 sae_clear_data(&sae2);
259
260 }
261 ESP_LOGI("SAE Test", "=========== Complete ============");
262
263 }
264
265 #endif /* CONFIG_WPA3_SAE */
266