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