|
1 /* |
|
2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: EAP and WLAN authentication protocols. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // This is enumeration of EAPOL source code. |
|
20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
21 #undef EAP_FILE_NUMBER_ENUM |
|
22 #define EAP_FILE_NUMBER_ENUM 50 |
|
23 #undef EAP_FILE_NUMBER_DATE |
|
24 #define EAP_FILE_NUMBER_DATE 1127594498 |
|
25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
26 |
|
27 |
|
28 |
|
29 #include "eap_am_memory.h" |
|
30 #include "eapol_key_state.h" |
|
31 #include "eapol_key_header.h" |
|
32 #include "eap_crypto_api.h" |
|
33 #include "abs_eap_am_mutex.h" |
|
34 #include "eap_state_notification.h" |
|
35 #include "eap_automatic_variable.h" |
|
36 #include "eapol_rsna_key_data_gtk_header.h" |
|
37 #include "abs_eapol_core.h" |
|
38 #include "abs_eapol_key_state.h" |
|
39 #include "eap_core_retransmission.h" |
|
40 #include "eapol_rsna_key_data_payloads.h" |
|
41 #include "eap_buffer.h" |
|
42 #include "eapol_session_key.h" |
|
43 #include "eapol_key_state_string.h" |
|
44 |
|
45 //-------------------------------------------------- |
|
46 |
|
47 // |
|
48 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::save_parameters( |
|
49 const eapol_key_authentication_type_e authentication_type, |
|
50 const eap_variable_data_c * const authenticator_RSNA_IE, |
|
51 const eap_variable_data_c * const supplicant_RSNA_IE, |
|
52 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, |
|
53 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher) |
|
54 { |
|
55 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
56 |
|
57 eap_status_e status(eap_status_process_general_error); |
|
58 |
|
59 m_authentication_type = authentication_type; |
|
60 m_eapol_pairwise_cipher = eapol_pairwise_cipher; |
|
61 m_eapol_group_cipher = eapol_group_cipher; |
|
62 |
|
63 eapol_key_state_string_c state_string; |
|
64 EAP_TRACE_DEBUG( |
|
65 m_am_tools, |
|
66 TRACE_FLAGS_DEFAULT, |
|
67 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::save_parameters(): m_authentication_type=%s, ") |
|
68 EAPL("m_eapol_pairwise_cipher=%d, m_eapol_group_cipher=%d.\n"), |
|
69 (m_is_client == true) ? "client": "server", |
|
70 state_string.get_eapol_key_authentication_type_string(m_authentication_type), |
|
71 m_eapol_pairwise_cipher, |
|
72 m_eapol_group_cipher)); |
|
73 |
|
74 |
|
75 if (get_is_RSNA() == true |
|
76 || get_is_WPA() == true |
|
77 #if defined(EAP_USE_WPXM) |
|
78 || get_is_WPXM() == true |
|
79 #endif //#if defined(EAP_USE_WPXM) |
|
80 ) |
|
81 { |
|
82 if (authenticator_RSNA_IE->get_is_valid_data() == true) |
|
83 { |
|
84 status = m_authenticator_RSNA_IE.set_copy_of_buffer( |
|
85 authenticator_RSNA_IE); |
|
86 if (status != eap_status_ok) |
|
87 { |
|
88 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
89 return EAP_STATUS_RETURN(m_am_tools, status); |
|
90 } |
|
91 |
|
92 EAP_TRACE_DATA_DEBUG( |
|
93 m_am_tools, |
|
94 TRACE_FLAGS_DEFAULT, |
|
95 (EAPL("Authenticator RSN IE"), |
|
96 get_authenticator_RSNA_IE()->get_data( |
|
97 get_authenticator_RSNA_IE()->get_data_length()), |
|
98 get_authenticator_RSNA_IE()->get_data_length())); |
|
99 } |
|
100 else |
|
101 { |
|
102 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
103 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
104 } |
|
105 |
|
106 if (supplicant_RSNA_IE->get_is_valid_data() == true) |
|
107 { |
|
108 status = m_supplicant_RSNA_IE.set_copy_of_buffer( |
|
109 supplicant_RSNA_IE); |
|
110 if (status != eap_status_ok) |
|
111 { |
|
112 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
113 return EAP_STATUS_RETURN(m_am_tools, status); |
|
114 } |
|
115 |
|
116 EAP_TRACE_DATA_DEBUG( |
|
117 m_am_tools, |
|
118 TRACE_FLAGS_DEFAULT, |
|
119 (EAPL("Supplicant RSN IE"), |
|
120 get_supplicant_RSNA_IE()->get_data( |
|
121 get_supplicant_RSNA_IE()->get_data_length()), |
|
122 get_supplicant_RSNA_IE()->get_data_length())); |
|
123 } |
|
124 else |
|
125 { |
|
126 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
127 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
128 } |
|
129 } |
|
130 |
|
131 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
132 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
133 } |
|
134 |
|
135 //-------------------------------------------------- |
|
136 |
|
137 // |
|
138 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize( |
|
139 const eap_am_network_id_c * const receive_network_id, |
|
140 const eapol_key_authentication_type_e authentication_type, |
|
141 const eap_variable_data_c * const authenticator_RSNA_IE, |
|
142 const eap_variable_data_c * const supplicant_RSNA_IE, |
|
143 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, |
|
144 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, |
|
145 const eap_variable_data_c * const pre_shared_key) |
|
146 { |
|
147 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
148 |
|
149 eap_status_e status(eap_status_process_general_error); |
|
150 |
|
151 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
152 |
|
153 status = save_parameters( |
|
154 authentication_type, |
|
155 authenticator_RSNA_IE, |
|
156 supplicant_RSNA_IE, |
|
157 eapol_pairwise_cipher, |
|
158 eapol_group_cipher); |
|
159 if (status != eap_status_ok) |
|
160 { |
|
161 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
162 return EAP_STATUS_RETURN(m_am_tools, status); |
|
163 } |
|
164 |
|
165 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
166 |
|
167 if ((m_authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
168 || m_authentication_type == eapol_key_authentication_type_WPA_PSK) |
|
169 && (pre_shared_key == 0 |
|
170 || pre_shared_key->get_is_valid_data() == false |
|
171 || pre_shared_key->get_data_length() < EAPOL_RSNA_PMK_LENGTH_BYTES)) |
|
172 { |
|
173 if (pre_shared_key != 0) |
|
174 { |
|
175 EAP_TRACE_ERROR( |
|
176 m_am_tools, |
|
177 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
178 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pre shared key 0x%08x, PSK length %d.\n"), |
|
179 pre_shared_key->get_data(pre_shared_key->get_data_length()), |
|
180 pre_shared_key->get_data_length())); |
|
181 } |
|
182 |
|
183 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
184 return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); |
|
185 } |
|
186 else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
187 && (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) |
|
188 { |
|
189 EAP_TRACE_ERROR( |
|
190 m_am_tools, |
|
191 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
192 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pairwise cipher suite %d.\n"), |
|
193 m_eapol_pairwise_cipher)); |
|
194 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
195 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); |
|
196 } |
|
197 else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
198 && (m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) |
|
199 { |
|
200 EAP_TRACE_ERROR( |
|
201 m_am_tools, |
|
202 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
203 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal group cipher suite %d.\n"), |
|
204 m_eapol_group_cipher)); |
|
205 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
206 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); |
|
207 } |
|
208 else if (m_authentication_type == eapol_key_authentication_type_WPA_EAP |
|
209 && (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) |
|
210 { |
|
211 EAP_TRACE_ERROR( |
|
212 m_am_tools, |
|
213 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
214 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pairwise cipher suite %d.\n"), |
|
215 m_eapol_pairwise_cipher)); |
|
216 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
217 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); |
|
218 } |
|
219 else if (m_authentication_type == eapol_key_authentication_type_WPA_EAP |
|
220 && (m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)) |
|
221 { |
|
222 EAP_TRACE_ERROR( |
|
223 m_am_tools, |
|
224 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
225 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal group cipher suite %d.\n"), |
|
226 m_eapol_group_cipher)); |
|
227 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
228 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); |
|
229 } |
|
230 else if (m_authentication_type == eapol_key_authentication_type_802_1X) |
|
231 { |
|
232 // OK, cannot check the pairwise and group ciphers. |
|
233 // AP will tell these in the EAPOL RC4 Key message. |
|
234 } |
|
235 |
|
236 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
237 |
|
238 status = set_mac_addresses(receive_network_id); |
|
239 if (status != eap_status_ok) |
|
240 { |
|
241 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
242 return EAP_STATUS_RETURN(m_am_tools, status); |
|
243 } |
|
244 |
|
245 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
246 |
|
247 set_eapol_key_state(eapol_key_state_none); |
|
248 m_eapol_key_handshake_type = eapol_key_handshake_type_none; |
|
249 |
|
250 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
251 |
|
252 if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
253 || m_authentication_type == eapol_key_authentication_type_WPA_PSK) |
|
254 { |
|
255 // Here we swap the addresses. |
|
256 eap_am_network_id_c send_network_id( |
|
257 m_am_tools, |
|
258 receive_network_id->get_destination_id(), |
|
259 receive_network_id->get_source_id(), |
|
260 receive_network_id->get_type()); |
|
261 if (send_network_id.get_is_valid_data() == false) |
|
262 { |
|
263 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
264 } |
|
265 |
|
266 status = set_pairwise_PMK( |
|
267 pre_shared_key, |
|
268 &send_network_id); |
|
269 if (status != eap_status_ok) |
|
270 { |
|
271 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
272 return EAP_STATUS_RETURN(m_am_tools, status); |
|
273 } |
|
274 } |
|
275 |
|
276 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
277 { |
|
278 m_is_associated = true; |
|
279 |
|
280 EAP_TRACE_DEBUG( |
|
281 m_am_tools, |
|
282 TRACE_FLAGS_DEFAULT, |
|
283 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::initialize(): m_is_associated=%s.\n"), |
|
284 (m_is_client == true) ? "client": "server", |
|
285 (m_is_associated == true) ? "true": "false")); |
|
286 } |
|
287 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
288 |
|
289 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
290 } |
|
291 |
|
292 //-------------------------------------------------- |
|
293 |
|
294 #if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
295 |
|
296 // |
|
297 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize( |
|
298 const eap_am_network_id_c * const receive_network_id, |
|
299 const eapol_key_authentication_type_e authentication_type) |
|
300 { |
|
301 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
302 |
|
303 eap_status_e status(eap_status_process_general_error); |
|
304 |
|
305 reset(); |
|
306 |
|
307 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
308 |
|
309 m_authentication_type = authentication_type; |
|
310 |
|
311 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
312 |
|
313 status = set_mac_addresses(receive_network_id); |
|
314 if (status != eap_status_ok) |
|
315 { |
|
316 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
317 return EAP_STATUS_RETURN(m_am_tools, status); |
|
318 } |
|
319 |
|
320 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
321 |
|
322 set_eapol_key_state(eapol_key_state_none); |
|
323 m_eapol_key_handshake_type = eapol_key_handshake_type_none; |
|
324 |
|
325 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
326 |
|
327 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
328 // Creates SNonce. This is done here in early phase of authentication. |
|
329 // This will reduce the CPU load when time critical first message |
|
330 // of 4-Way handshake is processed. |
|
331 status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES); |
|
332 if (status != eap_status_ok) |
|
333 { |
|
334 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
335 return EAP_STATUS_RETURN(m_am_tools, status); |
|
336 } |
|
337 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
338 |
|
339 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
340 |
|
341 |
|
342 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
343 } |
|
344 |
|
345 #endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
346 |
|
347 //-------------------------------------------------- |
|
348 |
|
349 // |
|
350 eap_status_e eapol_key_state_c::set_mac_addresses( |
|
351 const eap_am_network_id_c * const receive_network_id) |
|
352 { |
|
353 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
354 |
|
355 eap_status_e status(eap_status_process_general_error); |
|
356 |
|
357 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
358 |
|
359 { |
|
360 const eap_variable_data_c * authenticator_MAC_address = 0; |
|
361 const eap_variable_data_c * supplicant_MAC_address = 0; |
|
362 |
|
363 if (m_is_client == true) |
|
364 { |
|
365 authenticator_MAC_address = receive_network_id->get_source_id(); |
|
366 supplicant_MAC_address = receive_network_id->get_destination_id(); |
|
367 } |
|
368 else |
|
369 { |
|
370 authenticator_MAC_address = receive_network_id->get_destination_id(); |
|
371 supplicant_MAC_address = receive_network_id->get_source_id(); |
|
372 } |
|
373 |
|
374 |
|
375 status = m_authenticator_MAC_address.set_copy_of_buffer( |
|
376 authenticator_MAC_address); |
|
377 if (status != eap_status_ok) |
|
378 { |
|
379 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
380 return EAP_STATUS_RETURN(m_am_tools, status); |
|
381 } |
|
382 |
|
383 status = m_supplicant_MAC_address.set_copy_of_buffer( |
|
384 supplicant_MAC_address); |
|
385 if (status != eap_status_ok) |
|
386 { |
|
387 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
388 return EAP_STATUS_RETURN(m_am_tools, status); |
|
389 } |
|
390 } |
|
391 |
|
392 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
393 |
|
394 { |
|
395 const eap_variable_data_c * destination = 0; |
|
396 const eap_variable_data_c * source = 0; |
|
397 |
|
398 if (m_is_client == true) |
|
399 { |
|
400 destination = &m_authenticator_MAC_address; |
|
401 source = &m_supplicant_MAC_address; |
|
402 } |
|
403 else |
|
404 { |
|
405 destination = &m_supplicant_MAC_address; |
|
406 source = &m_authenticator_MAC_address; |
|
407 } |
|
408 |
|
409 |
|
410 eap_am_network_id_c send_network_id(m_am_tools, |
|
411 source, |
|
412 destination, |
|
413 eapol_ethernet_type_pae); |
|
414 |
|
415 status = m_send_network_id.set_copy_of_network_id(&send_network_id); |
|
416 if (status != eap_status_ok) |
|
417 { |
|
418 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
419 return EAP_STATUS_RETURN(m_am_tools, status); |
|
420 } |
|
421 } |
|
422 |
|
423 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
424 |
|
425 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
426 return EAP_STATUS_RETURN(m_am_tools, status); |
|
427 } |
|
428 |
|
429 //-------------------------------------------------- |
|
430 |
|
431 // |
|
432 EAP_FUNC_EXPORT eapol_key_state_c::~eapol_key_state_c() |
|
433 { |
|
434 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
435 |
|
436 EAP_TRACE_DEBUG( |
|
437 m_am_tools, |
|
438 TRACE_FLAGS_DEFAULT, |
|
439 (EAPL("EAPOL_KEY: eapol_key_state_c::~eapol_key_state_c(): this = 0x%08x => 0x%08x.\n"), |
|
440 this, |
|
441 dynamic_cast<abs_eap_base_timer_c *>(this))); |
|
442 |
|
443 EAP_ASSERT(m_shutdown_was_called == true); |
|
444 |
|
445 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
446 } |
|
447 |
|
448 //-------------------------------------------------- |
|
449 |
|
450 // |
|
451 EAP_FUNC_EXPORT eapol_key_state_c::eapol_key_state_c( |
|
452 abs_eap_am_tools_c * const tools, |
|
453 abs_eapol_key_state_c * const key_state_partner, |
|
454 abs_eapol_core_c * const eapol_partner, |
|
455 const bool is_client_when_true, |
|
456 const eap_am_network_id_c * const receive_network_id, |
|
457 const eapol_key_authentication_type_e authentication_type, |
|
458 const eap_variable_data_c * const authenticator_RSNA_IE, |
|
459 const eap_variable_data_c * const supplicant_RSNA_IE, |
|
460 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, |
|
461 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, |
|
462 const eap_variable_data_c * const pre_shared_key) |
|
463 : m_am_tools(tools) |
|
464 , m_key_state_partner(key_state_partner) |
|
465 , m_eapol_partner(eapol_partner) |
|
466 , m_send_network_id(tools) |
|
467 , m_authenticator_RSNA_IE(tools) |
|
468 , m_unicast_cipher_suite_RSNA_IE(tools) |
|
469 , m_supplicant_RSNA_IE(tools) |
|
470 , m_received_PMKID(tools) |
|
471 , m_supplicant_MAC_address(tools) |
|
472 , m_authenticator_MAC_address(tools) |
|
473 , m_ANonce(tools) |
|
474 , m_SNonce(tools) |
|
475 , m_EAPOL_key_IV(tools) |
|
476 , m_pairwise_PMK_WPXK3(tools) |
|
477 , m_PMKID(tools) |
|
478 , m_transient_PTK(tools) |
|
479 , m_confirmation_KCK(tools) |
|
480 , m_encryption_KEK(tools) |
|
481 , m_temporal_TK(tools) |
|
482 , m_group_GTK(tools) |
|
483 #if defined(EAP_USE_WPXM) |
|
484 , m_WPXM_WPXK1(tools) |
|
485 , m_WPXM_WPXK2(tools) |
|
486 , m_WPXM_WPXC(eapol_key_constant_wpxm_initial_wpxc_counter_value) |
|
487 #endif //#if defined(EAP_USE_WPXM) |
|
488 , m_group_GTK_ID(0u) |
|
489 , m_group_GTK_Tx_bit(false) |
|
490 , m_eapol_header_offset(0ul) |
|
491 , m_MTU(0ul) |
|
492 , m_trailer_length(0ul) |
|
493 , m_retransmission(0) |
|
494 , m_retransmission_time(EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT) |
|
495 , m_retransmission_counter(EAPOL_KEY_STATE_RETRANSMISSION_COUNTER) |
|
496 , m_handshake_timeout(EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT) |
|
497 #if defined(EAP_USE_WPXM) |
|
498 , m_wpxm_reassociate_timeout(EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT) |
|
499 , m_EAPOL_WPXM_key_descriptor_type(eapol_key_descriptor_type_none) |
|
500 #endif //#if defined(EAP_USE_WPXM) |
|
501 , m_authentication_type(authentication_type) |
|
502 , m_eapol_pairwise_cipher(eapol_pairwise_cipher) |
|
503 , m_eapol_group_cipher(eapol_group_cipher) |
|
504 , m_eapol_key_state(eapol_key_state_none) |
|
505 , m_eapol_key_handshake_type(eapol_key_handshake_type_none) |
|
506 , m_create_key_failure(eapol_key_state_none) |
|
507 , m_pmksa_caching_timeout(EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT) |
|
508 , m_key_reply_counter(0ul) |
|
509 , m_client_send_key_reply_counter(0ul) |
|
510 , m_is_client(is_client_when_true) |
|
511 , m_is_valid(false) |
|
512 , m_marked_removed(false) |
|
513 , m_shutdown_was_called(false) |
|
514 , m_allow_missing_PMKID_in_message_1(false) |
|
515 , m_skip_PMKID_key_data_in_message_1(false) |
|
516 , m_allow_non_zero_mic_and_reserved_in_message_1(false) |
|
517 , m_indicate_pmkid_to_lower_layer(false) |
|
518 , m_handshake_timeout_set(false) |
|
519 , m_server_TEST_group_key_update(false) |
|
520 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
521 , m_is_associated(false) |
|
522 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
523 { |
|
524 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
525 |
|
526 EAP_UNREFERENCED_PARAMETER(receive_network_id); |
|
527 EAP_UNREFERENCED_PARAMETER(authenticator_RSNA_IE); |
|
528 EAP_UNREFERENCED_PARAMETER(supplicant_RSNA_IE); |
|
529 EAP_UNREFERENCED_PARAMETER(pre_shared_key); |
|
530 |
|
531 EAP_TRACE_DEBUG( |
|
532 m_am_tools, |
|
533 TRACE_FLAGS_DEFAULT, |
|
534 (EAPL("eapol_key_state_c::eapol_key_state_c(1): %s\n"), |
|
535 (m_is_client == true) ? "client": "server")); |
|
536 |
|
537 for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) |
|
538 { |
|
539 m_received_802_1x_keys[key_type] = false; |
|
540 } |
|
541 |
|
542 |
|
543 set_is_valid(); |
|
544 |
|
545 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
546 } |
|
547 |
|
548 //-------------------------------------------------- |
|
549 |
|
550 // |
|
551 EAP_FUNC_EXPORT eapol_key_state_c::eapol_key_state_c( |
|
552 abs_eap_am_tools_c * const tools, |
|
553 abs_eapol_key_state_c * const key_state_partner, |
|
554 abs_eapol_core_c * const eapol_partner, |
|
555 const bool is_client_when_true, |
|
556 const eap_am_network_id_c * const /* receive_network_id */, |
|
557 const eapol_key_authentication_type_e authentication_type) |
|
558 : m_am_tools(tools) |
|
559 , m_key_state_partner(key_state_partner) |
|
560 , m_eapol_partner(eapol_partner) |
|
561 , m_send_network_id(tools) |
|
562 , m_authenticator_RSNA_IE(tools) |
|
563 , m_unicast_cipher_suite_RSNA_IE(tools) |
|
564 , m_supplicant_RSNA_IE(tools) |
|
565 , m_received_PMKID(tools) |
|
566 , m_supplicant_MAC_address(tools) |
|
567 , m_authenticator_MAC_address(tools) |
|
568 , m_ANonce(tools) |
|
569 , m_SNonce(tools) |
|
570 , m_EAPOL_key_IV(tools) |
|
571 , m_pairwise_PMK_WPXK3(tools) |
|
572 , m_PMKID(tools) |
|
573 , m_transient_PTK(tools) |
|
574 , m_confirmation_KCK(tools) |
|
575 , m_encryption_KEK(tools) |
|
576 , m_temporal_TK(tools) |
|
577 , m_group_GTK(tools) |
|
578 #if defined(EAP_USE_WPXM) |
|
579 , m_WPXM_WPXK1(tools) |
|
580 , m_WPXM_WPXK2(tools) |
|
581 , m_WPXM_WPXC(eapol_key_constant_wpxm_initial_wpxc_counter_value) |
|
582 #endif //#if defined(EAP_USE_WPXM) |
|
583 , m_group_GTK_ID(0u) |
|
584 , m_group_GTK_Tx_bit(false) |
|
585 , m_eapol_header_offset(0ul) |
|
586 , m_MTU(0ul) |
|
587 , m_trailer_length(0ul) |
|
588 , m_retransmission(0) |
|
589 , m_retransmission_time(EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT) |
|
590 , m_retransmission_counter(EAPOL_KEY_STATE_RETRANSMISSION_COUNTER) |
|
591 , m_handshake_timeout(EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT) |
|
592 #if defined(EAP_USE_WPXM) |
|
593 , m_wpxm_reassociate_timeout(EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT) |
|
594 , m_EAPOL_WPXM_key_descriptor_type(eapol_key_descriptor_type_none) |
|
595 #endif //#if defined(EAP_USE_WPXM) |
|
596 , m_authentication_type(authentication_type) |
|
597 , m_eapol_pairwise_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) |
|
598 , m_eapol_group_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none) |
|
599 , m_eapol_key_state(eapol_key_state_none) |
|
600 , m_eapol_key_handshake_type(eapol_key_handshake_type_none) |
|
601 , m_create_key_failure(eapol_key_state_none) |
|
602 , m_pmksa_caching_timeout(EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT) |
|
603 , m_key_reply_counter(0ul) |
|
604 , m_client_send_key_reply_counter(0ul) |
|
605 , m_is_client(is_client_when_true) |
|
606 , m_is_valid(false) |
|
607 , m_marked_removed(false) |
|
608 , m_shutdown_was_called(false) |
|
609 , m_allow_missing_PMKID_in_message_1(false) |
|
610 , m_skip_PMKID_key_data_in_message_1(false) |
|
611 , m_allow_non_zero_mic_and_reserved_in_message_1(false) |
|
612 , m_indicate_pmkid_to_lower_layer(false) |
|
613 , m_handshake_timeout_set(false) |
|
614 , m_server_TEST_group_key_update(false) |
|
615 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
616 , m_is_associated(false) |
|
617 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
618 { |
|
619 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
620 |
|
621 EAP_TRACE_DEBUG( |
|
622 m_am_tools, |
|
623 TRACE_FLAGS_DEFAULT, |
|
624 (EAPL("eapol_key_state_c::eapol_key_state_c(2): %s\n"), |
|
625 (m_is_client == true) ? "client": "server")); |
|
626 |
|
627 for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) |
|
628 { |
|
629 m_received_802_1x_keys[key_type] = false; |
|
630 } |
|
631 |
|
632 set_is_valid(); |
|
633 |
|
634 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
635 } |
|
636 |
|
637 //-------------------------------------------------- |
|
638 |
|
639 // |
|
640 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::configure() |
|
641 { |
|
642 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
643 |
|
644 EAP_TRACE_DEBUG( |
|
645 m_am_tools, |
|
646 TRACE_FLAGS_DEFAULT, |
|
647 (EAPL("eapol_key_state_c::configure(): %s\n"), |
|
648 (m_is_client == true) ? "client": "server")); |
|
649 |
|
650 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
651 |
|
652 m_eapol_header_offset = m_eapol_partner->get_header_offset(&m_MTU, &m_trailer_length); |
|
653 |
|
654 for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) |
|
655 { |
|
656 m_received_802_1x_keys[key_type] = false; |
|
657 } |
|
658 |
|
659 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
660 |
|
661 if (m_is_client == false) |
|
662 { |
|
663 eap_variable_data_c retransmission_time(m_am_tools); |
|
664 |
|
665 eap_status_e status = m_key_state_partner->read_configure( |
|
666 cf_str_EAPOL_key_state_retransmission_time.get_field(), |
|
667 &retransmission_time); |
|
668 if (status == eap_status_ok |
|
669 && retransmission_time.get_is_valid_data() == true) |
|
670 { |
|
671 u32_t *retransmission_time_value = reinterpret_cast<u32_t *>( |
|
672 retransmission_time.get_data(sizeof(u32_t))); |
|
673 if (retransmission_time_value != 0) |
|
674 { |
|
675 m_retransmission_time = *retransmission_time_value; |
|
676 } |
|
677 else |
|
678 { |
|
679 m_retransmission_time = EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT; |
|
680 } |
|
681 } |
|
682 else |
|
683 { |
|
684 m_retransmission_time = EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT; |
|
685 } |
|
686 } |
|
687 |
|
688 if (m_is_client == false) |
|
689 { |
|
690 eap_variable_data_c retransmission_counter(m_am_tools); |
|
691 |
|
692 eap_status_e status = m_key_state_partner->read_configure( |
|
693 cf_str_EAPOL_key_state_retransmission_counter.get_field(), |
|
694 &retransmission_counter); |
|
695 if (status == eap_status_ok |
|
696 && retransmission_counter.get_is_valid_data() == true) |
|
697 { |
|
698 u32_t *retransmission_counter_value = reinterpret_cast<u32_t *>( |
|
699 retransmission_counter.get_data(sizeof(u32_t))); |
|
700 if (retransmission_counter_value != 0) |
|
701 { |
|
702 m_retransmission_counter = *retransmission_counter_value; |
|
703 } |
|
704 } |
|
705 } |
|
706 |
|
707 |
|
708 { |
|
709 eap_variable_data_c session_timeout(m_am_tools); |
|
710 |
|
711 eap_status_e status = m_key_state_partner->read_configure( |
|
712 cf_str_EAPOL_key_state_handshake_timeout.get_field(), |
|
713 &session_timeout); |
|
714 if (status == eap_status_ok |
|
715 && session_timeout.get_is_valid_data() == true) |
|
716 { |
|
717 u32_t *handler_timeout = reinterpret_cast<u32_t *>( |
|
718 session_timeout.get_data(sizeof(u32_t))); |
|
719 if (handler_timeout != 0) |
|
720 { |
|
721 m_handshake_timeout = *handler_timeout; |
|
722 } |
|
723 } |
|
724 } |
|
725 |
|
726 |
|
727 #if defined(EAP_USE_WPXM) |
|
728 |
|
729 { |
|
730 eap_variable_data_c wpxm_reassociation_timeout(m_am_tools); |
|
731 |
|
732 eap_status_e status = m_key_state_partner->read_configure( |
|
733 cf_str_EAPOL_key_state_wpxm_reassociate_timeout.get_field(), |
|
734 &wpxm_reassociation_timeout); |
|
735 if (status == eap_status_ok |
|
736 && wpxm_reassociation_timeout.get_is_valid_data() == true) |
|
737 { |
|
738 u32_t *handler_timeout = reinterpret_cast<u32_t *>( |
|
739 wpxm_reassociation_timeout.get_data(sizeof(u32_t))); |
|
740 if (handler_timeout != 0) |
|
741 { |
|
742 m_wpxm_reassociate_timeout = *handler_timeout; |
|
743 } |
|
744 } |
|
745 } |
|
746 |
|
747 |
|
748 if (m_is_client == false) |
|
749 { |
|
750 eap_variable_data_c EAPOL_WPXM_type(m_am_tools); |
|
751 |
|
752 eap_status_e status = m_key_state_partner->read_configure( |
|
753 cf_str_EAPOL_WPXM_type.get_field(), |
|
754 &EAPOL_WPXM_type); |
|
755 if (status == eap_status_ok |
|
756 && EAPOL_WPXM_type.get_is_valid() == true |
|
757 && EAPOL_WPXM_type.get_data_length() > 0ul |
|
758 && EAPOL_WPXM_type.get_data( |
|
759 EAPOL_WPXM_type.get_data_length()) != 0) |
|
760 { |
|
761 if (cf_str_EAPOL_key_authentication_type_config_value_RSNA_EAP |
|
762 .get_field()->compare( |
|
763 m_am_tools, |
|
764 &EAPOL_WPXM_type) == true) |
|
765 { |
|
766 m_EAPOL_WPXM_key_descriptor_type = eapol_key_descriptor_type_RSNA; |
|
767 } |
|
768 else if (cf_str_EAPOL_key_authentication_type_config_value_WPA_EAP |
|
769 .get_field()->compare( |
|
770 m_am_tools, |
|
771 &EAPOL_WPXM_type) == true) |
|
772 { |
|
773 m_EAPOL_WPXM_key_descriptor_type = eapol_key_descriptor_type_WPA; |
|
774 } |
|
775 } |
|
776 } |
|
777 |
|
778 #endif //#if defined(EAP_USE_WPXM) |
|
779 |
|
780 |
|
781 { |
|
782 eap_variable_data_c pmksa_caching_timeout(m_am_tools); |
|
783 |
|
784 eap_status_e status = m_key_state_partner->read_configure( |
|
785 cf_str_EAPOL_key_state_pmksa_caching_timeout.get_field(), |
|
786 &pmksa_caching_timeout); |
|
787 if (status == eap_status_ok |
|
788 && pmksa_caching_timeout.get_is_valid_data() == true) |
|
789 { |
|
790 u32_t *handler_timeout = reinterpret_cast<u32_t *>( |
|
791 pmksa_caching_timeout.get_data(sizeof(u32_t))); |
|
792 if (handler_timeout != 0) |
|
793 { |
|
794 m_pmksa_caching_timeout = *handler_timeout; |
|
795 } |
|
796 } |
|
797 } |
|
798 |
|
799 |
|
800 if (m_is_client == true) |
|
801 { |
|
802 { |
|
803 eap_variable_data_c allow_missing_PMKID_in_message_1(m_am_tools); |
|
804 |
|
805 eap_status_e status = m_key_state_partner->read_configure( |
|
806 cf_str_EAPOL_key_state_allow_missing_PMKID_in_message_1.get_field(), |
|
807 &allow_missing_PMKID_in_message_1); |
|
808 if (status == eap_status_ok |
|
809 && allow_missing_PMKID_in_message_1.get_is_valid_data() == true) |
|
810 { |
|
811 u32_t *flag = reinterpret_cast<u32_t *>( |
|
812 allow_missing_PMKID_in_message_1.get_data(sizeof(u32_t))); |
|
813 if (flag != 0 |
|
814 && *flag != 0) |
|
815 { |
|
816 m_allow_missing_PMKID_in_message_1 = true; |
|
817 } |
|
818 } |
|
819 } |
|
820 |
|
821 { |
|
822 eap_variable_data_c allow_non_zero_mic_in_message_1(m_am_tools); |
|
823 |
|
824 eap_status_e status = m_key_state_partner->read_configure( |
|
825 cf_str_EAPOL_key_state_allow_non_zero_mic_in_message_1.get_field(), |
|
826 &allow_non_zero_mic_in_message_1); |
|
827 if (status == eap_status_ok |
|
828 && allow_non_zero_mic_in_message_1.get_is_valid_data() == true) |
|
829 { |
|
830 u32_t *flag = reinterpret_cast<u32_t *>( |
|
831 allow_non_zero_mic_in_message_1.get_data(sizeof(u32_t))); |
|
832 if (flag != 0 |
|
833 && *flag != 0) |
|
834 { |
|
835 m_allow_non_zero_mic_and_reserved_in_message_1 = true; |
|
836 } |
|
837 } |
|
838 } |
|
839 |
|
840 { |
|
841 eap_variable_data_c indicate_pmkid_to_lower_layer(m_am_tools); |
|
842 |
|
843 eap_status_e status = m_key_state_partner->read_configure( |
|
844 cf_str_EAPOL_key_state_indicate_pmkid_to_lower_layer.get_field(), |
|
845 &indicate_pmkid_to_lower_layer); |
|
846 if (status == eap_status_ok |
|
847 && indicate_pmkid_to_lower_layer.get_is_valid_data() == true) |
|
848 { |
|
849 u32_t *flag = reinterpret_cast<u32_t *>( |
|
850 indicate_pmkid_to_lower_layer.get_data(sizeof(u32_t))); |
|
851 if (flag != 0 |
|
852 && *flag != 0) |
|
853 { |
|
854 m_indicate_pmkid_to_lower_layer = true; |
|
855 } |
|
856 } |
|
857 } |
|
858 |
|
859 } |
|
860 |
|
861 if (m_is_client == false) |
|
862 { |
|
863 { |
|
864 eap_variable_data_c skip_PMKID_key_data_in_message_1(m_am_tools); |
|
865 |
|
866 eap_status_e status = m_key_state_partner->read_configure( |
|
867 cf_str_EAPOL_key_state_skip_PMKID_key_data_in_message_1.get_field(), |
|
868 &skip_PMKID_key_data_in_message_1); |
|
869 if (status == eap_status_ok |
|
870 && skip_PMKID_key_data_in_message_1.get_is_valid_data() == true) |
|
871 { |
|
872 u32_t *flag = reinterpret_cast<u32_t *>( |
|
873 skip_PMKID_key_data_in_message_1.get_data(sizeof(u32_t))); |
|
874 if (flag != 0 |
|
875 && *flag != 0) |
|
876 { |
|
877 m_skip_PMKID_key_data_in_message_1 = true; |
|
878 } |
|
879 } |
|
880 } |
|
881 |
|
882 { |
|
883 eap_variable_data_c EAPOL_key_state_TEST_group_key_update(m_am_tools); |
|
884 |
|
885 eap_status_e status = m_key_state_partner->read_configure( |
|
886 cf_str_EAPOL_key_state_TEST_group_key_update.get_field(), |
|
887 &EAPOL_key_state_TEST_group_key_update); |
|
888 if (status == eap_status_ok |
|
889 && EAPOL_key_state_TEST_group_key_update.get_is_valid_data() == true) |
|
890 { |
|
891 u32_t *flag = reinterpret_cast<u32_t *>( |
|
892 EAPOL_key_state_TEST_group_key_update.get_data(sizeof(u32_t))); |
|
893 if (flag != 0 |
|
894 && *flag != 0) |
|
895 { |
|
896 m_server_TEST_group_key_update = true; |
|
897 } |
|
898 } |
|
899 } |
|
900 |
|
901 } |
|
902 |
|
903 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
904 |
|
905 eap_status_e status(eap_status_ok); |
|
906 |
|
907 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
908 |
|
909 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
910 return EAP_STATUS_RETURN(m_am_tools, status); |
|
911 } |
|
912 |
|
913 //-------------------------------------------------- |
|
914 |
|
915 void eapol_key_state_c::send_error_notification(const eap_status_e error) |
|
916 { |
|
917 // Notifies the lower level of an authentication error. |
|
918 eap_state_notification_c notification( |
|
919 m_am_tools, |
|
920 &m_send_network_id, |
|
921 m_is_client, |
|
922 eap_state_notification_generic, |
|
923 eap_protocol_layer_general, |
|
924 eapol_key_handshake_type_none, |
|
925 eap_state_none, |
|
926 eap_general_state_authentication_error, |
|
927 0, |
|
928 false); |
|
929 |
|
930 notification.set_authentication_error(error); |
|
931 |
|
932 m_key_state_partner->state_notification(¬ification); |
|
933 } |
|
934 |
|
935 //-------------------------------------------------- |
|
936 |
|
937 // |
|
938 eap_status_e eapol_key_state_c::set_reassociation_parameters( |
|
939 const eap_variable_data_c * const pairwise_PMK_WPXK3, |
|
940 const eap_variable_data_c * const PMKID, |
|
941 const eap_variable_data_c * const transient_PTK, |
|
942 const eap_variable_data_c * const confirmation_KCK, |
|
943 const eap_variable_data_c * const encryption_KEK, |
|
944 const eap_variable_data_c * const temporal_TK, |
|
945 const eap_variable_data_c * const WPXM_WPXK1, |
|
946 const eap_variable_data_c * const WPXM_WPXK2, |
|
947 const u32_t WPXM_WPXC, |
|
948 const eapol_key_handshake_type_e eapol_key_handshake_type, |
|
949 const eapol_key_authentication_type_e authentication_type |
|
950 ) |
|
951 { |
|
952 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
953 |
|
954 eapol_key_state_string_c state_string; |
|
955 EAP_TRACE_DEBUG( |
|
956 m_am_tools, |
|
957 TRACE_FLAGS_DEFAULT, |
|
958 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_reassociation_parameters(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
959 (m_is_client == true) ? "client": "server", |
|
960 this, |
|
961 get_eapol_key_state(), |
|
962 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
963 m_authentication_type, |
|
964 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
965 |
|
966 eap_status_e status = m_pairwise_PMK_WPXK3.set_copy_of_buffer(pairwise_PMK_WPXK3); |
|
967 if (status != eap_status_ok) |
|
968 { |
|
969 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
970 return EAP_STATUS_RETURN(m_am_tools, status); |
|
971 } |
|
972 |
|
973 status = m_PMKID.set_copy_of_buffer(PMKID); |
|
974 if (status != eap_status_ok) |
|
975 { |
|
976 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
977 return EAP_STATUS_RETURN(m_am_tools, status); |
|
978 } |
|
979 |
|
980 status = m_transient_PTK.set_copy_of_buffer(transient_PTK); |
|
981 if (status != eap_status_ok) |
|
982 { |
|
983 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
984 return EAP_STATUS_RETURN(m_am_tools, status); |
|
985 } |
|
986 |
|
987 status = m_confirmation_KCK.set_copy_of_buffer(confirmation_KCK); |
|
988 if (status != eap_status_ok) |
|
989 { |
|
990 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
991 return EAP_STATUS_RETURN(m_am_tools, status); |
|
992 } |
|
993 |
|
994 status = m_encryption_KEK.set_copy_of_buffer(encryption_KEK); |
|
995 if (status != eap_status_ok) |
|
996 { |
|
997 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
998 return EAP_STATUS_RETURN(m_am_tools, status); |
|
999 } |
|
1000 |
|
1001 status = m_temporal_TK.set_copy_of_buffer(temporal_TK); |
|
1002 if (status != eap_status_ok) |
|
1003 { |
|
1004 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1005 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1006 } |
|
1007 |
|
1008 #if defined(EAP_USE_WPXM) |
|
1009 status = m_WPXM_WPXK1.set_copy_of_buffer(WPXM_WPXK1); |
|
1010 if (status != eap_status_ok) |
|
1011 { |
|
1012 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1013 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1014 } |
|
1015 |
|
1016 status = m_WPXM_WPXK2.set_copy_of_buffer(WPXM_WPXK2); |
|
1017 if (status != eap_status_ok) |
|
1018 { |
|
1019 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1020 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1021 } |
|
1022 |
|
1023 m_WPXM_WPXC = WPXM_WPXC; |
|
1024 |
|
1025 EAP_TRACE_DEBUG( |
|
1026 m_am_tools, |
|
1027 TRACE_FLAGS_DEFAULT, |
|
1028 (EAPL("EAPOL_KEY: eapol_key_state_c::set_reassociation_parameters(): ") |
|
1029 EAPL("Set m_WPXM_WPXC=%d.\n"), |
|
1030 m_WPXM_WPXC)); |
|
1031 |
|
1032 |
|
1033 m_eapol_key_handshake_type = eapol_key_handshake_type; |
|
1034 m_authentication_type = authentication_type; |
|
1035 #else |
|
1036 EAP_UNREFERENCED_PARAMETER(WPXM_WPXK1); |
|
1037 EAP_UNREFERENCED_PARAMETER(WPXM_WPXK2); |
|
1038 EAP_UNREFERENCED_PARAMETER(WPXM_WPXC); |
|
1039 #endif //#if defined(EAP_USE_WPXM) |
|
1040 |
|
1041 set_eapol_key_state(eapol_key_state_preauthenticated); |
|
1042 |
|
1043 EAP_TRACE_DEBUG( |
|
1044 m_am_tools, |
|
1045 TRACE_FLAGS_DEFAULT, |
|
1046 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_reassociation_parameters(): m_authentication_type=%s, ") |
|
1047 EAPL("m_eapol_pairwise_cipher=%d, m_eapol_group_cipher=%d.\n"), |
|
1048 (m_is_client == true) ? "client": "server", |
|
1049 state_string.get_eapol_key_authentication_type_string(m_authentication_type), |
|
1050 m_eapol_pairwise_cipher, |
|
1051 m_eapol_group_cipher)); |
|
1052 |
|
1053 |
|
1054 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1055 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1056 } |
|
1057 |
|
1058 //-------------------------------------------------- |
|
1059 |
|
1060 // |
|
1061 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::started_eap_authentication() |
|
1062 { |
|
1063 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1064 |
|
1065 EAP_TRACE_DEBUG( |
|
1066 m_am_tools, |
|
1067 TRACE_FLAGS_DEFAULT, |
|
1068 (EAPL("eapol_key_state_c::started_eap_authentication(): %s\n"), |
|
1069 (m_is_client == true) ? "client": "server")); |
|
1070 |
|
1071 (void) cancel_handshake_timeout(); |
|
1072 (void) cancel_reassociate_timeout(); |
|
1073 (void) cancel_pmksa_caching_timeout(); |
|
1074 (void) cancel_4_way_handshake_start_timeout(); |
|
1075 |
|
1076 |
|
1077 { |
|
1078 // Indicates lower layers the EAP authentication is running. |
|
1079 eap_state_notification_c * notification = new eap_state_notification_c( |
|
1080 m_am_tools, |
|
1081 &m_send_network_id, |
|
1082 m_is_client, |
|
1083 eap_state_notification_generic, |
|
1084 eap_protocol_layer_eapol_key, |
|
1085 eapol_key_handshake_type_none, |
|
1086 eapol_key_state_eap_authentication_running, |
|
1087 eapol_key_state_eap_authentication_running, |
|
1088 0ul, |
|
1089 false); |
|
1090 if (notification == 0) |
|
1091 { |
|
1092 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1093 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1094 } |
|
1095 m_key_state_partner->state_notification(notification); |
|
1096 |
|
1097 delete notification; |
|
1098 } |
|
1099 |
|
1100 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1101 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1102 } |
|
1103 |
|
1104 //-------------------------------------------------- |
|
1105 |
|
1106 // |
|
1107 EAP_FUNC_EXPORT eapol_key_state_c *eapol_key_state_c::copy(const eap_am_network_id_c * const receive_network_id) |
|
1108 { |
|
1109 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1110 |
|
1111 eapol_key_state_c * const new_state = new eapol_key_state_c( |
|
1112 m_am_tools, |
|
1113 m_key_state_partner, |
|
1114 m_eapol_partner, |
|
1115 m_is_client, |
|
1116 receive_network_id, |
|
1117 m_authentication_type, |
|
1118 &m_authenticator_RSNA_IE, |
|
1119 &m_supplicant_RSNA_IE, |
|
1120 m_eapol_pairwise_cipher, |
|
1121 m_eapol_group_cipher, |
|
1122 &m_pairwise_PMK_WPXK3); |
|
1123 |
|
1124 if (new_state == 0) |
|
1125 { |
|
1126 (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1127 return 0; |
|
1128 } |
|
1129 |
|
1130 if (new_state->get_is_valid() == false) |
|
1131 { |
|
1132 new_state->shutdown(); |
|
1133 delete new_state; |
|
1134 (void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1135 return 0; |
|
1136 } |
|
1137 |
|
1138 eap_status_e status = new_state->configure(); |
|
1139 if (status != eap_status_ok) |
|
1140 { |
|
1141 new_state->shutdown(); |
|
1142 delete new_state; |
|
1143 (void) EAP_STATUS_RETURN(m_am_tools, status); |
|
1144 return 0; |
|
1145 } |
|
1146 |
|
1147 |
|
1148 #if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
1149 |
|
1150 status = new_state->initialize( |
|
1151 receive_network_id, |
|
1152 m_authentication_type); |
|
1153 if (status != eap_status_ok) |
|
1154 { |
|
1155 new_state->shutdown(); |
|
1156 delete new_state; |
|
1157 (void) EAP_STATUS_RETURN(m_am_tools, status); |
|
1158 return 0; |
|
1159 } |
|
1160 |
|
1161 #endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
1162 |
|
1163 |
|
1164 eapol_key_handshake_type_e eapol_key_handshake_type(m_eapol_key_handshake_type); |
|
1165 |
|
1166 eapol_key_authentication_type_e authentication_type(m_authentication_type); |
|
1167 |
|
1168 #if defined(EAP_USE_WPXM) |
|
1169 if (authentication_type == eapol_key_authentication_type_WPXM) |
|
1170 { |
|
1171 eapol_key_handshake_type = eapol_key_handshake_type_WPXM_reassociation; |
|
1172 } |
|
1173 #endif //#if defined(EAP_USE_WPXM) |
|
1174 |
|
1175 |
|
1176 status = new_state->set_reassociation_parameters( |
|
1177 &m_pairwise_PMK_WPXK3, |
|
1178 &m_PMKID, |
|
1179 &m_transient_PTK, |
|
1180 &m_confirmation_KCK, |
|
1181 &m_encryption_KEK, |
|
1182 &m_temporal_TK, |
|
1183 #if defined(EAP_USE_WPXM) |
|
1184 &m_WPXM_WPXK1, |
|
1185 &m_WPXM_WPXK2, |
|
1186 m_WPXM_WPXC, |
|
1187 #else |
|
1188 0, |
|
1189 0, |
|
1190 0ul, |
|
1191 #endif //#if defined(EAP_USE_WPXM) |
|
1192 eapol_key_handshake_type, |
|
1193 authentication_type |
|
1194 ); |
|
1195 if (status != eap_status_ok) |
|
1196 { |
|
1197 new_state->shutdown(); |
|
1198 delete new_state; |
|
1199 (void) EAP_STATUS_RETURN(m_am_tools, status); |
|
1200 return 0; |
|
1201 } |
|
1202 |
|
1203 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1204 return new_state; |
|
1205 } |
|
1206 |
|
1207 //-------------------------------------------------- |
|
1208 |
|
1209 // |
|
1210 eap_status_e eapol_key_state_c::handshake_failure_notification() |
|
1211 { |
|
1212 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1213 |
|
1214 eapol_key_state_string_c eapol_key_state_string; |
|
1215 |
|
1216 EAP_TRACE_DEBUG( |
|
1217 m_am_tools, |
|
1218 TRACE_FLAGS_DEFAULT, |
|
1219 (EAPL("eapol_key_state_c::handshake_failure_notification(): %s, m_eapol_key_handshake_type=%s, get_eapol_key_state()=%s\n"), |
|
1220 (m_is_client == true) ? "client": "server", |
|
1221 eapol_key_state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type), |
|
1222 eapol_key_state_string.get_eapol_key_state_string(get_eapol_key_state()))); |
|
1223 |
|
1224 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
1225 |
|
1226 if (m_eapol_key_handshake_type == eapol_key_handshake_type_4_way_handshake) |
|
1227 { |
|
1228 if (get_eapol_key_state() == eapol_key_state_preauthenticated) |
|
1229 { |
|
1230 // Do not notify lower layer. |
|
1231 EAP_TRACE_ALWAYS( |
|
1232 m_am_tools, |
|
1233 TRACE_FLAGS_DEFAULT, |
|
1234 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Does not notify pre-authenticated state.\n"), |
|
1235 (m_is_client == true ? "client": "server"))); |
|
1236 } |
|
1237 else if (get_eapol_key_state() == eapol_key_state_none) |
|
1238 { |
|
1239 EAP_TRACE_ALWAYS( |
|
1240 m_am_tools, |
|
1241 TRACE_FLAGS_DEFAULT, |
|
1242 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"), |
|
1243 (m_is_client == true ? "client": "server"))); |
|
1244 } |
|
1245 else if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull) |
|
1246 { |
|
1247 // This is notification to eapol_core_c object. |
|
1248 // 4-Way Handshake terminated unsuccessfully. |
|
1249 eap_state_notification_c notification( |
|
1250 m_am_tools, |
|
1251 &m_send_network_id, |
|
1252 m_is_client, |
|
1253 eap_state_notification_generic, |
|
1254 eap_protocol_layer_eapol_key, |
|
1255 eapol_key_handshake_type_4_way_handshake, |
|
1256 eapol_key_state_4_way_handshake_failed, |
|
1257 eapol_key_state_802_11i_authentication_terminated_unsuccessfull, |
|
1258 0ul, |
|
1259 false); |
|
1260 |
|
1261 notification.set_authentication_error(eap_status_authentication_failure); |
|
1262 |
|
1263 m_key_state_partner->state_notification(¬ification); |
|
1264 |
|
1265 set_eapol_key_state(eapol_key_state_4_way_handshake_failed); |
|
1266 |
|
1267 EAP_TRACE_ALWAYS( |
|
1268 m_am_tools, |
|
1269 TRACE_FLAGS_DEFAULT, |
|
1270 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): 4-Way Handshake FAILED\n"), |
|
1271 (m_is_client == true ? "client": "server"))); |
|
1272 } |
|
1273 } |
|
1274 else if (m_eapol_key_handshake_type == eapol_key_handshake_type_group_key_handshake) |
|
1275 { |
|
1276 if (get_eapol_key_state() == eapol_key_state_preauthenticated) |
|
1277 { |
|
1278 // Do not notify lower layer. |
|
1279 EAP_TRACE_ALWAYS( |
|
1280 m_am_tools, |
|
1281 TRACE_FLAGS_DEFAULT, |
|
1282 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Does not notify pre-authenticated state.\n"), |
|
1283 (m_is_client == true ? "client": "server"))); |
|
1284 } |
|
1285 else if (get_eapol_key_state() == eapol_key_state_none) |
|
1286 { |
|
1287 EAP_TRACE_ALWAYS( |
|
1288 m_am_tools, |
|
1289 TRACE_FLAGS_DEFAULT, |
|
1290 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"), |
|
1291 (m_is_client == true ? "client": "server"))); |
|
1292 } |
|
1293 else if (get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull) |
|
1294 { |
|
1295 // This is notification to eapol_core_c object. |
|
1296 // Group Key Handshake terminated unsuccessfully. |
|
1297 eap_state_notification_c notification( |
|
1298 m_am_tools, |
|
1299 &m_send_network_id, |
|
1300 m_is_client, |
|
1301 eap_state_notification_generic, |
|
1302 eap_protocol_layer_eapol_key, |
|
1303 eapol_key_handshake_type_group_key_handshake, |
|
1304 eapol_key_state_group_key_handshake_failed, |
|
1305 eapol_key_state_802_11i_authentication_terminated_unsuccessfull, |
|
1306 0ul, |
|
1307 false); |
|
1308 |
|
1309 notification.set_authentication_error(eap_status_authentication_failure); |
|
1310 |
|
1311 m_key_state_partner->state_notification(¬ification); |
|
1312 |
|
1313 set_eapol_key_state(eapol_key_state_4_way_handshake_failed); |
|
1314 |
|
1315 EAP_TRACE_ALWAYS( |
|
1316 m_am_tools, |
|
1317 TRACE_FLAGS_DEFAULT, |
|
1318 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Group Key Handshake FAILED\n"), |
|
1319 (m_is_client == true ? "client": "server"))); |
|
1320 } |
|
1321 } |
|
1322 else if (m_eapol_key_handshake_type == eapol_key_handshake_type_none) |
|
1323 { |
|
1324 EAP_TRACE_ALWAYS( |
|
1325 m_am_tools, |
|
1326 TRACE_FLAGS_DEFAULT, |
|
1327 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"), |
|
1328 (m_is_client == true ? "client": "server"))); |
|
1329 } |
|
1330 else |
|
1331 { |
|
1332 EAP_UNREFERENCED_PARAMETER(eapol_key_state_string); |
|
1333 |
|
1334 set_eapol_key_state(eapol_key_state_4_way_handshake_failed); |
|
1335 |
|
1336 EAP_TRACE_ALWAYS( |
|
1337 m_am_tools, |
|
1338 TRACE_FLAGS_DEFAULT, |
|
1339 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unknown Handshake FAILED\n"), |
|
1340 (m_is_client == true ? "client": "server"))); |
|
1341 } |
|
1342 |
|
1343 |
|
1344 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1345 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1346 } |
|
1347 |
|
1348 //-------------------------------------------------- |
|
1349 |
|
1350 // |
|
1351 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::shutdown() |
|
1352 { |
|
1353 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1354 |
|
1355 EAP_TRACE_DEBUG( |
|
1356 m_am_tools, |
|
1357 TRACE_FLAGS_DEFAULT, |
|
1358 (EAPL("eapol_key_state_c::shutdown(): %s\n"), |
|
1359 (m_is_client == true) ? "client": "server")); |
|
1360 |
|
1361 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
1362 |
|
1363 if (m_shutdown_was_called == true) |
|
1364 { |
|
1365 EAP_TRACE_DEBUG( |
|
1366 m_am_tools, |
|
1367 TRACE_FLAGS_DEFAULT, |
|
1368 (EAPL("eapol_key_state_c::shutdown(): Already called.\n"))); |
|
1369 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1370 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1371 } |
|
1372 m_shutdown_was_called = true; |
|
1373 |
|
1374 // This will cancel all timers of this object. |
|
1375 cancel_retransmission(); |
|
1376 cancel_handshake_timeout(); |
|
1377 cancel_pmksa_caching_timeout(); |
|
1378 cancel_reassociate_timeout(); |
|
1379 cancel_4_way_handshake_start_timeout(); |
|
1380 |
|
1381 eap_status_e status = handshake_failure_notification(); |
|
1382 |
|
1383 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1384 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1385 } |
|
1386 |
|
1387 //-------------------------------------------------- |
|
1388 |
|
1389 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::set_s_nonce( |
|
1390 const eap_variable_data_c * const s_nonce) |
|
1391 { |
|
1392 eap_status_e status = m_SNonce.set_copy_of_buffer(s_nonce); |
|
1393 |
|
1394 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1395 } |
|
1396 |
|
1397 //-------------------------------------------------- |
|
1398 |
|
1399 // |
|
1400 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::check_pmksa_cache( |
|
1401 const eapol_key_authentication_type_e selected_eapol_key_authentication_type, |
|
1402 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, |
|
1403 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite) |
|
1404 { |
|
1405 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1406 |
|
1407 EAP_TRACE_DEBUG( |
|
1408 m_am_tools, |
|
1409 TRACE_FLAGS_DEFAULT, |
|
1410 (EAPL("eapol_key_state_c::check_pmksa_cache(): %s\n"), |
|
1411 (m_is_client == true) ? "client": "server")); |
|
1412 |
|
1413 eap_status_e status = eap_status_ok; |
|
1414 |
|
1415 eapol_key_state_string_c state_string; |
|
1416 EAP_TRACE_DEBUG( |
|
1417 m_am_tools, |
|
1418 TRACE_FLAGS_DEFAULT, |
|
1419 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::check_pmksa_cache(): this = 0x%08x, state %d=%s, selected_eapol_key_authentication_type %d=%s, m_authentication_type %d=%s.\n"), |
|
1420 (m_is_client == true) ? "client": "server", |
|
1421 this, |
|
1422 get_eapol_key_state(), |
|
1423 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
1424 selected_eapol_key_authentication_type, |
|
1425 state_string.get_eapol_key_authentication_type_string(selected_eapol_key_authentication_type), |
|
1426 m_authentication_type, |
|
1427 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
1428 |
|
1429 |
|
1430 if (selected_eapol_key_authentication_type != eapol_key_authentication_type_RSNA_EAP |
|
1431 && selected_eapol_key_authentication_type != eapol_key_authentication_type_RSNA_PSK |
|
1432 && selected_eapol_key_authentication_type != eapol_key_authentication_type_WPXM) |
|
1433 { |
|
1434 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); |
|
1435 } |
|
1436 else if (selected_eapol_key_authentication_type != m_authentication_type |
|
1437 || pairwise_key_cipher_suite != m_eapol_pairwise_cipher |
|
1438 || group_key_cipher_suite != m_eapol_group_cipher) |
|
1439 { |
|
1440 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite); |
|
1441 } |
|
1442 |
|
1443 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1444 } |
|
1445 |
|
1446 //-------------------------------------------------- |
|
1447 |
|
1448 // |
|
1449 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize_preauthentication( |
|
1450 const eap_am_network_id_c * const receive_network_id, |
|
1451 const eapol_key_authentication_type_e authentication_type) |
|
1452 { |
|
1453 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1454 |
|
1455 eapol_key_state_string_c state_string; |
|
1456 EAP_TRACE_DEBUG( |
|
1457 m_am_tools, |
|
1458 TRACE_FLAGS_DEFAULT, |
|
1459 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::initialize_preauthentication(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
1460 (m_is_client == true) ? "client": "server", |
|
1461 this, |
|
1462 get_eapol_key_state(), |
|
1463 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
1464 m_authentication_type, |
|
1465 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
1466 |
|
1467 eap_status_e status(eap_status_process_general_error); |
|
1468 |
|
1469 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
1470 |
|
1471 if (m_authentication_type != authentication_type) |
|
1472 { |
|
1473 // Illegal authentication type, must be the same as previously used. |
|
1474 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1475 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1476 } |
|
1477 |
|
1478 if (m_authentication_type == eapol_key_authentication_type_none |
|
1479 || m_authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
1480 || m_authentication_type == eapol_key_authentication_type_WPA_PSK |
|
1481 || m_authentication_type == eapol_key_authentication_type_802_1X) |
|
1482 { |
|
1483 // Illegal authentication type. |
|
1484 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1485 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1486 } |
|
1487 |
|
1488 set_eapol_key_state(eapol_key_state_none); |
|
1489 m_eapol_key_handshake_type = eapol_key_handshake_type_none; |
|
1490 |
|
1491 reset(); |
|
1492 |
|
1493 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
1494 |
|
1495 status = set_mac_addresses(receive_network_id); |
|
1496 if (status != eap_status_ok) |
|
1497 { |
|
1498 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1499 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1500 } |
|
1501 |
|
1502 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
1503 |
|
1504 set_eapol_key_state(eapol_key_state_none); |
|
1505 m_eapol_key_handshake_type = eapol_key_handshake_type_none; |
|
1506 |
|
1507 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1508 } |
|
1509 |
|
1510 //-------------------------------------------------- |
|
1511 |
|
1512 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::read_reassociation_parameters( |
|
1513 const eap_am_network_id_c * const /* receive_network_id */, ///< source includes remote address, destination includes local address. |
|
1514 const eapol_key_authentication_type_e required_authentication_type, |
|
1515 eap_variable_data_c * const PMKID, |
|
1516 const eap_variable_data_c * const received_WPA_ie, |
|
1517 const eap_variable_data_c * const sent_WPA_ie) |
|
1518 { |
|
1519 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1520 |
|
1521 eapol_key_state_string_c state_string; |
|
1522 EAP_TRACE_DEBUG( |
|
1523 m_am_tools, |
|
1524 TRACE_FLAGS_DEFAULT, |
|
1525 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::read_reassociation_parameters(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
1526 (m_is_client == true) ? "client": "server", |
|
1527 this, |
|
1528 get_eapol_key_state(), |
|
1529 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
1530 m_authentication_type, |
|
1531 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
1532 |
|
1533 |
|
1534 (void) cancel_pmksa_caching_timeout(); |
|
1535 (void) cancel_handshake_timeout(); |
|
1536 (void) cancel_reassociate_timeout(); |
|
1537 (void) cancel_4_way_handshake_start_timeout(); |
|
1538 |
|
1539 eap_status_e status(eap_status_process_general_error); |
|
1540 |
|
1541 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
1542 |
|
1543 if (received_WPA_ie != 0 |
|
1544 && received_WPA_ie->get_is_valid_data() == true) |
|
1545 { |
|
1546 status = m_authenticator_RSNA_IE.set_copy_of_buffer(received_WPA_ie); |
|
1547 if (status != eap_status_ok) |
|
1548 { |
|
1549 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1550 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1551 } |
|
1552 } |
|
1553 |
|
1554 if (sent_WPA_ie != 0 |
|
1555 && sent_WPA_ie->get_is_valid_data() == true) |
|
1556 { |
|
1557 status = m_supplicant_RSNA_IE.set_copy_of_buffer(sent_WPA_ie); |
|
1558 if (status != eap_status_ok) |
|
1559 { |
|
1560 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1561 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1562 } |
|
1563 } |
|
1564 |
|
1565 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
1566 |
|
1567 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
1568 // Creates SNonce. This is done here in early phase of authentication. |
|
1569 // This will reduce the CPU load when time critical first message |
|
1570 // of 4-Way handshake is processed. |
|
1571 status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES); |
|
1572 if (status != eap_status_ok) |
|
1573 { |
|
1574 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1575 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1576 } |
|
1577 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
1578 |
|
1579 status = init_handshake_timeout(m_handshake_timeout); |
|
1580 if (status != eap_status_ok) |
|
1581 { |
|
1582 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1583 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1584 } |
|
1585 |
|
1586 |
|
1587 if (get_eapol_key_state() != eapol_key_state_preauthenticated |
|
1588 || m_authentication_type != required_authentication_type) |
|
1589 { |
|
1590 EAP_TRACE_DEBUG( |
|
1591 m_am_tools, |
|
1592 TRACE_FLAGS_DEFAULT, |
|
1593 (EAPL("ERROR: EAPOL_KEY: %s: eapol_key_state_c::read_reassociation_parameters(): this = 0x%08x, (get_eapol_key_state()=%d=%s) != (eapol_key_state_preauthenticated)\n"), |
|
1594 (m_is_client == true) ? "client": "server", |
|
1595 this, |
|
1596 get_eapol_key_state(), |
|
1597 state_string.get_eapol_key_state_string(get_eapol_key_state()))); |
|
1598 |
|
1599 EAP_TRACE_DEBUG( |
|
1600 m_am_tools, |
|
1601 TRACE_FLAGS_DEFAULT, |
|
1602 (EAPL("ERROR: EAPOL_KEY: %s: || (m_authentication_type=%d=%s) != (required_authentication_type=%d=%s)\n"), |
|
1603 (m_is_client == true) ? "client": "server", |
|
1604 m_authentication_type, |
|
1605 state_string.get_eapol_key_authentication_type_string(m_authentication_type), |
|
1606 required_authentication_type, |
|
1607 state_string.get_eapol_key_authentication_type_string(required_authentication_type))); |
|
1608 |
|
1609 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1610 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1611 } |
|
1612 |
|
1613 if (get_is_RSNA() == true) |
|
1614 { |
|
1615 if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) |
|
1616 { |
|
1617 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1618 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1619 } |
|
1620 |
|
1621 status = create_PMKID(); |
|
1622 if (status != eap_status_ok) |
|
1623 { |
|
1624 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1625 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1626 } |
|
1627 |
|
1628 |
|
1629 status = PMKID->set_copy_of_buffer(&m_PMKID); |
|
1630 if (status != eap_status_ok) |
|
1631 { |
|
1632 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1633 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1634 } |
|
1635 } |
|
1636 #if defined(EAP_USE_WPXM) |
|
1637 else if (get_is_WPXM() == true) |
|
1638 { |
|
1639 // We need to create a new PTKn. |
|
1640 ++m_WPXM_WPXC; |
|
1641 |
|
1642 EAP_TRACE_DEBUG( |
|
1643 m_am_tools, |
|
1644 TRACE_FLAGS_DEFAULT, |
|
1645 (EAPL("EAPOL_KEY: eapol_key_state_c::read_reassociation_parameters(): ") |
|
1646 EAPL("m_WPXM_WPXC=%d.\n"), |
|
1647 m_WPXM_WPXC)); |
|
1648 |
|
1649 status = derive_WPXM_PTK(m_WPXM_WPXC); |
|
1650 if (status != eap_status_ok) |
|
1651 { |
|
1652 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1653 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1654 } |
|
1655 |
|
1656 status = init_reassociate_timeout(m_wpxm_reassociate_timeout); |
|
1657 if (status != eap_status_ok) |
|
1658 { |
|
1659 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1660 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1661 } |
|
1662 |
|
1663 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1664 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1665 } |
|
1666 #endif //#if defined(EAP_USE_WPXM) |
|
1667 else |
|
1668 { |
|
1669 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1670 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1671 } |
|
1672 |
|
1673 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1674 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1675 } |
|
1676 |
|
1677 //-------------------------------------------------- |
|
1678 |
|
1679 // |
|
1680 eap_status_e eapol_key_state_c::complete_reassociation( |
|
1681 const eapol_wlan_authentication_state_e reassociation_result, |
|
1682 const eap_am_network_id_c * const /* receive_network_id */, |
|
1683 const eapol_key_authentication_type_e authentication_type, |
|
1684 const eap_variable_data_c * const received_WPA_IE, |
|
1685 const eap_variable_data_c * const sent_WPA_IE, |
|
1686 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, |
|
1687 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite |
|
1688 ) |
|
1689 { |
|
1690 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1691 |
|
1692 EAP_TRACE_DEBUG( |
|
1693 m_am_tools, |
|
1694 TRACE_FLAGS_DEFAULT, |
|
1695 (EAPL("eapol_key_state_c::complete_reassociation(): %s\n"), |
|
1696 (m_is_client == true) ? "client": "server")); |
|
1697 |
|
1698 eap_status_e status(eap_status_process_general_error); |
|
1699 |
|
1700 if (get_eapol_key_state() != eapol_key_state_preauthenticated |
|
1701 || m_authentication_type != authentication_type) |
|
1702 { |
|
1703 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1704 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1705 } |
|
1706 |
|
1707 if (reassociation_result == eapol_wlan_authentication_state_association_ok) |
|
1708 { |
|
1709 if (get_is_RSNA() == true) |
|
1710 { |
|
1711 status = allow_4_way_handshake(); |
|
1712 if (status != eap_status_ok) |
|
1713 { |
|
1714 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1715 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1716 } |
|
1717 |
|
1718 status = save_parameters( |
|
1719 authentication_type, |
|
1720 received_WPA_IE, |
|
1721 sent_WPA_IE, |
|
1722 pairwise_key_cipher_suite, |
|
1723 group_key_cipher_suite); |
|
1724 if (status != eap_status_ok) |
|
1725 { |
|
1726 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1727 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1728 } |
|
1729 } |
|
1730 #if defined(EAP_USE_WPXM) |
|
1731 else if (get_is_WPXM() == true) |
|
1732 { |
|
1733 // OK, nothing to do here. |
|
1734 status = eap_status_ok; |
|
1735 } |
|
1736 #endif //#if defined(EAP_USE_WPXM) |
|
1737 else |
|
1738 { |
|
1739 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1740 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1741 } |
|
1742 |
|
1743 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
1744 { |
|
1745 m_is_associated = true; |
|
1746 |
|
1747 EAP_TRACE_DEBUG( |
|
1748 m_am_tools, |
|
1749 TRACE_FLAGS_DEFAULT, |
|
1750 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::complete_reassociation(): m_is_associated=%s.\n"), |
|
1751 (m_is_client == true) ? "client": "server", |
|
1752 (m_is_associated == true) ? "true": "false")); |
|
1753 } |
|
1754 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
1755 |
|
1756 } |
|
1757 else |
|
1758 { |
|
1759 // Reassociation failed, clean-up state. |
|
1760 reset(); |
|
1761 |
|
1762 // Timeout value zero will remove state immediately. |
|
1763 status = init_handshake_timeout(0ul); |
|
1764 if (status != eap_status_ok) |
|
1765 { |
|
1766 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1767 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1768 } |
|
1769 } |
|
1770 |
|
1771 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1772 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1773 } |
|
1774 |
|
1775 //-------------------------------------------------- |
|
1776 |
|
1777 // |
|
1778 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_RSNA() |
|
1779 { |
|
1780 return (m_authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
1781 || m_authentication_type == eapol_key_authentication_type_RSNA_PSK); |
|
1782 } |
|
1783 |
|
1784 //-------------------------------------------------- |
|
1785 |
|
1786 // |
|
1787 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_WPA() |
|
1788 { |
|
1789 return (m_authentication_type == eapol_key_authentication_type_WPA_EAP |
|
1790 || m_authentication_type == eapol_key_authentication_type_WPA_PSK); |
|
1791 } |
|
1792 |
|
1793 //-------------------------------------------------- |
|
1794 |
|
1795 // |
|
1796 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::asynchronous_init_remove_eapol_key_state() |
|
1797 { |
|
1798 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1799 |
|
1800 eap_status_e status = handshake_failure_notification(); |
|
1801 if (status != eap_status_ok) |
|
1802 { |
|
1803 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1804 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1805 } |
|
1806 |
|
1807 status = m_key_state_partner->asynchronous_init_remove_eapol_key_state( |
|
1808 &m_send_network_id); |
|
1809 |
|
1810 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1811 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1812 } |
|
1813 |
|
1814 //-------------------------------------------------- |
|
1815 |
|
1816 // |
|
1817 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::timer_expired( |
|
1818 const u32_t id, void *data) |
|
1819 { |
|
1820 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1821 EAP_UNREFERENCED_PARAMETER(data); |
|
1822 |
|
1823 eap_status_e status = eap_status_process_general_error; |
|
1824 |
|
1825 EAP_TRACE_DEBUG( |
|
1826 m_am_tools, |
|
1827 TRACE_FLAGS_DEFAULT, |
|
1828 (EAPL("TIMER: EAPOL_KEY: %s: [0x%08x]->eapol_key_state_c::timer_expired(id 0x%02x, data 0x%08x).\n"), |
|
1829 (m_is_client == true ? "client": "server"), |
|
1830 this, |
|
1831 id, |
|
1832 data)); |
|
1833 |
|
1834 if (id == EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID) |
|
1835 { |
|
1836 eapol_key_state_string_c state_string; |
|
1837 EAP_TRACE_DEBUG( |
|
1838 m_am_tools, |
|
1839 TRACE_FLAGS_DEFAULT, |
|
1840 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID expired, eapol_key_state=%d=%s\n"), |
|
1841 (m_is_client == true ? "client": "server"), |
|
1842 get_eapol_key_state(), |
|
1843 state_string.get_eapol_key_state_string(get_eapol_key_state()))); |
|
1844 |
|
1845 if ((m_is_client == true |
|
1846 && get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_3) |
|
1847 || (m_is_client == false |
|
1848 && get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_2)) |
|
1849 { |
|
1850 if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
1851 || m_authentication_type == eapol_key_authentication_type_WPA_PSK) |
|
1852 { |
|
1853 // Most propably the PSK is incorrect. |
|
1854 // There could be other problems too. |
|
1855 send_error_notification(eap_status_wrong_password); |
|
1856 } |
|
1857 else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
1858 || m_authentication_type == eapol_key_authentication_type_WPA_EAP |
|
1859 || m_authentication_type == eapol_key_authentication_type_802_1X |
|
1860 || m_authentication_type == eapol_key_authentication_type_WPXM) |
|
1861 { |
|
1862 send_error_notification(eap_status_authentication_failure); |
|
1863 } |
|
1864 } |
|
1865 else if (get_eapol_key_state() != eapol_key_state_none) |
|
1866 { |
|
1867 send_error_notification(eap_status_authentication_failure); |
|
1868 } |
|
1869 |
|
1870 // Terminate the session. |
|
1871 status = asynchronous_init_remove_eapol_key_state(); |
|
1872 } |
|
1873 else if (id == EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID) |
|
1874 { |
|
1875 EAP_TRACE_DEBUG( |
|
1876 m_am_tools, |
|
1877 TRACE_FLAGS_DEFAULT, |
|
1878 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID elapsed.\n"), |
|
1879 (m_is_client == true ? "client": "server"))); |
|
1880 |
|
1881 if (m_retransmission != 0 |
|
1882 && m_retransmission->get_is_valid() == true |
|
1883 && m_retransmission->get_retransmission_counter() > 0) |
|
1884 { |
|
1885 EAP_TRACE_DEBUG( |
|
1886 m_am_tools, |
|
1887 TRACE_FLAGS_DEFAULT, |
|
1888 (EAPL("TIMER: EAPOL_KEY: new retransmission, m_retransmission->get_is_valid()=%d, ") |
|
1889 EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), |
|
1890 m_retransmission->get_is_valid(), |
|
1891 m_retransmission->get_retransmission_counter())); |
|
1892 |
|
1893 // This packet send is initialized by timer event. |
|
1894 status = resend_packet( |
|
1895 m_retransmission->get_send_network_id(), |
|
1896 m_retransmission->get_sent_packet(), |
|
1897 m_retransmission->get_header_offset(), |
|
1898 m_retransmission->get_data_length(), |
|
1899 m_retransmission->get_buffer_size() |
|
1900 ); |
|
1901 |
|
1902 if (status == eap_status_ok) |
|
1903 { |
|
1904 if (m_retransmission->get_retransmission_counter() > 0u) |
|
1905 { |
|
1906 // OK, initialize the next time to retransmit. |
|
1907 u32_t next_retransmission_time(m_retransmission->get_next_retransmission_time()); |
|
1908 |
|
1909 status = m_key_state_partner->set_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, 0, |
|
1910 next_retransmission_time); |
|
1911 if (status != eap_status_ok) |
|
1912 { |
|
1913 delete m_retransmission; |
|
1914 m_retransmission = 0; |
|
1915 } |
|
1916 else |
|
1917 { |
|
1918 m_retransmission->get_next_retransmission_counter(); // This decrements the counter. |
|
1919 |
|
1920 EAP_TRACE_DEBUG( |
|
1921 m_am_tools, |
|
1922 TRACE_FLAGS_DEFAULT, |
|
1923 (EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID set %d ms, retransmission_counter %d.\n"), |
|
1924 next_retransmission_time, |
|
1925 m_retransmission->get_retransmission_counter())); |
|
1926 } |
|
1927 } |
|
1928 |
|
1929 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1930 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1931 } |
|
1932 else |
|
1933 { |
|
1934 delete m_retransmission; |
|
1935 m_retransmission = 0; |
|
1936 |
|
1937 status = eap_status_ok; |
|
1938 |
|
1939 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1940 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1941 } |
|
1942 } |
|
1943 else |
|
1944 { |
|
1945 EAP_TRACE_DEBUG( |
|
1946 m_am_tools, |
|
1947 TRACE_FLAGS_DEFAULT, |
|
1948 (EAPL("TIMER: EAPOL_KEY: no retransmission, m_retransmission=0x%08x.\n"), |
|
1949 m_retransmission)); |
|
1950 if (m_retransmission != 0) |
|
1951 { |
|
1952 EAP_TRACE_DEBUG( |
|
1953 m_am_tools, |
|
1954 TRACE_FLAGS_DEFAULT, |
|
1955 (EAPL("TIMER: EAPOL_KEY: no retransmission, m_retransmission->get_is_valid()=%d, ") |
|
1956 EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), |
|
1957 m_retransmission->get_is_valid(), |
|
1958 m_retransmission->get_retransmission_counter())); |
|
1959 } |
|
1960 |
|
1961 // No good EAPOL-Key-Response received to EAPOL-Key-Requests. |
|
1962 // Terminate the session. |
|
1963 status = asynchronous_init_remove_eapol_key_state(); |
|
1964 } |
|
1965 } |
|
1966 else if (id == EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID) |
|
1967 { |
|
1968 EAP_TRACE_DEBUG( |
|
1969 m_am_tools, |
|
1970 TRACE_FLAGS_DEFAULT, |
|
1971 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID expired.\n"), |
|
1972 (m_is_client == true ? "client": "server"))); |
|
1973 |
|
1974 // Caching timeout. |
|
1975 // Remove the cached session. |
|
1976 status = asynchronous_init_remove_eapol_key_state(); |
|
1977 } |
|
1978 #if defined(EAP_USE_WPXM) |
|
1979 else if (id == EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID) |
|
1980 { |
|
1981 EAP_TRACE_DEBUG( |
|
1982 m_am_tools, |
|
1983 TRACE_FLAGS_DEFAULT, |
|
1984 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID expired.\n"), |
|
1985 (m_is_client == true ? "client": "server"))); |
|
1986 |
|
1987 eap_state_notification_c notification( |
|
1988 m_am_tools, |
|
1989 &m_send_network_id, |
|
1990 m_is_client, |
|
1991 eap_state_notification_generic, |
|
1992 eap_protocol_layer_eapol_key, |
|
1993 eapol_key_handshake_type_WPXM_reassociation, |
|
1994 get_eapol_key_state(), |
|
1995 eapol_key_state_reassociation_failed, |
|
1996 0ul, |
|
1997 false); |
|
1998 |
|
1999 notification.set_authentication_error(eap_status_authentication_failure); |
|
2000 |
|
2001 m_key_state_partner->state_notification(¬ification); |
|
2002 |
|
2003 // Remove the cached session. |
|
2004 status = asynchronous_init_remove_eapol_key_state(); |
|
2005 } |
|
2006 #endif //#if defined(EAP_USE_WPXM) |
|
2007 else if (id == EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID) |
|
2008 { |
|
2009 EAP_TRACE_DEBUG( |
|
2010 m_am_tools, |
|
2011 TRACE_FLAGS_DEFAULT, |
|
2012 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID expired.\n"), |
|
2013 (m_is_client == true ? "client": "server"))); |
|
2014 |
|
2015 // Here we swap the addresses. |
|
2016 eap_am_network_id_c receive_network_id(m_am_tools, |
|
2017 m_send_network_id.get_destination_id(), |
|
2018 m_send_network_id.get_source_id(), |
|
2019 m_send_network_id.get_type()); |
|
2020 if (receive_network_id.get_is_valid_data() == false) |
|
2021 { |
|
2022 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2023 } |
|
2024 |
|
2025 status = start_group_key_handshake( |
|
2026 &receive_network_id, |
|
2027 eapol_protocol_version_2, |
|
2028 #if defined(EAP_USE_WPXM) |
|
2029 m_EAPOL_WPXM_key_descriptor_type |
|
2030 #else |
|
2031 eapol_key_descriptor_type_RSNA |
|
2032 #endif //#if defined(EAP_USE_WPXM) |
|
2033 ); |
|
2034 if (status != eap_status_ok) |
|
2035 { |
|
2036 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2037 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2038 } |
|
2039 } |
|
2040 else if (id == EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID) |
|
2041 { |
|
2042 EAP_TRACE_DEBUG( |
|
2043 m_am_tools, |
|
2044 TRACE_FLAGS_DEFAULT, |
|
2045 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID expired.\n"), |
|
2046 (m_is_client == true ? "client": "server"))); |
|
2047 |
|
2048 // Here we swap the addresses. |
|
2049 eap_am_network_id_c receive_network_id(m_am_tools, |
|
2050 m_send_network_id.get_destination_id(), |
|
2051 m_send_network_id.get_source_id(), |
|
2052 m_send_network_id.get_type()); |
|
2053 if (receive_network_id.get_is_valid_data() == false) |
|
2054 { |
|
2055 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2056 } |
|
2057 |
|
2058 status = initialize_4_way_handshake( |
|
2059 &receive_network_id, |
|
2060 eapol_protocol_version_2); |
|
2061 if (status != eap_status_ok) |
|
2062 { |
|
2063 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2064 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2065 } |
|
2066 } |
|
2067 |
|
2068 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2069 } |
|
2070 |
|
2071 //-------------------------------------------------- |
|
2072 |
|
2073 // |
|
2074 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::timer_delete_data( |
|
2075 const u32_t id, void *data) |
|
2076 { |
|
2077 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2078 EAP_UNREFERENCED_PARAMETER(data); |
|
2079 |
|
2080 EAP_TRACE_DEBUG( |
|
2081 m_am_tools, |
|
2082 TRACE_FLAGS_DEFAULT, |
|
2083 (EAPL("TIMER: EAPOL_KEY: %s: [0x%08x]->eapol_key_state_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), |
|
2084 (m_is_client == true) ? "client": "server", |
|
2085 this, |
|
2086 id, |
|
2087 data)); |
|
2088 |
|
2089 if (id == EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID) |
|
2090 { |
|
2091 // Nothing to delete. |
|
2092 } |
|
2093 else if (id == EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID) |
|
2094 { |
|
2095 if (m_retransmission != 0 |
|
2096 && m_retransmission->get_is_valid() == true |
|
2097 && m_retransmission->get_retransmission_counter() > 0) |
|
2098 { |
|
2099 // Do not delete yet. |
|
2100 // cancel_retransmission() will delete m_retransmission. |
|
2101 } |
|
2102 else if (m_retransmission != 0) |
|
2103 { |
|
2104 delete m_retransmission; |
|
2105 m_retransmission = 0; |
|
2106 } |
|
2107 } |
|
2108 |
|
2109 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2110 } |
|
2111 |
|
2112 //-------------------------------------------------- |
|
2113 |
|
2114 |
|
2115 // |
|
2116 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::trace_eapol_key_message( |
|
2117 const i8_t * const prefix, |
|
2118 eapol_RSNA_key_header_c * const eapol_key_message) |
|
2119 { |
|
2120 EAP_UNREFERENCED_PARAMETER(prefix); |
|
2121 EAP_UNREFERENCED_PARAMETER(eapol_key_message); |
|
2122 |
|
2123 #if defined(USE_EAP_TRACE) |
|
2124 |
|
2125 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2126 |
|
2127 u32_t key_replay_counter_high = static_cast<u32_t>(eap_shift_right_64_bit( |
|
2128 eapol_key_message->get_key_replay_counter(), 32)); |
|
2129 u32_t key_replay_counter_low = static_cast<u32_t>(eapol_key_message->get_key_replay_counter()); |
|
2130 |
|
2131 EAP_UNREFERENCED_PARAMETER(key_replay_counter_high); |
|
2132 EAP_UNREFERENCED_PARAMETER(key_replay_counter_low); |
|
2133 |
|
2134 if (get_is_RSNA() == true) |
|
2135 { |
|
2136 EAP_TRACE_DEBUG( |
|
2137 m_am_tools, |
|
2138 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2139 (EAPL("EAPOL_KEY: %s (0x%08x): eapol version 0x%02x, eapol packet type 0x%02x, ") |
|
2140 EAPL("eapol packet body length 0x%04x\n"), |
|
2141 prefix, |
|
2142 (eapol_key_message), |
|
2143 (eapol_key_message)->get_eapol_protocol_version(), |
|
2144 (eapol_key_message)->get_eapol_packet_type(), |
|
2145 (eapol_key_message)->get_eapol_packet_body_length() |
|
2146 )); |
|
2147 |
|
2148 EAP_TRACE_DEBUG( |
|
2149 m_am_tools, |
|
2150 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2151 (EAPL("EAPOL_KEY: %s (0x%08x): eapol key descriptor type 0x%02x, ") |
|
2152 EAPL("key information 0x%04x, ") |
|
2153 EAPL("key information key descriptor version 0x%01x\n"), |
|
2154 prefix, |
|
2155 (eapol_key_message), |
|
2156 (eapol_key_message)->get_key_descriptor_type(), |
|
2157 (eapol_key_message)->get_key_information(), |
|
2158 (eapol_key_message)->get_key_information_key_descriptor_version() |
|
2159 )); |
|
2160 |
|
2161 EAP_TRACE_DEBUG( |
|
2162 m_am_tools, |
|
2163 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2164 (EAPL("EAPOL_KEY: %s (0x%08x): key information key type 0x%01x, ") |
|
2165 EAPL("key information reserved 0x%01x, ") |
|
2166 EAPL("key information install 0x%01x\n"), |
|
2167 prefix, |
|
2168 (eapol_key_message), |
|
2169 (eapol_key_message)->get_key_information_key_type(), |
|
2170 (eapol_key_message)->get_key_information_reserved_a(), |
|
2171 (eapol_key_message)->get_key_information_install() |
|
2172 )); |
|
2173 |
|
2174 EAP_TRACE_DEBUG( |
|
2175 m_am_tools, |
|
2176 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2177 (EAPL("EAPOL_KEY: %s (0x%08x): key information key ack 0x%01x, ") |
|
2178 EAPL("key information key MIC 0x%01x, ") |
|
2179 EAPL("key information secure 0x%01x\n"), |
|
2180 prefix, |
|
2181 (eapol_key_message), |
|
2182 (eapol_key_message)->get_key_information_key_ack(), |
|
2183 (eapol_key_message)->get_key_information_key_MIC(), |
|
2184 (eapol_key_message)->get_key_information_secure() |
|
2185 )); |
|
2186 |
|
2187 EAP_TRACE_DEBUG( |
|
2188 m_am_tools, |
|
2189 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2190 (EAPL("EAPOL_KEY: %s (0x%08x): key information error 0x%01x, ") |
|
2191 EAPL("key information request 0x%01x, ") |
|
2192 EAPL("key information encrypted key data 0x%01x\n"), |
|
2193 prefix, |
|
2194 (eapol_key_message), |
|
2195 (eapol_key_message)->get_key_information_error(), |
|
2196 (eapol_key_message)->get_key_information_request(), |
|
2197 (eapol_key_message)->get_key_information_encrypted_key_data() |
|
2198 )); |
|
2199 |
|
2200 EAP_TRACE_DEBUG( |
|
2201 m_am_tools, |
|
2202 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2203 (EAPL("EAPOL_KEY: %s (0x%08x): key information reserved 0x%01x, ") |
|
2204 EAPL("key length 0x%04x, key reply counter 0x%08x%08x\n"), |
|
2205 prefix, |
|
2206 (eapol_key_message), |
|
2207 (eapol_key_message)->get_key_information_reserved_b(), |
|
2208 (eapol_key_message)->get_key_length(), |
|
2209 key_replay_counter_high, |
|
2210 key_replay_counter_low |
|
2211 )); |
|
2212 } |
|
2213 else if (get_is_WPA() == true |
|
2214 #if defined(EAP_USE_WPXM) |
|
2215 || get_is_WPXM() == true |
|
2216 #endif //#if defined(EAP_USE_WPXM) |
|
2217 ) |
|
2218 { |
|
2219 // According to 802.11i D3.0 |
|
2220 |
|
2221 EAP_TRACE_DEBUG( |
|
2222 m_am_tools, |
|
2223 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2224 (EAPL("EAPOL_KEY: %s (0x%08x): eapol version 0x%02x, eapol packet type 0x%02x, ") |
|
2225 EAPL("eapol packet body length 0x%04x\n"), |
|
2226 prefix, |
|
2227 (eapol_key_message), |
|
2228 (eapol_key_message)->get_eapol_protocol_version(), |
|
2229 (eapol_key_message)->get_eapol_packet_type(), |
|
2230 (eapol_key_message)->get_eapol_packet_body_length() |
|
2231 )); |
|
2232 |
|
2233 EAP_TRACE_DEBUG( |
|
2234 m_am_tools, |
|
2235 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2236 (EAPL("EAPOL_KEY: %s (0x%08x): eapol key descriptor type 0x%02x, ") |
|
2237 EAPL("key information 0x%04x, ") |
|
2238 EAPL("key information key descriptor version 0x%01x\n"), |
|
2239 prefix, |
|
2240 (eapol_key_message), |
|
2241 (eapol_key_message)->get_key_descriptor_type(), |
|
2242 (eapol_key_message)->get_key_information(), |
|
2243 (eapol_key_message)->get_key_information_key_descriptor_version() |
|
2244 )); |
|
2245 |
|
2246 EAP_TRACE_DEBUG( |
|
2247 m_am_tools, |
|
2248 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2249 (EAPL("EAPOL_KEY: %s (0x%08x): key information key type 0x%01x, ") |
|
2250 EAPL("key information key index 0x%01x, ") |
|
2251 EAPL("key information install 0x%01x\n"), |
|
2252 prefix, |
|
2253 (eapol_key_message), |
|
2254 (eapol_key_message)->get_key_information_key_type(), |
|
2255 (eapol_key_message)->get_key_information_key_index(), |
|
2256 (eapol_key_message)->get_key_information_install() |
|
2257 )); |
|
2258 |
|
2259 EAP_TRACE_DEBUG( |
|
2260 m_am_tools, |
|
2261 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2262 (EAPL("EAPOL_KEY: %s (0x%08x): key information key ack 0x%01x, ") |
|
2263 EAPL("key information key MIC 0x%01x, ") |
|
2264 EAPL("key information secure 0x%01x\n"), |
|
2265 prefix, |
|
2266 (eapol_key_message), |
|
2267 (eapol_key_message)->get_key_information_key_ack(), |
|
2268 (eapol_key_message)->get_key_information_key_MIC(), |
|
2269 (eapol_key_message)->get_key_information_secure() |
|
2270 )); |
|
2271 |
|
2272 EAP_TRACE_DEBUG( |
|
2273 m_am_tools, |
|
2274 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2275 (EAPL("EAPOL_KEY: %s (0x%08x): key information error 0x%01x, ") |
|
2276 EAPL("key information request 0x%01x, ") |
|
2277 EAPL("key information encrypted key data 0x%01x\n"), |
|
2278 prefix, |
|
2279 (eapol_key_message), |
|
2280 (eapol_key_message)->get_key_information_error(), |
|
2281 (eapol_key_message)->get_key_information_request(), |
|
2282 (eapol_key_message)->get_key_information_encrypted_key_data() |
|
2283 )); |
|
2284 |
|
2285 EAP_TRACE_DEBUG( |
|
2286 m_am_tools, |
|
2287 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2288 (EAPL("EAPOL_KEY: %s (0x%08x): key information reserved 0x%02x, ") |
|
2289 EAPL("key length 0x%04x, key reply counter 0x%08x%08x\n"), |
|
2290 prefix, |
|
2291 (eapol_key_message), |
|
2292 (eapol_key_message)->get_key_information_reserved_b(), |
|
2293 (eapol_key_message)->get_key_length(), |
|
2294 key_replay_counter_high, |
|
2295 key_replay_counter_low |
|
2296 )); |
|
2297 } |
|
2298 else |
|
2299 { |
|
2300 // ERROR. |
|
2301 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2302 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); |
|
2303 } |
|
2304 |
|
2305 EAP_TRACE_DATA_DEBUG( |
|
2306 m_am_tools, |
|
2307 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2308 (EAPL("key nonce"), |
|
2309 (eapol_key_message)->get_key_NONCE(), |
|
2310 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE)); |
|
2311 |
|
2312 EAP_TRACE_DATA_DEBUG( |
|
2313 m_am_tools, |
|
2314 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2315 (EAPL("EAPOL-Key IV"), |
|
2316 (eapol_key_message)->get_EAPOL_key_IV(), |
|
2317 eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE)); |
|
2318 |
|
2319 EAP_TRACE_DATA_DEBUG( |
|
2320 m_am_tools, |
|
2321 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2322 (EAPL("Key RSC"), |
|
2323 (eapol_key_message)->get_key_RSC(), |
|
2324 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE)); |
|
2325 |
|
2326 EAP_TRACE_DATA_DEBUG( |
|
2327 m_am_tools, |
|
2328 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2329 (EAPL("STA MAC address"), |
|
2330 (eapol_key_message)->get_key_STA_MAC_address(), |
|
2331 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE)); |
|
2332 |
|
2333 EAP_TRACE_DATA_DEBUG( |
|
2334 m_am_tools, |
|
2335 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2336 (EAPL("reserved"), |
|
2337 (eapol_key_message)->get_key_reserved(), |
|
2338 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE)); |
|
2339 |
|
2340 EAP_TRACE_DATA_DEBUG( |
|
2341 m_am_tools, |
|
2342 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2343 (EAPL("Key MIC"), |
|
2344 (eapol_key_message)->get_key_MIC(), |
|
2345 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE)); |
|
2346 |
|
2347 EAP_TRACE_DATA_DEBUG( |
|
2348 m_am_tools, |
|
2349 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2350 (EAPL("Key Data"), |
|
2351 (eapol_key_message)->get_key_data((eapol_key_message)->get_key_data_length()), |
|
2352 (eapol_key_message)->get_key_data_length())); |
|
2353 |
|
2354 #endif //#if defined(USE_EAP_TRACE) |
|
2355 |
|
2356 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2357 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2358 } |
|
2359 |
|
2360 |
|
2361 //-------------------------------------------------- |
|
2362 |
|
2363 |
|
2364 // |
|
2365 eap_status_e eapol_key_state_c::trace_eapol_rsna_key_data_payload( |
|
2366 const bool is_RSNA, |
|
2367 const bool is_WPXM, |
|
2368 const eapol_key_descriptor_type_e eapol_key_descriptor_type, |
|
2369 const i8_t * const prefix, |
|
2370 const eapol_rsna_key_data_header_c * const key_data_payload, |
|
2371 const u32_t buffer_length) |
|
2372 { |
|
2373 EAP_UNREFERENCED_PARAMETER(is_RSNA); |
|
2374 EAP_UNREFERENCED_PARAMETER(prefix); |
|
2375 EAP_UNREFERENCED_PARAMETER(key_data_payload); |
|
2376 EAP_UNREFERENCED_PARAMETER(buffer_length); |
|
2377 EAP_UNREFERENCED_PARAMETER(is_WPXM); |
|
2378 EAP_UNREFERENCED_PARAMETER(eapol_key_descriptor_type); |
|
2379 |
|
2380 #if defined(USE_EAP_TRACE) |
|
2381 |
|
2382 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2383 |
|
2384 if ((is_RSNA == true |
|
2385 || (is_WPXM == true && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA)) |
|
2386 && key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_RSN_key_data) |
|
2387 { |
|
2388 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2389 (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s\n"), |
|
2390 prefix, |
|
2391 key_data_payload, |
|
2392 key_data_payload->get_descriptor_type(), |
|
2393 key_data_payload->get_descriptor_type_string())); |
|
2394 |
|
2395 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2396 (EAPL("EAPOL_KEY: %s (0x%08x): key_data_payload 0x%04x=%s\n"), |
|
2397 prefix, |
|
2398 key_data_payload, |
|
2399 key_data_payload->get_payload_type(), |
|
2400 key_data_payload->get_payload_type_string())); |
|
2401 |
|
2402 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2403 (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x.\n"), |
|
2404 prefix, |
|
2405 key_data_payload, |
|
2406 key_data_payload->get_header_and_body_length(), |
|
2407 buffer_length)); |
|
2408 |
|
2409 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2410 (EAPL("EAPOL_KEY: key_data_payload"), |
|
2411 (key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())), |
|
2412 key_data_payload->get_header_buffer_length())); |
|
2413 } |
|
2414 else if ((is_RSNA == true |
|
2415 || (is_WPXM == true && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA)) |
|
2416 && key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_RSN_IE) |
|
2417 { |
|
2418 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2419 (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"), |
|
2420 prefix, |
|
2421 key_data_payload, |
|
2422 key_data_payload->get_descriptor_type(), |
|
2423 key_data_payload->get_descriptor_type_string())); |
|
2424 |
|
2425 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2426 (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, RSN IE.\n"), |
|
2427 prefix, |
|
2428 key_data_payload, |
|
2429 key_data_payload->get_header_and_body_length(), |
|
2430 buffer_length)); |
|
2431 |
|
2432 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2433 (EAPL("EAPOL_KEY: RSN IE"), |
|
2434 (key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())), |
|
2435 key_data_payload->get_header_buffer_length())); |
|
2436 } |
|
2437 else if (key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_WPA_IE |
|
2438 && eapol_key_descriptor_type == eapol_key_descriptor_type_WPA) |
|
2439 { |
|
2440 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2441 (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"), |
|
2442 prefix, |
|
2443 key_data_payload, |
|
2444 key_data_payload->get_descriptor_type(), |
|
2445 key_data_payload->get_descriptor_type_string())); |
|
2446 |
|
2447 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2448 (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, WPA IE.\n"), |
|
2449 prefix, |
|
2450 key_data_payload, |
|
2451 key_data_payload->get_header_and_body_length(), |
|
2452 buffer_length)); |
|
2453 |
|
2454 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2455 (EAPL("EAPOL_KEY: WPA IE"), |
|
2456 (key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())), |
|
2457 key_data_payload->get_header_buffer_length())); |
|
2458 } |
|
2459 else |
|
2460 { |
|
2461 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2462 (EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"), |
|
2463 prefix, |
|
2464 key_data_payload, |
|
2465 key_data_payload->get_descriptor_type(), |
|
2466 key_data_payload->get_descriptor_type_string())); |
|
2467 |
|
2468 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2469 (EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, Unknown data.\n"), |
|
2470 prefix, |
|
2471 key_data_payload, |
|
2472 key_data_payload->get_header_and_body_length(), |
|
2473 buffer_length)); |
|
2474 |
|
2475 u32_t max_length = (buffer_length < key_data_payload->get_header_buffer_length()) |
|
2476 ? buffer_length : key_data_payload->get_header_buffer_length(); |
|
2477 |
|
2478 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
2479 (EAPL("EAPOL_KEY: Unknown data"), |
|
2480 (key_data_payload->get_header_buffer(max_length)), |
|
2481 max_length)); |
|
2482 } |
|
2483 |
|
2484 #endif //#if defined(USE_EAP_TRACE) |
|
2485 |
|
2486 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2487 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2488 } |
|
2489 |
|
2490 |
|
2491 //-------------------------------------------------- |
|
2492 |
|
2493 // |
|
2494 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_authenticator_RSNA_IE() |
|
2495 { |
|
2496 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2497 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2498 return &m_authenticator_RSNA_IE; |
|
2499 } |
|
2500 |
|
2501 //-------------------------------------------------- |
|
2502 |
|
2503 // |
|
2504 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_unicast_cipher_suite_RSNA_IE() |
|
2505 { |
|
2506 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2507 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2508 return &m_unicast_cipher_suite_RSNA_IE; |
|
2509 } |
|
2510 |
|
2511 //-------------------------------------------------- |
|
2512 |
|
2513 // |
|
2514 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_supplicant_RSNA_IE() |
|
2515 { |
|
2516 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2517 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2518 return &m_supplicant_RSNA_IE; |
|
2519 } |
|
2520 |
|
2521 //-------------------------------------------------- |
|
2522 |
|
2523 // |
|
2524 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_received_PMKID() |
|
2525 { |
|
2526 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2527 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2528 return &m_received_PMKID; |
|
2529 } |
|
2530 |
|
2531 //-------------------------------------------------- |
|
2532 |
|
2533 // |
|
2534 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_supplicant_MAC_address() |
|
2535 { |
|
2536 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2537 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2538 return &m_supplicant_MAC_address; |
|
2539 } |
|
2540 |
|
2541 //-------------------------------------------------- |
|
2542 |
|
2543 // |
|
2544 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_authenticator_MAC_address() |
|
2545 { |
|
2546 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2547 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2548 return &m_authenticator_MAC_address; |
|
2549 } |
|
2550 |
|
2551 //-------------------------------------------------- |
|
2552 |
|
2553 // |
|
2554 EAP_FUNC_EXPORT u64_t eapol_key_state_c::get_key_reply_counter() |
|
2555 { |
|
2556 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2557 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2558 return m_key_reply_counter; |
|
2559 } |
|
2560 |
|
2561 //-------------------------------------------------- |
|
2562 |
|
2563 // |
|
2564 EAP_FUNC_EXPORT void eapol_key_state_c::increase_key_reply_counter() |
|
2565 { |
|
2566 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2567 |
|
2568 ++m_key_reply_counter; |
|
2569 |
|
2570 EAP_TRACE_DATA_DEBUG( |
|
2571 m_am_tools, |
|
2572 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2573 (EAPL("Incresed Local Reply Counter"), |
|
2574 &m_key_reply_counter, |
|
2575 sizeof(m_key_reply_counter))); |
|
2576 |
|
2577 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2578 } |
|
2579 |
|
2580 //-------------------------------------------------- |
|
2581 |
|
2582 // |
|
2583 EAP_FUNC_EXPORT void eapol_key_state_c::set_key_reply_counter(const u64_t reply_counter) |
|
2584 { |
|
2585 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2586 |
|
2587 m_key_reply_counter = reply_counter; |
|
2588 |
|
2589 EAP_TRACE_DATA_DEBUG( |
|
2590 m_am_tools, |
|
2591 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2592 (EAPL("Set Local Reply Counter"), |
|
2593 &m_key_reply_counter, |
|
2594 sizeof(m_key_reply_counter))); |
|
2595 |
|
2596 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2597 } |
|
2598 |
|
2599 //-------------------------------------------------- |
|
2600 |
|
2601 // |
|
2602 EAP_FUNC_EXPORT u64_t eapol_key_state_c::get_client_send_key_reply_counter() |
|
2603 { |
|
2604 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2605 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2606 return m_client_send_key_reply_counter; |
|
2607 } |
|
2608 |
|
2609 //-------------------------------------------------- |
|
2610 |
|
2611 // |
|
2612 EAP_FUNC_EXPORT void eapol_key_state_c::increase_client_send_key_reply_counter() |
|
2613 { |
|
2614 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2615 |
|
2616 ++m_client_send_key_reply_counter; |
|
2617 |
|
2618 EAP_TRACE_DATA_DEBUG( |
|
2619 m_am_tools, |
|
2620 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2621 (EAPL("Increased Client Send Reply Counter"), |
|
2622 &m_client_send_key_reply_counter, |
|
2623 sizeof(m_client_send_key_reply_counter))); |
|
2624 |
|
2625 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2626 } |
|
2627 |
|
2628 //-------------------------------------------------- |
|
2629 |
|
2630 // |
|
2631 EAP_FUNC_EXPORT void eapol_key_state_c::set_client_send_key_reply_counter(const u64_t reply_counter) |
|
2632 { |
|
2633 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2634 |
|
2635 m_client_send_key_reply_counter = reply_counter; |
|
2636 |
|
2637 EAP_TRACE_DATA_DEBUG( |
|
2638 m_am_tools, |
|
2639 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2640 (EAPL("Set Client Send Reply Counter"), |
|
2641 &m_client_send_key_reply_counter, |
|
2642 sizeof(m_client_send_key_reply_counter))); |
|
2643 |
|
2644 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2645 } |
|
2646 |
|
2647 //-------------------------------------------------- |
|
2648 |
|
2649 // |
|
2650 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_ANonce() |
|
2651 { |
|
2652 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2653 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2654 return &m_ANonce; |
|
2655 } |
|
2656 |
|
2657 //-------------------------------------------------- |
|
2658 |
|
2659 // |
|
2660 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_SNonce() |
|
2661 { |
|
2662 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2663 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2664 return &m_SNonce; |
|
2665 } |
|
2666 |
|
2667 //-------------------------------------------------- |
|
2668 |
|
2669 // |
|
2670 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_confirmation_KCK() |
|
2671 { |
|
2672 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2673 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2674 return &m_confirmation_KCK; |
|
2675 } |
|
2676 |
|
2677 //-------------------------------------------------- |
|
2678 |
|
2679 // |
|
2680 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_encryption_KEK() |
|
2681 { |
|
2682 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2683 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2684 return &m_encryption_KEK; |
|
2685 } |
|
2686 |
|
2687 //-------------------------------------------------- |
|
2688 |
|
2689 // |
|
2690 eap_status_e eapol_key_state_c::check_is_aes_key_wrap_padding( |
|
2691 const eapol_RSNA_key_descriptor_type_e /* current_key_data_type */, |
|
2692 eapol_rsna_key_data_header_c * const key_data_payload, |
|
2693 const u32_t key_data_max_length |
|
2694 ) |
|
2695 { |
|
2696 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2697 |
|
2698 if (key_data_max_length > 1ul) |
|
2699 { |
|
2700 u8_t * const data = key_data_payload->get_header_buffer(key_data_max_length); |
|
2701 |
|
2702 // The first byte is eapol_RSNA_key_data_type_RSN_key_data. |
|
2703 // The following padding bytes are zero bytes. |
|
2704 for (u32_t ind = 1ul; ind < key_data_max_length; ind++) |
|
2705 { |
|
2706 if (data[ind] != 0ul) |
|
2707 { |
|
2708 // Padding must be zero byte. |
|
2709 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2710 return eap_status_illegal_padding; |
|
2711 } |
|
2712 } // for() |
|
2713 } |
|
2714 |
|
2715 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2716 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2717 } |
|
2718 |
|
2719 //-------------------------------------------------- |
|
2720 |
|
2721 // |
|
2722 eap_status_e eapol_key_state_c::parse_generic_key_data_payload( |
|
2723 const eapol_key_descriptor_type_e eapol_key_descriptor_type, |
|
2724 const eapol_RSNA_key_descriptor_type_e current_key_descriptor_type, |
|
2725 eapol_rsna_key_data_header_c * const key_data_payload, |
|
2726 u32_t * const key_data_max_length, |
|
2727 eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads, |
|
2728 const eapol_key_state_e expected_key_message) |
|
2729 { |
|
2730 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2731 |
|
2732 EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD( |
|
2733 get_is_RSNA(), |
|
2734 get_is_WPXM(), |
|
2735 eapol_key_descriptor_type, |
|
2736 "eapol_key_state_c::parse_generic_key_data_payload(): Parsing EAPOL Key Data key_data_payload", |
|
2737 key_data_payload, |
|
2738 *key_data_max_length); |
|
2739 |
|
2740 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::parse_generic_key_data_payload()"); |
|
2741 |
|
2742 { |
|
2743 eapol_key_state_string_c debug_string; |
|
2744 EAP_UNREFERENCED_PARAMETER(debug_string); |
|
2745 |
|
2746 EAP_TRACE_DEBUG( |
|
2747 m_am_tools, |
|
2748 TRACE_FLAGS_DEFAULT, |
|
2749 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2750 EAPL("current key_data_payload_type 0x%04x=%s.\n"), |
|
2751 key_data_payload, |
|
2752 current_key_descriptor_type, |
|
2753 key_data_payload->get_descriptor_type_string())); |
|
2754 |
|
2755 EAP_TRACE_DEBUG( |
|
2756 m_am_tools, |
|
2757 TRACE_FLAGS_DEFAULT, |
|
2758 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2759 EAPL("eapol_key_descriptor_type 0x%02x=%s.\n"), |
|
2760 key_data_payload, |
|
2761 eapol_key_descriptor_type, |
|
2762 debug_string.get_eapol_key_descriptor_type_string(eapol_key_descriptor_type))); |
|
2763 |
|
2764 EAP_TRACE_DEBUG( |
|
2765 m_am_tools, |
|
2766 TRACE_FLAGS_DEFAULT, |
|
2767 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2768 EAPL("payload length is 0x%04x, key_data_max_length is 0x%08x.\n"), |
|
2769 key_data_payload, |
|
2770 key_data_payload->get_header_and_body_length(), |
|
2771 *key_data_max_length)); |
|
2772 |
|
2773 EAP_TRACE_DEBUG( |
|
2774 m_am_tools, |
|
2775 TRACE_FLAGS_DEFAULT, |
|
2776 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2777 EAPL("expected_key_message = %s = 0x%08x.\n"), |
|
2778 key_data_payload, |
|
2779 debug_string.get_eapol_key_state_string(expected_key_message), |
|
2780 expected_key_message)); |
|
2781 } |
|
2782 |
|
2783 if (get_is_RSNA() == true |
|
2784 && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA |
|
2785 && current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_key_data |
|
2786 && check_is_aes_key_wrap_padding( |
|
2787 current_key_descriptor_type, |
|
2788 key_data_payload, |
|
2789 *key_data_max_length) == eap_status_ok) |
|
2790 { |
|
2791 EAP_TRACE_DEBUG( |
|
2792 m_am_tools, |
|
2793 TRACE_FLAGS_DEFAULT, |
|
2794 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): AES key wrapping padding\n"), |
|
2795 key_data_payload)); |
|
2796 |
|
2797 // This is AES key wrap padding. |
|
2798 *key_data_max_length = 0ul; |
|
2799 |
|
2800 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2801 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2802 } |
|
2803 else if (*key_data_max_length < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE |
|
2804 || key_data_payload->get_header_and_body_length() == 0) |
|
2805 { |
|
2806 EAP_TRACE_ERROR( |
|
2807 m_am_tools, |
|
2808 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2809 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2810 EAPL("current key_data_payload_type 0x%04x=%s, payload length is 0x%04x, key_data_max_length is 0x%08x.\n"), |
|
2811 key_data_payload, |
|
2812 current_key_descriptor_type, |
|
2813 key_data_payload->get_descriptor_type_string(), |
|
2814 key_data_payload->get_header_and_body_length(), |
|
2815 *key_data_max_length)); |
|
2816 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2817 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2818 } |
|
2819 |
|
2820 |
|
2821 if ((get_is_RSNA() == true |
|
2822 || get_is_WPXM() == true) |
|
2823 && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA |
|
2824 && current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_key_data) |
|
2825 { |
|
2826 eapol_RSNA_key_payload_type_e current_key_data_type = key_data_payload->get_payload_type(); |
|
2827 |
|
2828 EAP_TRACE_DEBUG( |
|
2829 m_am_tools, |
|
2830 TRACE_FLAGS_DEFAULT, |
|
2831 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): current_key_data_type = %s = 0x%02x\n"), |
|
2832 key_data_payload, |
|
2833 key_data_payload->get_payload_type_string(), |
|
2834 current_key_data_type)); |
|
2835 |
|
2836 if (current_key_data_type == eapol_RSNA_key_payload_type_group_key_and_id |
|
2837 && m_is_client == true |
|
2838 && (expected_key_message == eapol_key_state_wait_4_way_handshake_message_3 |
|
2839 || expected_key_message == eapol_key_state_wait_group_key_handshake_message_1)) |
|
2840 { |
|
2841 EAP_TRACE_DEBUG( |
|
2842 m_am_tools, |
|
2843 TRACE_FLAGS_DEFAULT, |
|
2844 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): Key ID and Group Key\n"), |
|
2845 key_data_payload)); |
|
2846 |
|
2847 /* Key ID and Group Key: |
|
2848 * 0 1 2 3 |
|
2849 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
|
2850 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
2851 * | Type = 0xdd | Length | OUI 3 octets ...| |
|
2852 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
2853 * | ... OUI | Data Type 1 | Key ID and Tx | Reserved 0 | |
|
2854 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
2855 * | GTK (Length - 6) octets | |
|
2856 * +- -+ |
|
2857 * : : |
|
2858 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
2859 */ |
|
2860 if (key_data_payload->get_key_data_payload_length() |
|
2861 < eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_MINIMUM_SIZE) |
|
2862 { |
|
2863 EAP_TRACE_ERROR( |
|
2864 m_am_tools, |
|
2865 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2866 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2867 EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"), |
|
2868 key_data_payload, |
|
2869 current_key_data_type, |
|
2870 key_data_payload->get_descriptor_type_string(), |
|
2871 key_data_payload->get_key_data_payload_length())); |
|
2872 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2873 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2874 } |
|
2875 |
|
2876 |
|
2877 const u32_t buffer_length = key_data_payload->get_key_data_payload_length(); |
|
2878 |
|
2879 u8_t * const buffer |
|
2880 = static_cast<u8_t *>(key_data_payload->get_key_data_payload(buffer_length)); |
|
2881 |
|
2882 if (buffer == 0) |
|
2883 { |
|
2884 EAP_TRACE_ERROR( |
|
2885 m_am_tools, |
|
2886 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2887 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2888 EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), |
|
2889 key_data_payload, |
|
2890 current_key_data_type, |
|
2891 key_data_payload->get_payload_type_string(), |
|
2892 key_data_payload->get_key_data_payload_length())); |
|
2893 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2894 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2895 } |
|
2896 |
|
2897 |
|
2898 eapol_rsna_key_data_gtk_header_c gtk_header( |
|
2899 m_am_tools, |
|
2900 buffer, |
|
2901 buffer_length); |
|
2902 if (gtk_header.get_is_valid() == false) |
|
2903 { |
|
2904 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2905 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2906 } |
|
2907 |
|
2908 eap_status_e status = gtk_header.check_header(); |
|
2909 if (status != eap_status_ok) |
|
2910 { |
|
2911 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2912 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2913 } |
|
2914 |
|
2915 p_rsna_key_data_payloads->set_group_key_id(gtk_header.get_key_index()); |
|
2916 p_rsna_key_data_payloads->set_group_key_tx(gtk_header.get_tx_bit()); |
|
2917 |
|
2918 u32_t group_key_header_length = eapol_rsna_key_data_gtk_header_c::get_header_length(); |
|
2919 |
|
2920 // Note here we get a reference to the data bytes of the received packet. |
|
2921 status = p_rsna_key_data_payloads->get_group_key()->set_buffer( |
|
2922 key_data_payload, |
|
2923 gtk_header.get_gtk(key_data_payload->get_key_data_payload_length()-group_key_header_length), |
|
2924 key_data_payload->get_key_data_payload_length()-group_key_header_length, |
|
2925 false, |
|
2926 false); |
|
2927 if (status != eap_status_ok) |
|
2928 { |
|
2929 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2930 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2931 } |
|
2932 |
|
2933 EAP_TRACE_DEBUG( |
|
2934 m_am_tools, |
|
2935 TRACE_FLAGS_DEFAULT, |
|
2936 (EAPL("received RSN Group Key ID %d, Tx %d\n"), |
|
2937 p_rsna_key_data_payloads->get_group_key_id(), |
|
2938 p_rsna_key_data_payloads->get_group_key_tx())); |
|
2939 |
|
2940 EAP_TRACE_DATA_DEBUG( |
|
2941 m_am_tools, |
|
2942 TRACE_FLAGS_DEFAULT, |
|
2943 (EAPL("received RSN Group Key"), |
|
2944 p_rsna_key_data_payloads->get_group_key()->get_data( |
|
2945 p_rsna_key_data_payloads->get_group_key()->get_data_length()), |
|
2946 p_rsna_key_data_payloads->get_group_key()->get_data_length())); |
|
2947 } |
|
2948 else if (current_key_data_type == eapol_RSNA_key_payload_type_sta_key) |
|
2949 { |
|
2950 EAP_TRACE_DEBUG( |
|
2951 m_am_tools, |
|
2952 TRACE_FLAGS_DEFAULT, |
|
2953 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): STAKey\n"), |
|
2954 key_data_payload)); |
|
2955 |
|
2956 /* STAKey: |
|
2957 * 0 1 2 3 |
|
2958 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
|
2959 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
2960 * | Type = 0xdd | Length | OUI 3 octets ...| |
|
2961 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
2962 * | ... OUI | Data Type 2 | Ecrypted STAKey | |
|
2963 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ |
|
2964 * : (Length - 4) octets : |
|
2965 * +- -+ |
|
2966 * | | |
|
2967 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
2968 */ |
|
2969 if (key_data_payload->get_key_data_payload_length() < eapol_rsna_key_data_header_c::EAPOL_RSNA_STAKEY_MINIMUM_SIZE) |
|
2970 { |
|
2971 EAP_TRACE_ERROR( |
|
2972 m_am_tools, |
|
2973 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2974 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2975 EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"), |
|
2976 key_data_payload, current_key_data_type, key_data_payload->get_payload_type_string(), |
|
2977 key_data_payload->get_key_data_payload_length())); |
|
2978 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2979 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2980 } |
|
2981 |
|
2982 u8_t * buffer |
|
2983 = static_cast<u8_t *>(key_data_payload->get_key_data_payload( |
|
2984 key_data_payload->get_key_data_payload_length())); |
|
2985 |
|
2986 if (buffer == 0) |
|
2987 { |
|
2988 EAP_TRACE_ERROR( |
|
2989 m_am_tools, |
|
2990 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
2991 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
2992 EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), |
|
2993 key_data_payload, |
|
2994 current_key_data_type, |
|
2995 key_data_payload->get_payload_type_string(), |
|
2996 key_data_payload->get_key_data_payload_length())); |
|
2997 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2998 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2999 } |
|
3000 |
|
3001 // Note here we get a reference to the data bytes of the received packet. |
|
3002 eap_status_e status = p_rsna_key_data_payloads->get_STAKey()->set_buffer( |
|
3003 key_data_payload, buffer, key_data_payload->get_key_data_payload_length(), false, false); |
|
3004 if (status != eap_status_ok) |
|
3005 { |
|
3006 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3007 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3008 } |
|
3009 } |
|
3010 else if (current_key_data_type == eapol_RSNA_key_payload_type_pmkid) |
|
3011 { |
|
3012 EAP_TRACE_DEBUG( |
|
3013 m_am_tools, |
|
3014 TRACE_FLAGS_DEFAULT, |
|
3015 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): PMKID\n"), |
|
3016 key_data_payload)); |
|
3017 |
|
3018 /* PMKID: |
|
3019 * 0 1 2 3 |
|
3020 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
|
3021 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
3022 * | Type = 0xdd | Length | OUI 3 octets ...| |
|
3023 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
3024 * | ... OUI | Data Type 3 | PMKID plaintext | |
|
3025 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- -+ |
|
3026 * : (Length - 4) octets : |
|
3027 * +- -+ |
|
3028 * | | |
|
3029 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
|
3030 */ |
|
3031 if (key_data_payload->get_key_data_payload_length() < eapol_rsna_key_data_header_c::EAPOL_RSNA_PMKID_MINIMUM_SIZE) |
|
3032 { |
|
3033 EAP_TRACE_ERROR( |
|
3034 m_am_tools, |
|
3035 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3036 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
3037 EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"), |
|
3038 key_data_payload, current_key_data_type, key_data_payload->get_payload_type_string(), |
|
3039 key_data_payload->get_key_data_payload_length())); |
|
3040 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3041 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3042 } |
|
3043 |
|
3044 u8_t * buffer |
|
3045 = static_cast<u8_t *>(key_data_payload->get_key_data_payload( |
|
3046 key_data_payload->get_key_data_payload_length())); |
|
3047 |
|
3048 if (buffer == 0) |
|
3049 { |
|
3050 EAP_TRACE_ERROR( |
|
3051 m_am_tools, |
|
3052 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3053 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
3054 EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"), |
|
3055 key_data_payload, |
|
3056 current_key_data_type, |
|
3057 key_data_payload->get_payload_type_string(), |
|
3058 key_data_payload->get_key_data_payload_length())); |
|
3059 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3060 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3061 } |
|
3062 |
|
3063 // Note here we get a reference to the data bytes of the received packet. |
|
3064 eap_status_e status = p_rsna_key_data_payloads->get_PMKID()->set_buffer( |
|
3065 key_data_payload, buffer, key_data_payload->get_key_data_payload_length(), false, false); |
|
3066 if (status != eap_status_ok) |
|
3067 { |
|
3068 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3069 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3070 } |
|
3071 } |
|
3072 else if (current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE |
|
3073 && key_data_payload->get_header_and_body_length() >= eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE) |
|
3074 { |
|
3075 EAP_TRACE_DEBUG( |
|
3076 m_am_tools, |
|
3077 TRACE_FLAGS_DEFAULT, |
|
3078 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): WPA Information element\n"), |
|
3079 key_data_payload)); |
|
3080 |
|
3081 /* This is WPA Information element. NOTE the 2 first bytes match with |
|
3082 * EAPOL Key Data Encapsulation format. |
|
3083 * |
|
3084 * 0 1 2 3 4 5 6 7 |
|
3085 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3086 * | Element ID 48=0x30 (WPA 221=0xdd) 1 octet | |
|
3087 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3088 * | Length 1 octet | |
|
3089 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3090 * | Version 2 octets | |
|
3091 * +- -+ |
|
3092 * | | |
|
3093 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3094 * | Group Key Cipher Suite 4 octets | |
|
3095 * +- -+ |
|
3096 * | optional | |
|
3097 * +- -+ |
|
3098 * | | |
|
3099 * +- -+ |
|
3100 * | | |
|
3101 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3102 * | Pairwise Key Cipher Suite Count (m) 2 octets | |
|
3103 * +- -+ |
|
3104 * | optional | |
|
3105 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3106 * | Pairwise Key Cipher Suite List m*4 octets | |
|
3107 * +- -+ |
|
3108 * | optional | |
|
3109 * +- -+ |
|
3110 * | | |
|
3111 * +- -+ |
|
3112 * | | |
|
3113 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3114 * | Authentication and Key Management Suite Count (n) 2 octets | |
|
3115 * +- -+ |
|
3116 * | optional | |
|
3117 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3118 * | Authentication and Key Management Suite List n*4 octets | |
|
3119 * +- -+ |
|
3120 * | optional | |
|
3121 * +- -+ |
|
3122 * | | |
|
3123 * +- -+ |
|
3124 * | | |
|
3125 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3126 * | RSN Capabilities 2 octets | |
|
3127 * +- -+ |
|
3128 * | optional | |
|
3129 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3130 * | PMKID Count (s) 2 octets | |
|
3131 * +- -+ |
|
3132 * | optional | |
|
3133 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3134 * | PMKID List s*16 octets | |
|
3135 * +- -+ |
|
3136 * : optional : |
|
3137 * +- -+ |
|
3138 * | | |
|
3139 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
|
3140 */ |
|
3141 |
|
3142 // The second byte is the length of the RSN IE. Also the Type and Length fields are included. |
|
3143 const u32_t length_of_the_RSN_IE = key_data_payload->get_header_and_body_length(); |
|
3144 |
|
3145 if (length_of_the_RSN_IE < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE) |
|
3146 { |
|
3147 EAP_TRACE_ERROR( |
|
3148 m_am_tools, |
|
3149 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3150 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
3151 EAPL("RSN IE length 0x%04x too less, at least 0x%04x bytes required.\n"), |
|
3152 key_data_payload, |
|
3153 length_of_the_RSN_IE, |
|
3154 eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE)); |
|
3155 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3156 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3157 } |
|
3158 |
|
3159 |
|
3160 // RSN IE is the whole key_data_payload. |
|
3161 u8_t * buffer = reinterpret_cast<u8_t *>(key_data_payload->get_header_buffer(length_of_the_RSN_IE)); |
|
3162 |
|
3163 if (buffer == 0) |
|
3164 { |
|
3165 EAP_TRACE_ERROR( |
|
3166 m_am_tools, |
|
3167 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3168 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
3169 EAPL("current key_data_payload length 0x%04x data buffer incorrect.\n"), |
|
3170 key_data_payload, |
|
3171 length_of_the_RSN_IE)); |
|
3172 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3173 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3174 } |
|
3175 |
|
3176 eap_variable_data_c * const rsn_ie = new eap_variable_data_c(m_am_tools); |
|
3177 if (rsn_ie == 0) |
|
3178 { |
|
3179 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3180 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3181 } |
|
3182 |
|
3183 EAP_TRACE_DATA_DEBUG( |
|
3184 m_am_tools, |
|
3185 TRACE_FLAGS_DEFAULT, |
|
3186 (EAPL("Parsed WPA IE"), |
|
3187 buffer, |
|
3188 length_of_the_RSN_IE)); |
|
3189 |
|
3190 // Note here we get a reference to the data bytes of the received packet. |
|
3191 eap_status_e status = rsn_ie->set_buffer( |
|
3192 buffer, |
|
3193 length_of_the_RSN_IE, |
|
3194 false, |
|
3195 false); |
|
3196 if (status != eap_status_ok) |
|
3197 { |
|
3198 delete rsn_ie; |
|
3199 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3200 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3201 } |
|
3202 |
|
3203 // eap_array_c object will free rsn_ie. |
|
3204 status = p_rsna_key_data_payloads->get_RSN_IE()->add_object(rsn_ie, true); |
|
3205 if (status != eap_status_ok) |
|
3206 { |
|
3207 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3208 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3209 } |
|
3210 } |
|
3211 else |
|
3212 { |
|
3213 // Unknown payloads are quietly ignored. |
|
3214 EAP_TRACE_ERROR( |
|
3215 m_am_tools, |
|
3216 TRACE_FLAGS_DEFAULT, |
|
3217 (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(): ") |
|
3218 EAPL("Ignores unknown EAPOL Key Data type %d=0x%08x and payload %d=0x%08x, length %d.\n"), |
|
3219 current_key_descriptor_type, |
|
3220 current_key_descriptor_type, |
|
3221 current_key_data_type, |
|
3222 current_key_data_type, |
|
3223 key_data_payload->get_header_and_body_length())); |
|
3224 } |
|
3225 |
|
3226 *key_data_max_length -= key_data_payload->get_header_and_body_length(); |
|
3227 |
|
3228 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3229 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3230 } |
|
3231 else if (get_is_WPA() == true |
|
3232 && eapol_key_descriptor_type == eapol_key_descriptor_type_WPA |
|
3233 && expected_key_message == eapol_key_state_wait_group_key_handshake_message_1) |
|
3234 { |
|
3235 EAP_TRACE_DEBUG( |
|
3236 m_am_tools, |
|
3237 TRACE_FLAGS_DEFAULT, |
|
3238 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): GTK\n"), |
|
3239 key_data_payload)); |
|
3240 |
|
3241 // Data includes GTK. |
|
3242 // key_data_payload points to the GTK of length (*key_data_max_length). |
|
3243 |
|
3244 u8_t * const buffer |
|
3245 = reinterpret_cast<u8_t *>(key_data_payload); |
|
3246 |
|
3247 if (buffer == 0) |
|
3248 { |
|
3249 EAP_TRACE_ERROR( |
|
3250 m_am_tools, |
|
3251 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3252 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
3253 EAPL("length 0x%04x, data buffer incorrect.\n"), |
|
3254 key_data_payload, |
|
3255 *key_data_max_length)); |
|
3256 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3257 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3258 } |
|
3259 |
|
3260 // Note here we get a reference to the data bytes of the received packet. |
|
3261 eap_status_e status = p_rsna_key_data_payloads->get_group_key()->set_buffer( |
|
3262 key_data_payload, buffer, |
|
3263 *key_data_max_length, false, false); |
|
3264 if (status != eap_status_ok) |
|
3265 { |
|
3266 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3267 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3268 } |
|
3269 |
|
3270 EAP_TRACE_DATA_DEBUG( |
|
3271 m_am_tools, |
|
3272 TRACE_FLAGS_DEFAULT, |
|
3273 (EAPL("received WPA Group Key"), |
|
3274 p_rsna_key_data_payloads->get_group_key()->get_data( |
|
3275 p_rsna_key_data_payloads->get_group_key()->get_data_length()), |
|
3276 p_rsna_key_data_payloads->get_group_key()->get_data_length())); |
|
3277 |
|
3278 *key_data_max_length = 0ul; |
|
3279 |
|
3280 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3281 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3282 } |
|
3283 else if ((get_is_RSNA() == true |
|
3284 && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA |
|
3285 && current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_IE) |
|
3286 || (get_is_WPA() == true |
|
3287 && eapol_key_descriptor_type == eapol_key_descriptor_type_WPA |
|
3288 && current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE) |
|
3289 #if defined(EAP_USE_WPXM) |
|
3290 || (get_is_WPXM() == true |
|
3291 && (current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_IE |
|
3292 || current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE)) |
|
3293 #endif //#if defined(EAP_USE_WPXM) |
|
3294 ) |
|
3295 { |
|
3296 EAP_TRACE_DEBUG( |
|
3297 m_am_tools, |
|
3298 TRACE_FLAGS_DEFAULT, |
|
3299 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): RSN Information element\n"), |
|
3300 key_data_payload)); |
|
3301 |
|
3302 /* This is RSN or WPA Information element. NOTE the 2 first bytes match with |
|
3303 * EAPOL Key Data Encapsulation format. |
|
3304 * |
|
3305 * 0 1 2 3 4 5 6 7 |
|
3306 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3307 * | Element ID 48=0x30 (WPA 221=0xdd) 1 octet | |
|
3308 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3309 * | Length 1 octet | |
|
3310 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3311 * | Version 2 octets | |
|
3312 * +- -+ |
|
3313 * | | |
|
3314 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3315 * | Group Key Cipher Suite 4 octets | |
|
3316 * +- -+ |
|
3317 * | optional | |
|
3318 * +- -+ |
|
3319 * | | |
|
3320 * +- -+ |
|
3321 * | | |
|
3322 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3323 * | Pairwise Key Cipher Suite Count (m) 2 octets | |
|
3324 * +- -+ |
|
3325 * | optional | |
|
3326 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3327 * | Pairwise Key Cipher Suite List m*4 octets | |
|
3328 * +- -+ |
|
3329 * | optional | |
|
3330 * +- -+ |
|
3331 * | | |
|
3332 * +- -+ |
|
3333 * | | |
|
3334 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3335 * | Authentication and Key Management Suite Count (n) 2 octets | |
|
3336 * +- -+ |
|
3337 * | optional | |
|
3338 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3339 * | Authentication and Key Management Suite List n*4 octets | |
|
3340 * +- -+ |
|
3341 * | optional | |
|
3342 * +- -+ |
|
3343 * | | |
|
3344 * +- -+ |
|
3345 * | | |
|
3346 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3347 * | RSN Capabilities 2 octets | |
|
3348 * +- -+ |
|
3349 * | optional | |
|
3350 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3351 * | PMKID Count (s) 2 octets | |
|
3352 * +- -+ |
|
3353 * | optional | |
|
3354 * +-------+-------+-------+-------+-------+-------+-------+-------+ |
|
3355 * | PMKID List s*16 octets | |
|
3356 * +- -+ |
|
3357 * : optional : |
|
3358 * +- -+ |
|
3359 * | | |
|
3360 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
|
3361 */ |
|
3362 |
|
3363 // The second byte is the length of the RSN IE. Also the Type and Length fields are included. |
|
3364 const u32_t length_of_the_RSN_IE = key_data_payload->get_header_and_body_length(); |
|
3365 |
|
3366 if (length_of_the_RSN_IE < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE) |
|
3367 { |
|
3368 EAP_TRACE_ERROR( |
|
3369 m_am_tools, |
|
3370 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3371 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
3372 EAPL("RSN IE length 0x%04x too less, at least 0x%04x bytes required.\n"), |
|
3373 key_data_payload, |
|
3374 length_of_the_RSN_IE, |
|
3375 eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE)); |
|
3376 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3377 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3378 } |
|
3379 |
|
3380 |
|
3381 // RSN IE is the whole key_data_payload. |
|
3382 u8_t * buffer = reinterpret_cast<u8_t *>(key_data_payload->get_header_buffer(length_of_the_RSN_IE)); |
|
3383 |
|
3384 if (buffer == 0) |
|
3385 { |
|
3386 EAP_TRACE_ERROR( |
|
3387 m_am_tools, |
|
3388 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3389 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ") |
|
3390 EAPL("current key_data_payload length 0x%04x data buffer incorrect.\n"), |
|
3391 key_data_payload, |
|
3392 length_of_the_RSN_IE)); |
|
3393 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3394 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3395 } |
|
3396 |
|
3397 eap_variable_data_c * const rsn_ie = new eap_variable_data_c(m_am_tools); |
|
3398 if (rsn_ie == 0) |
|
3399 { |
|
3400 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3401 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3402 } |
|
3403 |
|
3404 EAP_TRACE_DATA_DEBUG( |
|
3405 m_am_tools, |
|
3406 TRACE_FLAGS_DEFAULT, |
|
3407 (EAPL("Parsed RSN IE"), |
|
3408 buffer, |
|
3409 length_of_the_RSN_IE)); |
|
3410 |
|
3411 // Note here we get a reference to the data bytes of the received packet. |
|
3412 eap_status_e status = rsn_ie->set_buffer( |
|
3413 buffer, |
|
3414 length_of_the_RSN_IE, |
|
3415 false, |
|
3416 false); |
|
3417 if (status != eap_status_ok) |
|
3418 { |
|
3419 delete rsn_ie; |
|
3420 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3421 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3422 } |
|
3423 |
|
3424 // eap_array_c object will free rsn_ie. |
|
3425 status = p_rsna_key_data_payloads->get_RSN_IE()->add_object(rsn_ie, true); |
|
3426 if (status != eap_status_ok) |
|
3427 { |
|
3428 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3429 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3430 } |
|
3431 |
|
3432 buffer += length_of_the_RSN_IE; |
|
3433 |
|
3434 *key_data_max_length -= length_of_the_RSN_IE; |
|
3435 |
|
3436 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3437 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3438 } |
|
3439 else |
|
3440 { |
|
3441 // Unknown payloads are quietly ignored. |
|
3442 eapol_RSNA_key_payload_type_e current_key_data_type = key_data_payload->get_payload_type(); |
|
3443 EAP_UNREFERENCED_PARAMETER(current_key_data_type); |
|
3444 |
|
3445 EAP_TRACE_ERROR( |
|
3446 m_am_tools, |
|
3447 TRACE_FLAGS_DEFAULT, |
|
3448 (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(): ") |
|
3449 EAPL("Unknown EAPOL Key Data type %d=0x%08x and payload %d=0x%08x, length %d.\n"), |
|
3450 current_key_descriptor_type, |
|
3451 current_key_descriptor_type, |
|
3452 current_key_data_type, |
|
3453 current_key_data_type, |
|
3454 key_data_payload->get_header_and_body_length())); |
|
3455 |
|
3456 *key_data_max_length -= key_data_payload->get_header_and_body_length(); |
|
3457 |
|
3458 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3459 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3460 } |
|
3461 } |
|
3462 |
|
3463 //-------------------------------------------------- |
|
3464 |
|
3465 // |
|
3466 eap_status_e eapol_key_state_c::parse_key_data( |
|
3467 const eapol_key_descriptor_type_e eapol_key_descriptor_type, |
|
3468 const eapol_rsna_key_data_header_c * const p_payload, |
|
3469 u32_t * const buffer_length, |
|
3470 eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads, |
|
3471 const eapol_key_state_e expected_key_message, |
|
3472 const eapol_RSNA_key_header_c::key_descriptor_version_e key_descriptor_version) |
|
3473 { |
|
3474 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3475 |
|
3476 EAP_TRACE_DEBUG( |
|
3477 m_am_tools, |
|
3478 TRACE_FLAGS_DEFAULT, |
|
3479 (EAPL("EAPOL_KEY: eapol_key_state_c::parse_key_data()\n"))); |
|
3480 |
|
3481 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::parse_key_data()"); |
|
3482 |
|
3483 eapol_rsna_key_data_header_c payload( |
|
3484 m_am_tools, |
|
3485 get_is_RSNA(), |
|
3486 get_is_WPXM(), |
|
3487 p_payload->get_header_buffer(*buffer_length), |
|
3488 *buffer_length); // Const correctness is gone. |
|
3489 |
|
3490 eapol_RSNA_key_descriptor_type_e current_payload = payload.get_descriptor_type(); |
|
3491 |
|
3492 eap_status_e status = eap_status_header_corrupted; |
|
3493 |
|
3494 if (payload.get_is_valid() == true |
|
3495 && current_payload != eapol_RSNA_key_data_type_none) |
|
3496 { |
|
3497 |
|
3498 if (get_is_RSNA() == true |
|
3499 || expected_key_message != eapol_key_state_wait_group_key_handshake_message_1 // WPA must check the expected message. |
|
3500 ) |
|
3501 { |
|
3502 if (*buffer_length < payload.get_header_and_body_length()) |
|
3503 { |
|
3504 EAP_TRACE_ERROR( |
|
3505 m_am_tools, |
|
3506 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3507 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(0x%08x): ") |
|
3508 EAPL("current payload 0x%04x=%s, payload length 0x%04x, buffer length 0x%04x.\n"), |
|
3509 payload.get_header_buffer(0ul), |
|
3510 current_payload, |
|
3511 payload.get_payload_type_string(), |
|
3512 payload.get_header_and_body_length(), |
|
3513 *buffer_length)); |
|
3514 EAP_TRACE_ERROR( |
|
3515 m_am_tools, |
|
3516 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3517 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ") |
|
3518 EAPL("EAPOl Key Data-payload header is corrupted.\n"))); |
|
3519 EAP_TRACE_DATA_ERROR( |
|
3520 m_am_tools, |
|
3521 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3522 (EAPL("payload"), |
|
3523 payload.get_header_buffer(*buffer_length), |
|
3524 *buffer_length)); |
|
3525 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3526 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3527 } |
|
3528 } |
|
3529 |
|
3530 status = parse_generic_key_data_payload( |
|
3531 eapol_key_descriptor_type, |
|
3532 current_payload, |
|
3533 &payload, |
|
3534 buffer_length, |
|
3535 p_rsna_key_data_payloads, |
|
3536 expected_key_message); |
|
3537 if (status != eap_status_ok) |
|
3538 { |
|
3539 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3540 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3541 } |
|
3542 |
|
3543 |
|
3544 while(*buffer_length >= payload.get_header_length() |
|
3545 && payload.get_is_valid() == true |
|
3546 && payload.get_header_buffer_length() |
|
3547 >= (payload.get_header_and_body_length())) |
|
3548 { |
|
3549 payload.set_header_buffer( |
|
3550 payload.get_next_header(), |
|
3551 payload.get_header_buffer_length() |
|
3552 -(payload.get_header_and_body_length())); |
|
3553 if (payload.get_is_valid() == false) |
|
3554 { |
|
3555 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3556 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3557 } |
|
3558 |
|
3559 current_payload = payload.get_descriptor_type(); |
|
3560 |
|
3561 if (*buffer_length < payload.get_header_and_body_length()) |
|
3562 { |
|
3563 EAP_TRACE_ERROR( |
|
3564 m_am_tools, |
|
3565 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3566 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(0x%08x): ") |
|
3567 EAPL("current payload 0x%04x=%s, payload length 0x%04x, buffer length 0x%04x.\n"), |
|
3568 payload.get_header_buffer(0ul), |
|
3569 current_payload, |
|
3570 payload.get_payload_type_string(), |
|
3571 payload.get_header_and_body_length(), |
|
3572 *buffer_length)); |
|
3573 EAP_TRACE_ERROR( |
|
3574 m_am_tools, |
|
3575 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3576 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ") |
|
3577 EAPL("EAPOl Key Data-payload header is corrupted.\n"))); |
|
3578 EAP_TRACE_DATA_ERROR( |
|
3579 m_am_tools, |
|
3580 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3581 (EAPL("payload"), |
|
3582 payload.get_header_buffer(*buffer_length), |
|
3583 *buffer_length)); |
|
3584 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3585 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3586 } |
|
3587 |
|
3588 status = parse_generic_key_data_payload( |
|
3589 eapol_key_descriptor_type, |
|
3590 current_payload, |
|
3591 &payload, |
|
3592 buffer_length, |
|
3593 p_rsna_key_data_payloads, |
|
3594 expected_key_message); |
|
3595 if (status != eap_status_ok) |
|
3596 { |
|
3597 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3598 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3599 } |
|
3600 } |
|
3601 } |
|
3602 |
|
3603 if (*buffer_length != 0u) |
|
3604 { |
|
3605 if (key_descriptor_version == eapol_RSNA_key_header_c::m_key_descriptor_version_1) |
|
3606 { |
|
3607 EAP_TRACE_ERROR( |
|
3608 m_am_tools, |
|
3609 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3610 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ") |
|
3611 EAPL("EAPOl Key Data-header is corrupted. Buffer length ") |
|
3612 EAPL("and payload length does not match. %lu illegal bytes.\n"), |
|
3613 *buffer_length)); |
|
3614 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3615 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3616 } |
|
3617 } |
|
3618 |
|
3619 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3620 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3621 } |
|
3622 |
|
3623 //-------------------------------------------------- |
|
3624 |
|
3625 // |
|
3626 eap_status_e eapol_key_state_c::rsna_prf( |
|
3627 const eap_variable_data_c * const key_K, |
|
3628 const eap_variable_data_c * const label_A, |
|
3629 const eap_variable_data_c * const input_B, |
|
3630 const u32_t output_length_bits, |
|
3631 eap_variable_data_c * const output |
|
3632 ) |
|
3633 { |
|
3634 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3635 eap_status_e status = eap_status_process_general_error; |
|
3636 |
|
3637 crypto_sha1_c sha1(m_am_tools); |
|
3638 status = sha1.hash_init(); |
|
3639 if (status != eap_status_ok) |
|
3640 { |
|
3641 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3642 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3643 } |
|
3644 |
|
3645 crypto_hmac_c hmac(m_am_tools, &sha1, false); |
|
3646 |
|
3647 if (hmac.get_is_valid() == false) |
|
3648 { |
|
3649 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3650 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3651 } |
|
3652 |
|
3653 u32_t required_digest_count = (output_length_bits+159)/160; |
|
3654 u32_t required_buffer_length = hmac.get_digest_length()*required_digest_count; |
|
3655 u32_t required_octet_count = output_length_bits/8ul; |
|
3656 |
|
3657 output->reset(); |
|
3658 status = output->set_buffer_length(required_buffer_length); |
|
3659 if (status != eap_status_ok) |
|
3660 { |
|
3661 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3662 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3663 } |
|
3664 output->set_data_length(output->get_buffer_length()); |
|
3665 |
|
3666 eap_variable_data_c input(m_am_tools); |
|
3667 if (input.get_is_valid() == false) |
|
3668 { |
|
3669 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3670 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3671 } |
|
3672 |
|
3673 u8_t zero = 0ul; |
|
3674 |
|
3675 status = input.set_buffer_length( |
|
3676 label_A->get_data_length() |
|
3677 + sizeof(zero) |
|
3678 + input_B->get_data_length() |
|
3679 + sizeof(u8_t)); |
|
3680 if (status != eap_status_ok) |
|
3681 { |
|
3682 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3683 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3684 } |
|
3685 |
|
3686 for (u8_t ind = 0ul; ind < required_digest_count; ind++) |
|
3687 { |
|
3688 status = input.reset_start_offset_and_data_length(); |
|
3689 if (status != eap_status_ok) |
|
3690 { |
|
3691 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3692 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3693 } |
|
3694 |
|
3695 status = hmac.hmac_set_key(key_K); |
|
3696 if (status != eap_status_ok) |
|
3697 { |
|
3698 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3699 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3700 } |
|
3701 |
|
3702 if (label_A->get_is_valid_data() == true) |
|
3703 { |
|
3704 status = input.add_data(label_A); |
|
3705 if (status != eap_status_ok) |
|
3706 { |
|
3707 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3708 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3709 } |
|
3710 |
|
3711 status = input.add_data(&zero, sizeof(zero)); |
|
3712 if (status != eap_status_ok) |
|
3713 { |
|
3714 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3715 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3716 } |
|
3717 } |
|
3718 |
|
3719 status = input.add_data(input_B); |
|
3720 if (status != eap_status_ok) |
|
3721 { |
|
3722 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3723 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3724 } |
|
3725 |
|
3726 status = input.add_data(&ind, sizeof(ind)); |
|
3727 if (status != eap_status_ok) |
|
3728 { |
|
3729 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3730 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3731 } |
|
3732 |
|
3733 status = hmac.hmac_update( |
|
3734 input.get_data(input.get_data_length()), |
|
3735 input.get_data_length()); |
|
3736 if (status != eap_status_ok) |
|
3737 { |
|
3738 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3739 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3740 } |
|
3741 |
|
3742 u32_t md_length = hmac.get_digest_length(); |
|
3743 |
|
3744 status = hmac.hmac_final( |
|
3745 output->get_data_offset( |
|
3746 ind*hmac.get_digest_length(), |
|
3747 hmac.get_digest_length()), |
|
3748 &md_length); |
|
3749 if (status != eap_status_ok) |
|
3750 { |
|
3751 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3752 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3753 } |
|
3754 |
|
3755 } // for() |
|
3756 |
|
3757 output->set_data_length(required_octet_count); |
|
3758 |
|
3759 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3760 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3761 } |
|
3762 |
|
3763 //-------------------------------------------------- |
|
3764 |
|
3765 // |
|
3766 eap_status_e eapol_key_state_c::select_minimum( |
|
3767 const eap_variable_data_c * const input_a, |
|
3768 const eap_variable_data_c * const input_b, |
|
3769 const eap_variable_data_c ** const minimum, |
|
3770 const eap_variable_data_c ** const maximum) |
|
3771 { |
|
3772 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3773 |
|
3774 if (input_a == 0 |
|
3775 || input_b == 0 |
|
3776 || minimum == 0 |
|
3777 || maximum == 0) |
|
3778 { |
|
3779 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3780 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
3781 } |
|
3782 |
|
3783 if (input_a->get_data_length() > input_b->get_data_length()) |
|
3784 { |
|
3785 *minimum = input_b; |
|
3786 *maximum = input_a; |
|
3787 } |
|
3788 else if (input_a->get_data_length() < input_b->get_data_length()) |
|
3789 { |
|
3790 *minimum = input_a; |
|
3791 *maximum = input_b; |
|
3792 } |
|
3793 else |
|
3794 { |
|
3795 const i32_t cmp = input_a->compare(input_b); |
|
3796 if (cmp < 0) |
|
3797 { |
|
3798 *minimum = input_a; |
|
3799 *maximum = input_b; |
|
3800 } |
|
3801 else // if (cmp >= 0) NOTE this includes equal case too. |
|
3802 { |
|
3803 *minimum = input_b; |
|
3804 *maximum = input_a; |
|
3805 } |
|
3806 } |
|
3807 |
|
3808 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3809 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3810 } |
|
3811 |
|
3812 //-------------------------------------------------- |
|
3813 |
|
3814 // |
|
3815 eap_status_e eapol_key_state_c::derive_PTK() |
|
3816 { |
|
3817 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3818 |
|
3819 EAP_TRACE_DEBUG( |
|
3820 m_am_tools, |
|
3821 TRACE_FLAGS_DEFAULT, |
|
3822 (EAPL("eapol_key_state_c::derive_PTK(): %s\n"), |
|
3823 (m_is_client == true) ? "client": "server")); |
|
3824 |
|
3825 eap_status_e status = eap_status_process_general_error; |
|
3826 |
|
3827 if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) |
|
3828 { |
|
3829 EAP_TRACE_ERROR( |
|
3830 m_am_tools, |
|
3831 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3832 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") |
|
3833 EAPL("Pairwise Master Key (PMK) is missing.\n"))); |
|
3834 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3835 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
3836 } |
|
3837 |
|
3838 if (m_supplicant_MAC_address.get_is_valid_data() == false) |
|
3839 { |
|
3840 EAP_TRACE_ERROR( |
|
3841 m_am_tools, |
|
3842 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3843 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") |
|
3844 EAPL("Supplicant MAC address is missing.\n"))); |
|
3845 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3846 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
3847 } |
|
3848 |
|
3849 if (m_authenticator_MAC_address.get_is_valid_data() == false) |
|
3850 { |
|
3851 EAP_TRACE_ERROR( |
|
3852 m_am_tools, |
|
3853 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3854 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") |
|
3855 EAPL("Authenticator MAC address is missing.\n"))); |
|
3856 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3857 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
3858 } |
|
3859 |
|
3860 if (m_ANonce.get_is_valid_data() == false) |
|
3861 { |
|
3862 EAP_TRACE_ERROR( |
|
3863 m_am_tools, |
|
3864 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3865 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") |
|
3866 EAPL("Authenticator nonce (ANonce) is missing.\n"))); |
|
3867 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3868 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
3869 } |
|
3870 |
|
3871 if (m_SNonce.get_is_valid_data() == false) |
|
3872 { |
|
3873 EAP_TRACE_ERROR( |
|
3874 m_am_tools, |
|
3875 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
3876 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ") |
|
3877 EAPL("Supplicant nonce (m_SNonce) is missing.\n"))); |
|
3878 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3879 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
3880 } |
|
3881 |
|
3882 EAP_TRACE_DATA_DEBUG( |
|
3883 m_am_tools, |
|
3884 TRACE_FLAGS_DEFAULT, |
|
3885 (EAPL("EAPOL-Key m_supplicant_MAC_address"), |
|
3886 m_supplicant_MAC_address.get_data(m_supplicant_MAC_address.get_data_length()), |
|
3887 m_supplicant_MAC_address.get_data_length())); |
|
3888 |
|
3889 EAP_TRACE_DATA_DEBUG( |
|
3890 m_am_tools, |
|
3891 TRACE_FLAGS_DEFAULT, |
|
3892 (EAPL("EAPOL-Key m_authenticator_MAC_address"), |
|
3893 m_authenticator_MAC_address.get_data(m_authenticator_MAC_address.get_data_length()), |
|
3894 m_authenticator_MAC_address.get_data_length())); |
|
3895 |
|
3896 EAP_TRACE_DATA_DEBUG( |
|
3897 m_am_tools, |
|
3898 TRACE_FLAGS_DEFAULT, |
|
3899 (EAPL("EAPOL-Key m_SNonce"), |
|
3900 m_SNonce.get_data(m_SNonce.get_data_length()), |
|
3901 m_SNonce.get_data_length())); |
|
3902 |
|
3903 EAP_TRACE_DATA_DEBUG( |
|
3904 m_am_tools, |
|
3905 TRACE_FLAGS_DEFAULT, |
|
3906 (EAPL("EAPOL-Key m_ANonce"), |
|
3907 m_ANonce.get_data(m_ANonce.get_data_length()), |
|
3908 m_ANonce.get_data_length())); |
|
3909 |
|
3910 EAP_TRACE_DATA_DEBUG( |
|
3911 m_am_tools, |
|
3912 TRACE_FLAGS_DEFAULT, |
|
3913 (EAPL("EAPOL-Key m_pairwise_PMK_WPXK3"), |
|
3914 m_pairwise_PMK_WPXK3.get_data(m_pairwise_PMK_WPXK3.get_data_length()), |
|
3915 m_pairwise_PMK_WPXK3.get_data_length())); |
|
3916 |
|
3917 |
|
3918 const eap_variable_data_c * minimum_MAC_address = 0; |
|
3919 const eap_variable_data_c * maximum_MAC_address = 0; |
|
3920 const eap_variable_data_c * minimum_nonce = 0; |
|
3921 const eap_variable_data_c * maximum_nonce = 0; |
|
3922 |
|
3923 status = select_minimum( |
|
3924 &m_supplicant_MAC_address, |
|
3925 &m_authenticator_MAC_address, |
|
3926 &minimum_MAC_address, |
|
3927 &maximum_MAC_address); |
|
3928 if (status != eap_status_ok) |
|
3929 { |
|
3930 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3931 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3932 } |
|
3933 |
|
3934 status = select_minimum( |
|
3935 &m_ANonce, |
|
3936 &m_SNonce, |
|
3937 &minimum_nonce, |
|
3938 &maximum_nonce); |
|
3939 if (status != eap_status_ok) |
|
3940 { |
|
3941 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3942 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3943 } |
|
3944 |
|
3945 |
|
3946 |
|
3947 eap_variable_data_c input(m_am_tools); |
|
3948 |
|
3949 status = input.set_buffer_length( |
|
3950 minimum_MAC_address->get_data_length() |
|
3951 + maximum_MAC_address->get_data_length() |
|
3952 + minimum_nonce->get_data_length() |
|
3953 + maximum_nonce->get_data_length()); |
|
3954 if (status != eap_status_ok) |
|
3955 { |
|
3956 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3957 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3958 } |
|
3959 |
|
3960 status = input.add_data(minimum_MAC_address); |
|
3961 if (status != eap_status_ok) |
|
3962 { |
|
3963 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3964 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3965 } |
|
3966 |
|
3967 status = input.add_data(maximum_MAC_address); |
|
3968 if (status != eap_status_ok) |
|
3969 { |
|
3970 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3971 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3972 } |
|
3973 |
|
3974 status = input.add_data(minimum_nonce); |
|
3975 if (status != eap_status_ok) |
|
3976 { |
|
3977 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3978 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3979 } |
|
3980 |
|
3981 status = input.add_data(maximum_nonce); |
|
3982 if (status != eap_status_ok) |
|
3983 { |
|
3984 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3985 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3986 } |
|
3987 |
|
3988 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
3989 |
|
3990 // Default is TKIP. |
|
3991 u32_t PTK_length = EAPOL_RSNA_TKIP_PTK_LENGTH_BITS; |
|
3992 u32_t tk_length_bytes = EAPOL_RSNA_TKIP_TK_LENGTH_BYTES; |
|
3993 |
|
3994 if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) |
|
3995 { |
|
3996 PTK_length = EAPOL_RSNA_CCMP_PTK_LENGTH_BITS; |
|
3997 tk_length_bytes = EAPOL_RSNA_CCMP_TK_LENGTH_BYTES; |
|
3998 } |
|
3999 else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40) |
|
4000 { |
|
4001 tk_length_bytes = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_40; |
|
4002 } |
|
4003 else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) |
|
4004 { |
|
4005 tk_length_bytes = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_104; |
|
4006 } |
|
4007 |
|
4008 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
4009 |
|
4010 eap_variable_data_c label(m_am_tools); |
|
4011 |
|
4012 status = label.set_copy_of_buffer( |
|
4013 EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL, |
|
4014 EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL_LENGTH); |
|
4015 if (status != eap_status_ok) |
|
4016 { |
|
4017 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4018 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4019 } |
|
4020 |
|
4021 status = rsna_prf( |
|
4022 &m_pairwise_PMK_WPXK3, |
|
4023 &label, |
|
4024 &input, |
|
4025 PTK_length, |
|
4026 &m_transient_PTK); |
|
4027 if (status != eap_status_ok) |
|
4028 { |
|
4029 m_transient_PTK.reset(); |
|
4030 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4031 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4032 } |
|
4033 |
|
4034 // Split PTK to KCK, KEK and TK. |
|
4035 status = m_confirmation_KCK.set_buffer( |
|
4036 m_transient_PTK.get_data_offset(EAPOL_RSNA_KCK_OFFSET_BYTES, EAPOL_RSNA_KCK_LENGTH_BYTES), |
|
4037 EAPOL_RSNA_KCK_LENGTH_BYTES, |
|
4038 false, |
|
4039 false); |
|
4040 if (status != eap_status_ok) |
|
4041 { |
|
4042 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4043 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4044 } |
|
4045 |
|
4046 status = m_encryption_KEK.set_buffer( |
|
4047 m_transient_PTK.get_data_offset(EAPOL_RSNA_KEK_OFFSET_BYTES, EAPOL_RSNA_KEK_LENGTH_BYTES), |
|
4048 EAPOL_RSNA_KEK_LENGTH_BYTES, |
|
4049 false, |
|
4050 false); |
|
4051 if (status != eap_status_ok) |
|
4052 { |
|
4053 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4054 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4055 } |
|
4056 |
|
4057 status = m_temporal_TK.set_buffer( |
|
4058 m_transient_PTK.get_data_offset(EAPOL_RSNA_TK_OFFSET_BYTES, tk_length_bytes), |
|
4059 tk_length_bytes, |
|
4060 false, |
|
4061 false); |
|
4062 if (status != eap_status_ok) |
|
4063 { |
|
4064 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4065 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4066 } |
|
4067 |
|
4068 |
|
4069 EAP_TRACE_DATA_DEBUG( |
|
4070 m_am_tools, |
|
4071 TRACE_FLAGS_DEFAULT, |
|
4072 (EAPL("EAPOL-Key KCK"), |
|
4073 m_confirmation_KCK.get_data(m_confirmation_KCK.get_data_length()), |
|
4074 m_confirmation_KCK.get_data_length())); |
|
4075 |
|
4076 EAP_TRACE_DATA_DEBUG( |
|
4077 m_am_tools, |
|
4078 TRACE_FLAGS_DEFAULT, |
|
4079 (EAPL("EAPOL-Key KEK"), |
|
4080 m_encryption_KEK.get_data(m_encryption_KEK.get_data_length()), |
|
4081 m_encryption_KEK.get_data_length())); |
|
4082 |
|
4083 EAP_TRACE_DATA_DEBUG( |
|
4084 m_am_tools, |
|
4085 TRACE_FLAGS_DEFAULT, |
|
4086 (EAPL("EAPOL-Key TK"), |
|
4087 m_temporal_TK.get_data(m_temporal_TK.get_data_length()), |
|
4088 m_temporal_TK.get_data_length())); |
|
4089 |
|
4090 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4091 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4092 } |
|
4093 |
|
4094 //-------------------------------------------------- |
|
4095 |
|
4096 // |
|
4097 eap_status_e eapol_key_state_c::create_nonce( |
|
4098 eap_variable_data_c * const nonce, const u32_t nonce_length) |
|
4099 { |
|
4100 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4101 |
|
4102 EAP_TRACE_DEBUG( |
|
4103 m_am_tools, |
|
4104 TRACE_FLAGS_DEFAULT, |
|
4105 (EAPL("eapol_key_state_c::create_nonce(): %s\n"), |
|
4106 (m_is_client == true) ? "client": "server")); |
|
4107 |
|
4108 eap_status_e status = eap_status_process_general_error; |
|
4109 |
|
4110 status = nonce->set_buffer_length(nonce_length); |
|
4111 if (status != eap_status_ok) |
|
4112 { |
|
4113 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4114 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4115 } |
|
4116 nonce->set_data_length(nonce_length); |
|
4117 |
|
4118 crypto_random_c rand(m_am_tools); |
|
4119 |
|
4120 if (rand.get_is_valid() == false) |
|
4121 { |
|
4122 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4123 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4124 } |
|
4125 |
|
4126 status = rand.get_rand_bytes( |
|
4127 nonce->get_data(nonce->get_data_length()), |
|
4128 nonce->get_data_length()); |
|
4129 if (status != eap_status_ok) |
|
4130 { |
|
4131 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4132 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4133 } |
|
4134 |
|
4135 EAP_TRACE_DATA_DEBUG( |
|
4136 m_am_tools, |
|
4137 TRACE_FLAGS_DEFAULT, |
|
4138 (EAPL("EAPOL-Key new nonce"), |
|
4139 nonce->get_data(nonce->get_data_length()), |
|
4140 nonce->get_data_length())); |
|
4141 |
|
4142 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4143 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4144 } |
|
4145 |
|
4146 //-------------------------------------------------- |
|
4147 |
|
4148 // |
|
4149 eap_status_e eapol_key_state_c::create_PMKID() |
|
4150 { |
|
4151 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4152 eap_status_e status = eap_status_process_general_error; |
|
4153 |
|
4154 if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) |
|
4155 { |
|
4156 EAP_TRACE_ERROR( |
|
4157 m_am_tools, |
|
4158 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4159 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ") |
|
4160 EAPL("Pairwise Master Key (PMK) is missing.\n"))); |
|
4161 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4162 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4163 } |
|
4164 |
|
4165 if (m_supplicant_MAC_address.get_is_valid_data() == false) |
|
4166 { |
|
4167 EAP_TRACE_ERROR( |
|
4168 m_am_tools, |
|
4169 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4170 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ") |
|
4171 EAPL("Supplicant MAC address is missing.\n"))); |
|
4172 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4173 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4174 } |
|
4175 |
|
4176 if (m_authenticator_MAC_address.get_is_valid_data() == false) |
|
4177 { |
|
4178 EAP_TRACE_ERROR( |
|
4179 m_am_tools, |
|
4180 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4181 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ") |
|
4182 EAPL("Authenticator MAC address is missing.\n"))); |
|
4183 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4184 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4185 } |
|
4186 |
|
4187 |
|
4188 crypto_sha1_c sha1(m_am_tools); |
|
4189 |
|
4190 status = sha1.hash_init(); |
|
4191 if (status != eap_status_ok) |
|
4192 { |
|
4193 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4194 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4195 } |
|
4196 |
|
4197 crypto_hmac_c hmac(m_am_tools, &sha1, false); |
|
4198 |
|
4199 if (hmac.get_is_valid() == false) |
|
4200 { |
|
4201 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4202 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4203 } |
|
4204 |
|
4205 status = hmac.hmac_set_key(&m_pairwise_PMK_WPXK3); |
|
4206 if (status != eap_status_ok) |
|
4207 { |
|
4208 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4209 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4210 } |
|
4211 |
|
4212 status = hmac.hmac_update( |
|
4213 EAPOL_RSNA_PMK_NAME_LABEL, |
|
4214 EAPOL_RSNA_PMK_NAME_LABEL_LENGTH); |
|
4215 if (status != eap_status_ok) |
|
4216 { |
|
4217 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4218 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4219 } |
|
4220 |
|
4221 status = hmac.hmac_update( |
|
4222 m_authenticator_MAC_address.get_data(m_authenticator_MAC_address.get_data_length()), |
|
4223 m_authenticator_MAC_address.get_data_length()); |
|
4224 if (status != eap_status_ok) |
|
4225 { |
|
4226 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4227 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4228 } |
|
4229 |
|
4230 status = hmac.hmac_update( |
|
4231 m_supplicant_MAC_address.get_data(m_supplicant_MAC_address.get_data_length()), |
|
4232 m_supplicant_MAC_address.get_data_length()); |
|
4233 if (status != eap_status_ok) |
|
4234 { |
|
4235 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4236 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4237 } |
|
4238 |
|
4239 |
|
4240 { |
|
4241 m_PMKID.reset(); |
|
4242 |
|
4243 status = m_PMKID.set_buffer_length(hmac.get_digest_length()); |
|
4244 if (status != eap_status_ok) |
|
4245 { |
|
4246 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4247 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4248 } |
|
4249 m_PMKID.set_data_length(hmac.get_digest_length()); |
|
4250 |
|
4251 u32_t md_length = hmac.get_digest_length(); |
|
4252 |
|
4253 status = hmac.hmac_final( |
|
4254 m_PMKID.get_data(hmac.get_digest_length()), |
|
4255 &md_length); |
|
4256 if (status != eap_status_ok) |
|
4257 { |
|
4258 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4259 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4260 } |
|
4261 |
|
4262 if (md_length < eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE) |
|
4263 { |
|
4264 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4265 return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); |
|
4266 } |
|
4267 |
|
4268 // This cuts the PMKID to 128 bits. |
|
4269 m_PMKID.set_data_length(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE); |
|
4270 |
|
4271 EAP_TRACE_DATA_DEBUG( |
|
4272 m_am_tools, |
|
4273 TRACE_FLAGS_DEFAULT, |
|
4274 (EAPL("EAPOL-Key PMKID"), |
|
4275 m_PMKID.get_data(), |
|
4276 m_PMKID.get_data_length())); |
|
4277 } |
|
4278 |
|
4279 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4280 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4281 } |
|
4282 |
|
4283 //-------------------------------------------------- |
|
4284 |
|
4285 // |
|
4286 eap_status_e eapol_key_state_c::encrypt_key_data( |
|
4287 eapol_RSNA_key_header_c * const eapol_key_message) |
|
4288 { |
|
4289 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4290 eap_status_e status = eap_status_process_general_error; |
|
4291 |
|
4292 if (m_encryption_KEK.get_is_valid_data() == false |
|
4293 || m_encryption_KEK.get_data_length() == 0ul) |
|
4294 { |
|
4295 EAP_TRACE_ERROR( |
|
4296 m_am_tools, |
|
4297 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4298 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::encrypt_key_data(): ") |
|
4299 EAPL("m_encryption_KEK is missing or corrupted.\n"))); |
|
4300 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4301 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4302 } |
|
4303 |
|
4304 |
|
4305 if (m_eapol_pairwise_cipher |
|
4306 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP |
|
4307 || m_eapol_group_cipher |
|
4308 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) |
|
4309 { |
|
4310 EAP_TRACE_DEBUG( |
|
4311 m_am_tools, |
|
4312 TRACE_FLAGS_DEFAULT, |
|
4313 (EAPL("EAPOL_KEY: AES-WRAP encryption algorithm.\n"))); |
|
4314 |
|
4315 crypto_aes_wrap_c aes_wrap(m_am_tools); |
|
4316 |
|
4317 if (aes_wrap.get_is_valid() == false) |
|
4318 { |
|
4319 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4320 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4321 } |
|
4322 |
|
4323 status = aes_wrap.set_encryption_key( |
|
4324 m_encryption_KEK.get_data(), |
|
4325 m_encryption_KEK.get_data_length()); |
|
4326 if (status != eap_status_ok) |
|
4327 { |
|
4328 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4329 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4330 } |
|
4331 |
|
4332 u32_t padding_length(0ul); |
|
4333 u32_t min_key_data_length = 2ul * aes_wrap.get_block_size(); |
|
4334 |
|
4335 if (eapol_key_message->get_key_data_length() < min_key_data_length) |
|
4336 { |
|
4337 padding_length = min_key_data_length - eapol_key_message->get_key_data_length(); |
|
4338 } |
|
4339 else if ((eapol_key_message->get_key_data_length() % aes_wrap.get_block_size()) != 0) |
|
4340 { |
|
4341 padding_length = aes_wrap.get_block_size() |
|
4342 - (eapol_key_message->get_key_data_length() % aes_wrap.get_block_size()); |
|
4343 } |
|
4344 |
|
4345 u32_t padding_offset = eapol_key_message->get_key_data_length(); |
|
4346 |
|
4347 // AES-Wrap increases message length with one block. |
|
4348 status = eapol_key_message->set_key_data_length( |
|
4349 static_cast<u16_t>(eapol_key_message->get_key_data_length() |
|
4350 + padding_length |
|
4351 + aes_wrap.get_block_size())); |
|
4352 if (status != eap_status_ok) |
|
4353 { |
|
4354 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4355 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4356 } |
|
4357 |
|
4358 if (padding_length > 0ul) |
|
4359 { |
|
4360 aes_wrap.add_padding_bytes( |
|
4361 eapol_key_message->get_key_data_offset( |
|
4362 padding_offset, |
|
4363 padding_length), |
|
4364 padding_length); |
|
4365 } |
|
4366 |
|
4367 if (eapol_key_message->get_key_data_length() < aes_wrap.get_block_size()) |
|
4368 { |
|
4369 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4370 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4371 } |
|
4372 |
|
4373 status = aes_wrap.encrypt_block( |
|
4374 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4375 eapol_key_message->get_key_data_length()-aes_wrap.get_block_size(), |
|
4376 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4377 eapol_key_message->get_key_data_length()); |
|
4378 |
|
4379 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4380 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4381 } |
|
4382 else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP |
|
4383 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40 |
|
4384 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) |
|
4385 { |
|
4386 EAP_TRACE_DEBUG( |
|
4387 m_am_tools, |
|
4388 TRACE_FLAGS_DEFAULT, |
|
4389 (EAPL("EAPOL_KEY: RC4 encryption algorithm.\n"))); |
|
4390 |
|
4391 if (m_EAPOL_key_IV.get_is_valid_data() == false |
|
4392 || m_EAPOL_key_IV.get_data_length() == 0ul) |
|
4393 { |
|
4394 EAP_TRACE_ERROR( |
|
4395 m_am_tools, |
|
4396 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4397 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::encrypt_key_data(): ") |
|
4398 EAPL("m_EAPOL_key_IV is missing or corrupted.\n"))); |
|
4399 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4400 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4401 } |
|
4402 |
|
4403 abs_crypto_stream_algorithm_c * const rc4 = new crypto_rc4_c(m_am_tools); |
|
4404 eap_automatic_variable_c<abs_crypto_stream_algorithm_c> automatic_rc4(m_am_tools, rc4); |
|
4405 |
|
4406 if (rc4 == 0 |
|
4407 || rc4->get_is_valid() == false) |
|
4408 { |
|
4409 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4410 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4411 } |
|
4412 |
|
4413 eap_variable_data_c key(m_am_tools); |
|
4414 |
|
4415 status = key.set_copy_of_buffer(&m_EAPOL_key_IV); |
|
4416 if (status != eap_status_ok) |
|
4417 { |
|
4418 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4419 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4420 } |
|
4421 |
|
4422 status = key.add_data(&m_encryption_KEK); |
|
4423 if (status != eap_status_ok) |
|
4424 { |
|
4425 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4426 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4427 } |
|
4428 |
|
4429 EAP_TRACE_DATA_DEBUG( |
|
4430 m_am_tools, |
|
4431 TRACE_FLAGS_DEFAULT, |
|
4432 (EAPL("EAPOL-Key encrypt key"), |
|
4433 key.get_data(key.get_data_length()), |
|
4434 key.get_data_length())); |
|
4435 |
|
4436 status = rc4->set_key(&key); |
|
4437 if (status != eap_status_ok) |
|
4438 { |
|
4439 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4440 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4441 } |
|
4442 |
|
4443 // The first 256 octets of RC4 key stream are discarded. |
|
4444 status = rc4->discard_stream(EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_LENGTH); |
|
4445 if (status != eap_status_ok) |
|
4446 { |
|
4447 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4448 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4449 } |
|
4450 |
|
4451 EAP_TRACE_DATA_DEBUG( |
|
4452 m_am_tools, |
|
4453 TRACE_FLAGS_DEFAULT, |
|
4454 (EAPL("EAPOL-Key plaintext data"), |
|
4455 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4456 eapol_key_message->get_key_data_length())); |
|
4457 |
|
4458 status = rc4->encrypt_data( |
|
4459 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4460 eapol_key_message->get_key_data_length()); |
|
4461 if (status != eap_status_ok) |
|
4462 { |
|
4463 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4464 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4465 } |
|
4466 |
|
4467 EAP_TRACE_DATA_DEBUG( |
|
4468 m_am_tools, |
|
4469 TRACE_FLAGS_DEFAULT, |
|
4470 (EAPL("EAPOL-Key encrypted data"), |
|
4471 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4472 eapol_key_message->get_key_data_length())); |
|
4473 |
|
4474 } |
|
4475 else |
|
4476 { |
|
4477 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4478 return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); |
|
4479 } |
|
4480 |
|
4481 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4482 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4483 } |
|
4484 |
|
4485 //-------------------------------------------------- |
|
4486 |
|
4487 // |
|
4488 eap_status_e eapol_key_state_c::decrypt_key_data( |
|
4489 eapol_RSNA_key_header_c * const eapol_key_message) |
|
4490 { |
|
4491 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4492 eap_status_e status = eap_status_process_general_error; |
|
4493 |
|
4494 |
|
4495 if (m_eapol_pairwise_cipher |
|
4496 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP |
|
4497 || m_eapol_group_cipher |
|
4498 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) |
|
4499 { |
|
4500 EAP_TRACE_DEBUG( |
|
4501 m_am_tools, |
|
4502 TRACE_FLAGS_DEFAULT, |
|
4503 (EAPL("EAPOL_KEY: AES-WRAP decryption algorithm.\n"))); |
|
4504 |
|
4505 crypto_aes_wrap_c aes_wrap(m_am_tools); |
|
4506 |
|
4507 if (aes_wrap.get_is_valid() == false) |
|
4508 { |
|
4509 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4510 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4511 } |
|
4512 |
|
4513 status = aes_wrap.set_decryption_key( |
|
4514 m_encryption_KEK.get_data(), |
|
4515 m_encryption_KEK.get_data_length()); |
|
4516 if (status != eap_status_ok) |
|
4517 { |
|
4518 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4519 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4520 } |
|
4521 |
|
4522 status = aes_wrap.decrypt_block( |
|
4523 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4524 eapol_key_message->get_key_data_length(), |
|
4525 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4526 eapol_key_message->get_key_data_length()); |
|
4527 if (status != eap_status_ok) |
|
4528 { |
|
4529 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4530 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4531 } |
|
4532 |
|
4533 // AES-Wrap increases message length with one block. |
|
4534 // Here we remove the block. |
|
4535 status = eapol_key_message->set_key_data_length( |
|
4536 static_cast<u16_t>(eapol_key_message->get_key_data_length() |
|
4537 - aes_wrap.get_block_size())); |
|
4538 |
|
4539 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4540 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4541 } |
|
4542 else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP |
|
4543 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40 |
|
4544 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) |
|
4545 { |
|
4546 EAP_TRACE_DEBUG( |
|
4547 m_am_tools, |
|
4548 TRACE_FLAGS_DEFAULT, |
|
4549 (EAPL("EAPOL_KEY: RC4 decryption algorithm.\n"))); |
|
4550 |
|
4551 abs_crypto_stream_algorithm_c * const rc4 = new crypto_rc4_c(m_am_tools); |
|
4552 eap_automatic_variable_c<abs_crypto_stream_algorithm_c> automatic_rc4(m_am_tools, rc4); |
|
4553 |
|
4554 if (rc4 == 0 |
|
4555 || rc4->get_is_valid() == false) |
|
4556 { |
|
4557 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4558 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4559 } |
|
4560 |
|
4561 eap_variable_data_c key(m_am_tools); |
|
4562 |
|
4563 status = key.set_copy_of_buffer(&m_EAPOL_key_IV); |
|
4564 if (status != eap_status_ok) |
|
4565 { |
|
4566 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4567 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4568 } |
|
4569 |
|
4570 status = key.add_data(&m_encryption_KEK); |
|
4571 if (status != eap_status_ok) |
|
4572 { |
|
4573 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4574 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4575 } |
|
4576 |
|
4577 EAP_TRACE_DATA_DEBUG( |
|
4578 m_am_tools, |
|
4579 TRACE_FLAGS_DEFAULT, |
|
4580 (EAPL("EAPOL-Key decrypt key"), |
|
4581 key.get_data(key.get_data_length()), |
|
4582 key.get_data_length())); |
|
4583 |
|
4584 status = rc4->set_key(&key); |
|
4585 if (status != eap_status_ok) |
|
4586 { |
|
4587 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4588 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4589 } |
|
4590 |
|
4591 // The first 256 octets of RC4 key stream are discarded. |
|
4592 status = rc4->discard_stream(EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_LENGTH); |
|
4593 if (status != eap_status_ok) |
|
4594 { |
|
4595 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4596 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4597 } |
|
4598 |
|
4599 EAP_TRACE_DATA_DEBUG( |
|
4600 m_am_tools, |
|
4601 TRACE_FLAGS_DEFAULT, |
|
4602 (EAPL("EAPOL-Key encrypted data"), |
|
4603 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4604 eapol_key_message->get_key_data_length())); |
|
4605 |
|
4606 status = rc4->decrypt_data( |
|
4607 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4608 eapol_key_message->get_key_data_length()); |
|
4609 if (status != eap_status_ok) |
|
4610 { |
|
4611 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4612 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4613 } |
|
4614 |
|
4615 EAP_TRACE_DATA_DEBUG( |
|
4616 m_am_tools, |
|
4617 TRACE_FLAGS_DEFAULT, |
|
4618 (EAPL("EAPOL-Key plaintext data"), |
|
4619 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()), |
|
4620 eapol_key_message->get_key_data_length())); |
|
4621 |
|
4622 } |
|
4623 else |
|
4624 { |
|
4625 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4626 return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); |
|
4627 } |
|
4628 |
|
4629 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4630 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4631 } |
|
4632 |
|
4633 //-------------------------------------------------- |
|
4634 |
|
4635 |
|
4636 // |
|
4637 eap_status_e eapol_key_state_c::create_key_mic( |
|
4638 eapol_RSNA_key_header_c * const eapol_key_message, |
|
4639 const eap_variable_data_c * const confirmation_key) |
|
4640 { |
|
4641 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4642 eap_status_e status = eap_status_process_general_error; |
|
4643 |
|
4644 if (eapol_key_message == 0) |
|
4645 { |
|
4646 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4647 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4648 } |
|
4649 |
|
4650 if (confirmation_key->get_is_valid_data() == false |
|
4651 || confirmation_key->get_data_length() == 0ul) |
|
4652 { |
|
4653 EAP_TRACE_ERROR( |
|
4654 m_am_tools, |
|
4655 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4656 (EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_key_mic(): ") |
|
4657 EAPL("confirmation_key is missing or corrupted.\n"))); |
|
4658 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4659 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4660 } |
|
4661 |
|
4662 status = eapol_key_message->zero_key_MIC(m_am_tools); |
|
4663 if (status != eap_status_ok) |
|
4664 { |
|
4665 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4666 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4667 } |
|
4668 |
|
4669 crypto_hmac_c * hmac = 0; |
|
4670 abs_crypto_hash_algorithm_c * hash = 0; |
|
4671 |
|
4672 if (m_eapol_pairwise_cipher |
|
4673 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP |
|
4674 || m_eapol_group_cipher |
|
4675 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) |
|
4676 { |
|
4677 EAP_TRACE_DEBUG( |
|
4678 m_am_tools, |
|
4679 TRACE_FLAGS_DEFAULT, |
|
4680 (EAPL("EAPOL_KEY: HMAC-SHA1 MIC algorithm.\n"))); |
|
4681 |
|
4682 hash = new crypto_sha1_c(m_am_tools); |
|
4683 } |
|
4684 else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP |
|
4685 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40 |
|
4686 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) |
|
4687 { |
|
4688 EAP_TRACE_DEBUG( |
|
4689 m_am_tools, |
|
4690 TRACE_FLAGS_DEFAULT, |
|
4691 (EAPL("EAPOL_KEY: HMAC-MD5 MIC algorithm.\n"))); |
|
4692 |
|
4693 hash = new crypto_md5_c(m_am_tools); |
|
4694 } |
|
4695 else |
|
4696 { |
|
4697 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4698 return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); |
|
4699 } |
|
4700 |
|
4701 eap_automatic_variable_c<abs_crypto_hash_algorithm_c> automatic_hash(m_am_tools, hash); |
|
4702 |
|
4703 if (hash == 0 |
|
4704 || hash->get_is_valid() == false) |
|
4705 { |
|
4706 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4707 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4708 } |
|
4709 |
|
4710 hmac = new crypto_hmac_c(m_am_tools, hash, true); |
|
4711 automatic_hash.do_not_free_variable(); |
|
4712 eap_automatic_variable_c<crypto_hmac_c> automatic_hmac(m_am_tools, hmac); |
|
4713 if (hmac == 0 |
|
4714 || hmac->get_is_valid() == false) |
|
4715 { |
|
4716 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4717 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4718 } |
|
4719 |
|
4720 |
|
4721 EAP_TRACE_DATA_DEBUG( |
|
4722 m_am_tools, |
|
4723 TRACE_FLAGS_DEFAULT, |
|
4724 (EAPL("EAPOL-Key MIC key"), |
|
4725 confirmation_key->get_data(), |
|
4726 confirmation_key->get_data_length())); |
|
4727 |
|
4728 status = hmac->hmac_set_key(confirmation_key); |
|
4729 if (status != eap_status_ok) |
|
4730 { |
|
4731 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4732 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4733 } |
|
4734 |
|
4735 // MIC is calculated over the whole EAPOL-Key message. |
|
4736 status = hmac->hmac_update( |
|
4737 eapol_key_message->get_header_buffer( |
|
4738 eapol_key_message->get_header_buffer_length()), |
|
4739 eapol_key_message->get_eapol_packet_length()); |
|
4740 if (status != eap_status_ok) |
|
4741 { |
|
4742 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4743 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4744 } |
|
4745 |
|
4746 EAP_TRACE_DATA_DEBUG( |
|
4747 m_am_tools, |
|
4748 TRACE_FLAGS_DEFAULT, |
|
4749 (EAPL("EAPOL-Key MIC data"), |
|
4750 eapol_key_message->get_header_buffer( |
|
4751 eapol_key_message->get_header_buffer_length()), |
|
4752 eapol_key_message->get_eapol_packet_length())); |
|
4753 |
|
4754 |
|
4755 { |
|
4756 eap_variable_data_c mic(m_am_tools); |
|
4757 |
|
4758 status = mic.set_buffer_length(hmac->get_digest_length()); |
|
4759 if (status != eap_status_ok) |
|
4760 { |
|
4761 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4762 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4763 } |
|
4764 mic.set_data_length(hmac->get_digest_length()); |
|
4765 |
|
4766 u32_t md_length = hmac->get_digest_length(); |
|
4767 |
|
4768 status = hmac->hmac_final( |
|
4769 mic.get_data(hmac->get_digest_length()), |
|
4770 &md_length); |
|
4771 if (status != eap_status_ok) |
|
4772 { |
|
4773 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4774 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4775 } |
|
4776 |
|
4777 if (md_length < eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE) |
|
4778 { |
|
4779 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4780 return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short); |
|
4781 } |
|
4782 |
|
4783 // This cuts the PMKID to 128 bits. |
|
4784 mic.set_data_length(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE); |
|
4785 |
|
4786 // Copy MIC to EAPOL-Key message. |
|
4787 m_am_tools->memmove( |
|
4788 eapol_key_message->get_key_MIC(), |
|
4789 mic.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE), |
|
4790 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE); |
|
4791 |
|
4792 EAP_TRACE_DATA_DEBUG( |
|
4793 m_am_tools, |
|
4794 TRACE_FLAGS_DEFAULT, |
|
4795 (EAPL("EAPOL-Key message"), |
|
4796 eapol_key_message->get_header_buffer( |
|
4797 eapol_key_message->get_header_buffer_length()), |
|
4798 eapol_key_message->get_eapol_packet_length())); |
|
4799 } |
|
4800 |
|
4801 |
|
4802 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4803 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4804 } |
|
4805 |
|
4806 //-------------------------------------------------- |
|
4807 |
|
4808 // |
|
4809 eap_status_e eapol_key_state_c::verify_key_mic( |
|
4810 eapol_RSNA_key_header_c * const eapol_key_message, |
|
4811 const eap_variable_data_c * const confirmation_key) |
|
4812 { |
|
4813 eap_variable_data_c original_MIC(m_am_tools); |
|
4814 |
|
4815 // Here we save the original received MIC. |
|
4816 eap_status_e status = original_MIC.set_copy_of_buffer( |
|
4817 eapol_key_message->get_key_MIC(), |
|
4818 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE); |
|
4819 if (status != eap_status_ok) |
|
4820 { |
|
4821 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4822 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4823 } |
|
4824 |
|
4825 // This function writes a new MIC to message. |
|
4826 status = create_key_mic( |
|
4827 eapol_key_message, |
|
4828 confirmation_key); |
|
4829 if (status != eap_status_ok) |
|
4830 { |
|
4831 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4832 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4833 } |
|
4834 |
|
4835 // This will compare the saved original MIC and new created MIC are the same. |
|
4836 if (m_am_tools->memcmp( |
|
4837 original_MIC.get_data(original_MIC.get_data_length()), |
|
4838 eapol_key_message->get_key_MIC(), |
|
4839 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE) != 0) |
|
4840 { |
|
4841 // MIC failure. |
|
4842 EAP_TRACE_ERROR( |
|
4843 m_am_tools, |
|
4844 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4845 (EAPL("ERROR: EAPOL_KEY: MIC failed.\n"))); |
|
4846 EAP_TRACE_DATA_ERROR( |
|
4847 m_am_tools, |
|
4848 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4849 (EAPL("Received MIC"), |
|
4850 original_MIC.get_data(original_MIC.get_data_length()), |
|
4851 original_MIC.get_data_length())); |
|
4852 EAP_TRACE_DATA_ERROR( |
|
4853 m_am_tools, |
|
4854 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
4855 (EAPL(" Local MIC"), |
|
4856 eapol_key_message->get_key_MIC(), |
|
4857 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE)); |
|
4858 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4859 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
4860 } |
|
4861 else |
|
4862 { |
|
4863 EAP_TRACE_DEBUG( |
|
4864 m_am_tools, |
|
4865 TRACE_FLAGS_DEFAULT, |
|
4866 (EAPL("EAPOL_KEY: MIC OK.\n"))); |
|
4867 } |
|
4868 |
|
4869 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4870 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
4871 } |
|
4872 |
|
4873 //-------------------------------------------------- |
|
4874 |
|
4875 // |
|
4876 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::add_RSN_GTK_payload( |
|
4877 const eapol_RSNA_key_header_c * const eapol_key_message, |
|
4878 eap_variable_data_c * const group_GTK, |
|
4879 u32_t * const eapol_data_length) |
|
4880 { |
|
4881 // Add GTK to Key Data. |
|
4882 |
|
4883 if (eapol_key_message == 0 |
|
4884 || eapol_key_message->get_is_valid() == false |
|
4885 || group_GTK == 0 |
|
4886 || group_GTK->get_is_valid_data() == false |
|
4887 || eapol_data_length == 0) |
|
4888 { |
|
4889 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4890 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4891 } |
|
4892 |
|
4893 u32_t GTK_length = group_GTK->get_data_length(); |
|
4894 |
|
4895 u32_t gtk_data_length = |
|
4896 eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_HEADER_SIZE |
|
4897 + GTK_length; |
|
4898 |
|
4899 u32_t key_data_buffer_length = |
|
4900 eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_HEADER_LENGTH |
|
4901 + gtk_data_length; |
|
4902 |
|
4903 eapol_rsna_key_data_header_c key_data_header( |
|
4904 m_am_tools, |
|
4905 get_is_RSNA(), |
|
4906 get_is_WPXM(), |
|
4907 eapol_key_message->get_key_data_offset(*eapol_data_length, key_data_buffer_length), |
|
4908 key_data_buffer_length); |
|
4909 if (key_data_header.get_is_valid() == false) |
|
4910 { |
|
4911 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4912 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4913 } |
|
4914 |
|
4915 eap_status_e status = key_data_header.reset_header(); |
|
4916 if (status != eap_status_ok) |
|
4917 { |
|
4918 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4919 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4920 } |
|
4921 |
|
4922 { |
|
4923 // Here Type and Length fields are NOT included. |
|
4924 u32_t key_data_length = |
|
4925 key_data_buffer_length |
|
4926 - 2ul; |
|
4927 |
|
4928 if (key_data_length > 0xff) |
|
4929 { |
|
4930 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4931 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message); |
|
4932 } |
|
4933 |
|
4934 status = key_data_header.set_length( |
|
4935 static_cast<u8_t>(key_data_length)); |
|
4936 if (status != eap_status_ok) |
|
4937 { |
|
4938 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4939 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4940 } |
|
4941 } |
|
4942 |
|
4943 status = key_data_header.set_payload_type(eapol_RSNA_key_payload_type_group_key_and_id); |
|
4944 if (status != eap_status_ok) |
|
4945 { |
|
4946 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4947 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4948 } |
|
4949 |
|
4950 EAP_TRACE_DATA_DEBUG( |
|
4951 m_am_tools, |
|
4952 TRACE_FLAGS_DEFAULT, |
|
4953 (EAPL("RSN Group Key"), |
|
4954 group_GTK->get_data(GTK_length), |
|
4955 GTK_length)); |
|
4956 |
|
4957 if (gtk_data_length == GTK_length + eapol_rsna_key_data_gtk_header_c::get_header_length()) |
|
4958 { |
|
4959 // Add authenticator GTK to Key Data. |
|
4960 eapol_rsna_key_data_gtk_header_c gtk_header( |
|
4961 m_am_tools, |
|
4962 key_data_header.get_key_data_payload(gtk_data_length), |
|
4963 gtk_data_length); |
|
4964 if (gtk_header.get_is_valid() == false) |
|
4965 { |
|
4966 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4967 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4968 } |
|
4969 |
|
4970 status = gtk_header.reset_header(); |
|
4971 if (status != eap_status_ok) |
|
4972 { |
|
4973 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4974 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4975 } |
|
4976 |
|
4977 m_group_GTK_ID = 1ul; |
|
4978 status = gtk_header.set_key_index(m_group_GTK_ID); |
|
4979 if (status != eap_status_ok) |
|
4980 { |
|
4981 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4982 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4983 } |
|
4984 |
|
4985 m_group_GTK_Tx_bit = true; |
|
4986 status = gtk_header.set_tx(m_group_GTK_Tx_bit); |
|
4987 if (status != eap_status_ok) |
|
4988 { |
|
4989 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4990 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4991 } |
|
4992 |
|
4993 u8_t * data_field_of_GTK |
|
4994 = gtk_header.get_gtk(GTK_length); |
|
4995 if (data_field_of_GTK == 0) |
|
4996 { |
|
4997 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4998 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4999 } |
|
5000 |
|
5001 m_am_tools->memmove( |
|
5002 data_field_of_GTK, |
|
5003 group_GTK->get_data(GTK_length), |
|
5004 GTK_length); |
|
5005 |
|
5006 EAP_TRACE_DEBUG( |
|
5007 m_am_tools, |
|
5008 TRACE_FLAGS_DEFAULT, |
|
5009 (EAPL("send RSN Group Key ID %d, Tx %d\n"), |
|
5010 gtk_header.get_key_index(), |
|
5011 gtk_header.get_tx_bit())); |
|
5012 |
|
5013 EAP_TRACE_DATA_DEBUG( |
|
5014 m_am_tools, |
|
5015 TRACE_FLAGS_DEFAULT, |
|
5016 (EAPL("send RSN Group Key payload"), |
|
5017 gtk_header.get_header_buffer(gtk_header.get_header_buffer_length()), |
|
5018 gtk_header.get_header_buffer_length())); |
|
5019 } |
|
5020 else |
|
5021 { |
|
5022 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5023 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5024 } |
|
5025 |
|
5026 *eapol_data_length += key_data_buffer_length; |
|
5027 |
|
5028 EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD( |
|
5029 get_is_RSNA(), |
|
5030 get_is_WPXM(), |
|
5031 eapol_key_message->get_key_descriptor_type(), |
|
5032 "Added EAPOL Key Data key_data_payload", |
|
5033 &key_data_header, |
|
5034 *eapol_data_length); |
|
5035 |
|
5036 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5037 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5038 } |
|
5039 |
|
5040 //-------------------------------------------------- |
|
5041 |
|
5042 // |
|
5043 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::add_RSN_IE_payload( |
|
5044 const eapol_RSNA_key_header_c * const eapol_key_message, |
|
5045 eap_variable_data_c * const RSNA_IE, |
|
5046 u32_t * const eapol_data_length) |
|
5047 { |
|
5048 // Add RSN IE to Key Data. |
|
5049 |
|
5050 if (eapol_key_message == 0 |
|
5051 || eapol_key_message->get_is_valid() == false |
|
5052 || RSNA_IE == 0 |
|
5053 || RSNA_IE->get_is_valid_data() == false |
|
5054 || eapol_data_length == 0) |
|
5055 { |
|
5056 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5057 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
5058 } |
|
5059 |
|
5060 u32_t rsn_ie_data_length(RSNA_IE->get_data_length()); |
|
5061 |
|
5062 u8_t * const data_field_of_RSN_IE |
|
5063 = reinterpret_cast<u8_t *>( |
|
5064 eapol_key_message->get_key_data_offset(*eapol_data_length, rsn_ie_data_length)); |
|
5065 if (data_field_of_RSN_IE == 0) |
|
5066 { |
|
5067 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5068 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5069 } |
|
5070 |
|
5071 m_am_tools->memmove( |
|
5072 data_field_of_RSN_IE, |
|
5073 RSNA_IE->get_data(rsn_ie_data_length), |
|
5074 rsn_ie_data_length); |
|
5075 |
|
5076 // NOTE, only two first bytes of RSN IE match with EAPOL Key Data. |
|
5077 eapol_rsna_key_data_header_c key_data_header( |
|
5078 m_am_tools, |
|
5079 get_is_RSNA(), |
|
5080 get_is_WPXM(), |
|
5081 data_field_of_RSN_IE, |
|
5082 rsn_ie_data_length); |
|
5083 if (key_data_header.get_is_valid() == false) |
|
5084 { |
|
5085 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5086 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5087 } |
|
5088 |
|
5089 *eapol_data_length += rsn_ie_data_length; |
|
5090 |
|
5091 EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD( |
|
5092 get_is_RSNA(), |
|
5093 get_is_WPXM(), |
|
5094 eapol_key_message->get_key_descriptor_type(), |
|
5095 "Added EAPOL RSN IE", |
|
5096 &key_data_header, |
|
5097 *eapol_data_length); |
|
5098 |
|
5099 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5100 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5101 } |
|
5102 |
|
5103 //-------------------------------------------------- |
|
5104 |
|
5105 // |
|
5106 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::process_eapol_key_frame( |
|
5107 const eap_am_network_id_c * const receive_network_id, |
|
5108 eap_general_header_base_c * const packet_data, |
|
5109 const u32_t packet_length) |
|
5110 { |
|
5111 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5112 |
|
5113 eap_status_e status = eap_status_not_supported; |
|
5114 |
|
5115 if (packet_length < eapol_header_wr_c::get_header_length() |
|
5116 || packet_data->get_header_buffer_length() < eapol_header_wr_c::get_header_length() |
|
5117 || packet_data->get_header_buffer_length() < packet_length) |
|
5118 { |
|
5119 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5120 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5121 } |
|
5122 |
|
5123 if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false) |
|
5124 { |
|
5125 EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, |
|
5126 (EAPL("EAPOL_KEY: eapol_key_state_c: process_eapol_key_frame(): m_pairwise_PMK_WPXK3 is not valid.\n"))); |
|
5127 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5128 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); |
|
5129 } |
|
5130 |
|
5131 eapol_header_wr_c eapol_header( |
|
5132 m_am_tools, |
|
5133 packet_data->get_header_buffer(packet_data->get_header_buffer_length()), |
|
5134 packet_data->get_header_buffer_length()); |
|
5135 if (eapol_header.get_is_valid() == false) |
|
5136 { |
|
5137 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5138 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5139 } |
|
5140 else if (eapol_header.check_header() != eap_status_ok) |
|
5141 { |
|
5142 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5143 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5144 } |
|
5145 |
|
5146 // Data length must be at least size of Descriptor Type. |
|
5147 const u32_t EAPOL_DESCRIPTOR_TYPE_LENGTH = sizeof(u8_t); |
|
5148 if (eapol_header.get_data_length() < EAPOL_DESCRIPTOR_TYPE_LENGTH) |
|
5149 { |
|
5150 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5151 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); |
|
5152 } |
|
5153 |
|
5154 const u8_t * const descriptor_type = eapol_header.get_data(EAPOL_DESCRIPTOR_TYPE_LENGTH); |
|
5155 if (descriptor_type == 0) |
|
5156 { |
|
5157 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5158 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); |
|
5159 } |
|
5160 |
|
5161 switch(static_cast<eapol_key_descriptor_type_e>(*descriptor_type)) |
|
5162 { |
|
5163 case eapol_key_descriptor_type_RC4: |
|
5164 status = process_RC4_key_descriptor(receive_network_id, packet_data, packet_length); |
|
5165 break; |
|
5166 case eapol_key_descriptor_type_RSNA: |
|
5167 case eapol_key_descriptor_type_WPA: |
|
5168 status = process_RSNA_key_descriptor(receive_network_id, packet_data, packet_length); |
|
5169 break; |
|
5170 default: |
|
5171 status = eap_status_not_supported; |
|
5172 break; |
|
5173 } |
|
5174 |
|
5175 if (status == eap_status_ok) |
|
5176 { |
|
5177 EAP_GENERAL_HEADER_SET_ERROR_DETECTED(packet_data, false); |
|
5178 } |
|
5179 |
|
5180 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5181 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5182 } |
|
5183 |
|
5184 //-------------------------------------------------- |
|
5185 |
|
5186 // |
|
5187 EAP_FUNC_EXPORT void eapol_key_state_c::set_is_valid() |
|
5188 { |
|
5189 m_is_valid = true; |
|
5190 } |
|
5191 |
|
5192 //-------------------------------------------------- |
|
5193 |
|
5194 // |
|
5195 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_valid() |
|
5196 { |
|
5197 return m_is_valid; |
|
5198 } |
|
5199 |
|
5200 //-------------------------------------------------- |
|
5201 |
|
5202 EAP_FUNC_EXPORT void eapol_key_state_c::object_increase_reference_count() |
|
5203 { |
|
5204 // Do nothing. |
|
5205 } |
|
5206 |
|
5207 //-------------------------------------------------- |
|
5208 |
|
5209 EAP_FUNC_EXPORT u32_t eapol_key_state_c::object_decrease_reference_count() |
|
5210 { |
|
5211 // Do nothing. |
|
5212 return 0ul; |
|
5213 } |
|
5214 |
|
5215 |
|
5216 //-------------------------------------------------- |
|
5217 |
|
5218 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_encryption_on() |
|
5219 { |
|
5220 /** |
|
5221 * @{ Add functionality of get_is_encryption_on() function } |
|
5222 */ |
|
5223 return false; |
|
5224 } |
|
5225 |
|
5226 //-------------------------------------------------- |
|
5227 |
|
5228 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
5229 |
|
5230 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_associated() |
|
5231 { |
|
5232 EAP_TRACE_DEBUG( |
|
5233 m_am_tools, |
|
5234 TRACE_FLAGS_DEFAULT, |
|
5235 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::get_is_associated(): m_is_associated=%s.\n"), |
|
5236 (m_is_client == true) ? "client": "server", |
|
5237 (m_is_associated == true) ? "true": "false")); |
|
5238 |
|
5239 return m_is_associated; |
|
5240 } |
|
5241 |
|
5242 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
5243 |
|
5244 //-------------------------------------------------- |
|
5245 |
|
5246 EAP_FUNC_EXPORT void eapol_key_state_c::set_eapol_key_state(const eapol_key_state_e state) |
|
5247 { |
|
5248 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5249 |
|
5250 eapol_key_state_string_c state_string; |
|
5251 |
|
5252 EAP_TRACE_DEBUG( |
|
5253 m_am_tools, |
|
5254 TRACE_FLAGS_DEFAULT, |
|
5255 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_eapol_key_state(): set_eapol_key_state() from %s to %s\n"), |
|
5256 (m_is_client == true ? "client": "server"), |
|
5257 state_string.get_eapol_key_state_string(m_eapol_key_state), |
|
5258 state_string.get_eapol_key_state_string(state))); |
|
5259 |
|
5260 m_eapol_key_state = state; |
|
5261 |
|
5262 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5263 } |
|
5264 |
|
5265 //-------------------------------------------------- |
|
5266 |
|
5267 EAP_FUNC_EXPORT eapol_key_state_e eapol_key_state_c::get_eapol_key_state() const |
|
5268 { |
|
5269 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5270 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5271 return m_eapol_key_state; |
|
5272 } |
|
5273 |
|
5274 //-------------------------------------------------- |
|
5275 |
|
5276 // |
|
5277 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::packet_send( |
|
5278 const eap_am_network_id_c * const send_network_id, |
|
5279 eap_buf_chain_wr_c * const sent_packet, |
|
5280 const u32_t header_offset, |
|
5281 const u32_t data_length, |
|
5282 const u32_t buffer_length) |
|
5283 { |
|
5284 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5285 |
|
5286 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5287 |
|
5288 cancel_retransmission(); |
|
5289 |
|
5290 if (m_is_client == false |
|
5291 && sent_packet->get_do_packet_retransmission() == true) |
|
5292 { |
|
5293 // Only EAPOL-server initializes re-transmission. |
|
5294 // EAPOL-server will re-transmit the packet when timer elapses and no response is received. |
|
5295 init_retransmission( |
|
5296 send_network_id, |
|
5297 sent_packet, |
|
5298 header_offset, |
|
5299 data_length, |
|
5300 eap_code_none, |
|
5301 0ul, |
|
5302 eap_type_none); |
|
5303 } |
|
5304 |
|
5305 |
|
5306 // NOTE: send packet directly to partner object of eapol_core_c object. |
|
5307 eap_status_e status = m_eapol_partner->packet_send( |
|
5308 send_network_id, |
|
5309 sent_packet, |
|
5310 header_offset, |
|
5311 data_length, |
|
5312 buffer_length); |
|
5313 |
|
5314 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5315 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5316 } |
|
5317 |
|
5318 //-------------------------------------------------- |
|
5319 |
|
5320 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::resend_packet( |
|
5321 const eap_am_network_id_c * const send_network_id, |
|
5322 eap_buf_chain_wr_c * const sent_packet, |
|
5323 const u32_t header_offset, |
|
5324 const u32_t data_length, |
|
5325 const u32_t buffer_length) |
|
5326 { |
|
5327 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5328 EAP_TRACE_DEBUG( |
|
5329 m_am_tools, |
|
5330 TRACE_FLAGS_DEFAULT, |
|
5331 (EAPL("<- EAPOL_KEY: %s: eapol_key_state_c::resend_packet().\n"), |
|
5332 (m_is_client == true) ? "client": "server")); |
|
5333 |
|
5334 // We make a copy because random error test may corrupt the data. |
|
5335 eap_buf_chain_wr_c * const copy_packet = sent_packet->copy(); |
|
5336 |
|
5337 if (copy_packet == 0) |
|
5338 { |
|
5339 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5340 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5341 } |
|
5342 |
|
5343 EAP_ASSERT(m_eapol_header_offset < sent_packet->get_data_length()); |
|
5344 EAP_ASSERT(data_length <= sent_packet->get_data_length()); |
|
5345 EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); |
|
5346 |
|
5347 // NOTE: send packet directly to partner object of eapol_core_c object. |
|
5348 // This will skip initialization of re-transmission for re-transmitted packet. |
|
5349 eap_status_e status = m_eapol_partner->packet_send( |
|
5350 send_network_id, |
|
5351 copy_packet, |
|
5352 header_offset, |
|
5353 data_length, |
|
5354 buffer_length |
|
5355 ); |
|
5356 |
|
5357 delete copy_packet; |
|
5358 |
|
5359 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5360 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5361 } |
|
5362 |
|
5363 //-------------------------------------------------- |
|
5364 |
|
5365 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_handshake_timeout() |
|
5366 { |
|
5367 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5368 |
|
5369 m_handshake_timeout_set = false; |
|
5370 |
|
5371 EAP_TRACE_DEBUG( |
|
5372 m_am_tools, |
|
5373 TRACE_FLAGS_DEFAULT, |
|
5374 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_handshake_timeout(): this = 0x%08x.\n"), |
|
5375 (m_is_client == true) ? "client": "server", |
|
5376 this)); |
|
5377 |
|
5378 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5379 |
|
5380 m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID); |
|
5381 |
|
5382 EAP_TRACE_DEBUG( |
|
5383 m_am_tools, |
|
5384 TRACE_FLAGS_DEFAULT, |
|
5385 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID cancelled.\n"), |
|
5386 (m_is_client == true ? "client": "server"))); |
|
5387 |
|
5388 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5389 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5390 } |
|
5391 |
|
5392 //-------------------------------------------------- |
|
5393 |
|
5394 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_handshake_timeout( |
|
5395 const u32_t timeout) |
|
5396 { |
|
5397 eapol_key_state_string_c state_string; |
|
5398 EAP_TRACE_DEBUG( |
|
5399 m_am_tools, |
|
5400 TRACE_FLAGS_DEFAULT, |
|
5401 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_handshake_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
5402 (m_is_client == true) ? "client": "server", |
|
5403 this, |
|
5404 get_eapol_key_state(), |
|
5405 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
5406 m_authentication_type, |
|
5407 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
5408 |
|
5409 if (m_handshake_timeout_set == true) |
|
5410 { |
|
5411 EAP_TRACE_DEBUG( |
|
5412 m_am_tools, |
|
5413 TRACE_FLAGS_DEFAULT, |
|
5414 (EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::init_handshake_timeout(): Already active.\n"))); |
|
5415 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5416 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5417 } |
|
5418 |
|
5419 m_handshake_timeout_set = true; |
|
5420 |
|
5421 eap_status_e status = m_key_state_partner->set_timer( |
|
5422 this, |
|
5423 EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID, |
|
5424 0, |
|
5425 timeout); |
|
5426 if (status != eap_status_ok) |
|
5427 { |
|
5428 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5429 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5430 } |
|
5431 |
|
5432 EAP_TRACE_DEBUG( |
|
5433 m_am_tools, |
|
5434 TRACE_FLAGS_DEFAULT, |
|
5435 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID set %d ms.\n"), |
|
5436 (m_is_client == true ? "client": "server"), |
|
5437 timeout)); |
|
5438 |
|
5439 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5440 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5441 } |
|
5442 |
|
5443 //-------------------------------------------------- |
|
5444 |
|
5445 eap_status_e eapol_key_state_c::cancel_reassociate_timeout() |
|
5446 { |
|
5447 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5448 |
|
5449 EAP_TRACE_DEBUG( |
|
5450 m_am_tools, |
|
5451 TRACE_FLAGS_DEFAULT, |
|
5452 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_reassociate_timeout(): this = 0x%08x.\n"), |
|
5453 (m_is_client == true) ? "client": "server", |
|
5454 this)); |
|
5455 |
|
5456 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5457 |
|
5458 m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID); |
|
5459 |
|
5460 EAP_TRACE_DEBUG( |
|
5461 m_am_tools, |
|
5462 TRACE_FLAGS_DEFAULT, |
|
5463 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID cancelled.\n"), |
|
5464 (m_is_client == true ? "client": "server"))); |
|
5465 |
|
5466 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5467 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5468 } |
|
5469 |
|
5470 //-------------------------------------------------- |
|
5471 |
|
5472 eap_status_e eapol_key_state_c::init_reassociate_timeout( |
|
5473 const u32_t timeout) |
|
5474 { |
|
5475 eapol_key_state_string_c state_string; |
|
5476 EAP_TRACE_DEBUG( |
|
5477 m_am_tools, |
|
5478 TRACE_FLAGS_DEFAULT, |
|
5479 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_reassociate_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
5480 (m_is_client == true) ? "client": "server", |
|
5481 this, |
|
5482 get_eapol_key_state(), |
|
5483 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
5484 m_authentication_type, |
|
5485 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
5486 |
|
5487 eap_status_e status = m_key_state_partner->set_timer( |
|
5488 this, |
|
5489 EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID, |
|
5490 0, |
|
5491 timeout); |
|
5492 if (status != eap_status_ok) |
|
5493 { |
|
5494 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5495 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5496 } |
|
5497 |
|
5498 EAP_TRACE_DEBUG( |
|
5499 m_am_tools, |
|
5500 TRACE_FLAGS_DEFAULT, |
|
5501 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID set %d ms.\n"), |
|
5502 (m_is_client == true ? "client": "server"), |
|
5503 timeout)); |
|
5504 |
|
5505 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5506 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5507 } |
|
5508 |
|
5509 //-------------------------------------------------- |
|
5510 |
|
5511 eap_status_e eapol_key_state_c::cancel_4_way_handshake_start_timeout() |
|
5512 { |
|
5513 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5514 |
|
5515 EAP_TRACE_DEBUG( |
|
5516 m_am_tools, |
|
5517 TRACE_FLAGS_DEFAULT, |
|
5518 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_4_way_handshake_start_timeout(): this = 0x%08x.\n"), |
|
5519 (m_is_client == true) ? "client": "server", |
|
5520 this)); |
|
5521 |
|
5522 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5523 |
|
5524 m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID); |
|
5525 |
|
5526 EAP_TRACE_DEBUG( |
|
5527 m_am_tools, |
|
5528 TRACE_FLAGS_DEFAULT, |
|
5529 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID cancelled.\n"), |
|
5530 (m_is_client == true ? "client": "server"))); |
|
5531 |
|
5532 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5533 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5534 } |
|
5535 |
|
5536 //-------------------------------------------------- |
|
5537 |
|
5538 eap_status_e eapol_key_state_c::init_4_way_handshake_start_timeout() |
|
5539 { |
|
5540 eapol_key_state_string_c state_string; |
|
5541 EAP_TRACE_DEBUG( |
|
5542 m_am_tools, |
|
5543 TRACE_FLAGS_DEFAULT, |
|
5544 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_4_way_handshake_start_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
5545 (m_is_client == true) ? "client": "server", |
|
5546 this, |
|
5547 get_eapol_key_state(), |
|
5548 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
5549 m_authentication_type, |
|
5550 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
5551 |
|
5552 eap_status_e status = m_key_state_partner->set_timer( |
|
5553 this, |
|
5554 EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID, |
|
5555 0, |
|
5556 EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT); |
|
5557 if (status != eap_status_ok) |
|
5558 { |
|
5559 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5560 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5561 } |
|
5562 |
|
5563 EAP_TRACE_DEBUG( |
|
5564 m_am_tools, |
|
5565 TRACE_FLAGS_DEFAULT, |
|
5566 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID set %d ms.\n"), |
|
5567 (m_is_client == true ? "client": "server"), |
|
5568 EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT)); |
|
5569 |
|
5570 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5571 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5572 } |
|
5573 |
|
5574 //-------------------------------------------------- |
|
5575 |
|
5576 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_pmksa_caching_timeout() |
|
5577 { |
|
5578 EAP_TRACE_DEBUG( |
|
5579 m_am_tools, |
|
5580 TRACE_FLAGS_DEFAULT, |
|
5581 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_pmksa_caching_timeout(): this = 0x%08x.\n"), |
|
5582 (m_is_client == true) ? "client": "server", |
|
5583 this)); |
|
5584 |
|
5585 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5586 |
|
5587 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5588 |
|
5589 m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID); |
|
5590 |
|
5591 EAP_TRACE_DEBUG( |
|
5592 m_am_tools, |
|
5593 TRACE_FLAGS_DEFAULT, |
|
5594 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID cancelled.\n"), |
|
5595 (m_is_client == true ? "client": "server"))); |
|
5596 |
|
5597 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5598 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5599 } |
|
5600 |
|
5601 //-------------------------------------------------- |
|
5602 |
|
5603 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_authentication_session() |
|
5604 { |
|
5605 eapol_key_state_string_c state_string; |
|
5606 EAP_TRACE_DEBUG( |
|
5607 m_am_tools, |
|
5608 TRACE_FLAGS_DEFAULT, |
|
5609 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_authentication_session(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
5610 (m_is_client == true) ? "client": "server", |
|
5611 this, |
|
5612 get_eapol_key_state(), |
|
5613 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
5614 m_authentication_type, |
|
5615 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
5616 |
|
5617 eap_status_e status(eap_status_process_general_error); |
|
5618 |
|
5619 // RSNA could cache the current PMKSA. |
|
5620 status = init_pmksa_caching_timeout(); |
|
5621 |
|
5622 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5623 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5624 } |
|
5625 |
|
5626 //-------------------------------------------------- |
|
5627 |
|
5628 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_pmksa_caching_timeout() |
|
5629 { |
|
5630 eapol_key_state_string_c state_string; |
|
5631 EAP_TRACE_DEBUG( |
|
5632 m_am_tools, |
|
5633 TRACE_FLAGS_DEFAULT, |
|
5634 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_pmksa_caching_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
5635 (m_is_client == true) ? "client": "server", |
|
5636 this, |
|
5637 get_eapol_key_state(), |
|
5638 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
5639 m_authentication_type, |
|
5640 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
5641 |
|
5642 eap_status_e status(eap_status_process_general_error); |
|
5643 |
|
5644 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
5645 { |
|
5646 m_is_associated = false; |
|
5647 |
|
5648 EAP_TRACE_DEBUG( |
|
5649 m_am_tools, |
|
5650 TRACE_FLAGS_DEFAULT, |
|
5651 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_pmksa_caching_timeout(): m_is_associated=%s.\n"), |
|
5652 (m_is_client == true) ? "client": "server", |
|
5653 (m_is_associated == true) ? "true": "false")); |
|
5654 } |
|
5655 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
5656 |
|
5657 if ((m_authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
5658 #if defined(EAP_USE_WPXM) |
|
5659 || get_is_WPXM() == true |
|
5660 #endif //#if defined(EAP_USE_WPXM) |
|
5661 ) |
|
5662 && (get_eapol_key_state() == eapol_key_state_4_way_handshake_successfull |
|
5663 || get_eapol_key_state() == eapol_key_state_group_key_handshake_successfull |
|
5664 || get_eapol_key_state() == eapol_key_state_preauthenticated |
|
5665 #if defined(EAP_USE_WPXM) |
|
5666 || get_eapol_key_state() == eapol_key_state_wpxm_reassociation_finished_successfull |
|
5667 #endif //#if defined(EAP_USE_WPXM) |
|
5668 )) |
|
5669 { |
|
5670 set_eapol_key_state(eapol_key_state_preauthenticated); |
|
5671 reset_cached_pmksa(); |
|
5672 |
|
5673 u32_t timeout(m_pmksa_caching_timeout); |
|
5674 |
|
5675 #if defined(EAP_USE_WPXM) |
|
5676 if (get_is_WPXM() == true) |
|
5677 { |
|
5678 timeout = EAPOL_KEY_STATE_TIMER_WPXM_CACHE_TIMEOUT; |
|
5679 } |
|
5680 #endif //#if defined(EAP_USE_WPXM) |
|
5681 |
|
5682 status = m_key_state_partner->set_timer( |
|
5683 this, |
|
5684 EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID, |
|
5685 0, |
|
5686 timeout); |
|
5687 if (status != eap_status_ok) |
|
5688 { |
|
5689 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5690 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5691 } |
|
5692 |
|
5693 EAP_TRACE_DEBUG( |
|
5694 m_am_tools, |
|
5695 TRACE_FLAGS_DEFAULT, |
|
5696 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID set %d ms.\n"), |
|
5697 (m_is_client == true ? "client": "server"), |
|
5698 m_pmksa_caching_timeout)); |
|
5699 |
|
5700 set_eapol_key_state(eapol_key_state_preauthenticated); |
|
5701 } |
|
5702 else |
|
5703 { |
|
5704 EAP_TRACE_DEBUG( |
|
5705 m_am_tools, |
|
5706 TRACE_FLAGS_DEFAULT, |
|
5707 (EAPL("%s: Removes PMKSA cache\n"), |
|
5708 (m_is_client == true ? "client": "server"))); |
|
5709 |
|
5710 // Other authentication modes do not use PMKSA cache, clean-up state. |
|
5711 reset(); |
|
5712 |
|
5713 // Timeout value zero will remove state immediately. |
|
5714 status = init_handshake_timeout(0ul); |
|
5715 if (status != eap_status_ok) |
|
5716 { |
|
5717 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5718 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5719 } |
|
5720 } |
|
5721 |
|
5722 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5723 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5724 } |
|
5725 |
|
5726 //-------------------------------------------------- |
|
5727 |
|
5728 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_retransmission() |
|
5729 { |
|
5730 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5731 |
|
5732 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5733 |
|
5734 if (m_is_client == false) |
|
5735 { |
|
5736 // Only EAP-server uses timer to re-transmits EAP-packets. |
|
5737 m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID); |
|
5738 } |
|
5739 |
|
5740 if (m_retransmission != 0) |
|
5741 { |
|
5742 EAP_TRACE_DEBUG( |
|
5743 m_am_tools, |
|
5744 TRACE_FLAGS_DEFAULT, |
|
5745 (EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID cancelled.\n"))); |
|
5746 |
|
5747 if (m_retransmission != 0) |
|
5748 { |
|
5749 delete m_retransmission; |
|
5750 m_retransmission = 0; |
|
5751 } |
|
5752 } |
|
5753 |
|
5754 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5755 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5756 } |
|
5757 |
|
5758 //-------------------------------------------------- |
|
5759 |
|
5760 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_retransmission( |
|
5761 const eap_am_network_id_c * const send_network_id, |
|
5762 eap_buf_chain_wr_c * const sent_packet, |
|
5763 const u32_t header_offset, |
|
5764 const u32_t data_length, |
|
5765 const eap_code_value_e eap_code, |
|
5766 const u8_t eap_identifier, |
|
5767 const eap_type_value_e eap_type |
|
5768 ) |
|
5769 { |
|
5770 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5771 |
|
5772 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5773 |
|
5774 if (m_retransmission_time == 0u |
|
5775 || m_retransmission_counter == 0u) |
|
5776 { |
|
5777 // No retransmission. |
|
5778 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5779 } |
|
5780 |
|
5781 EAP_ASSERT(send_network_id->get_source() != 0); |
|
5782 EAP_ASSERT(send_network_id->get_destination() != 0); |
|
5783 |
|
5784 if (m_is_client == false) |
|
5785 { |
|
5786 // Only EAP-server uses timer to re-transmits EAP-packets. |
|
5787 m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID); |
|
5788 } |
|
5789 |
|
5790 if (m_retransmission != 0) |
|
5791 { |
|
5792 delete m_retransmission; |
|
5793 m_retransmission = 0; |
|
5794 } |
|
5795 |
|
5796 m_retransmission = new eap_core_retransmission_c( |
|
5797 m_am_tools, |
|
5798 send_network_id, |
|
5799 sent_packet, |
|
5800 header_offset, |
|
5801 data_length, |
|
5802 m_retransmission_time, |
|
5803 m_retransmission_counter, |
|
5804 eap_code, |
|
5805 eap_identifier, |
|
5806 eap_type |
|
5807 ); |
|
5808 |
|
5809 if (m_retransmission == 0) |
|
5810 { |
|
5811 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5812 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5813 } |
|
5814 |
|
5815 if (m_retransmission->get_is_valid() == true) |
|
5816 { |
|
5817 // Because this object do re-transmission other layers must not do re-transmission of this packet. |
|
5818 sent_packet->set_do_packet_retransmission(false); |
|
5819 |
|
5820 if (m_is_client == false) |
|
5821 { |
|
5822 // Only EAP-server uses timer to re-transmits EAP-packets. |
|
5823 u32_t next_retransmission_time(m_retransmission->get_next_retransmission_time()); |
|
5824 |
|
5825 eap_status_e status = m_key_state_partner->set_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, 0, |
|
5826 next_retransmission_time); |
|
5827 if (status != eap_status_ok) |
|
5828 { |
|
5829 delete m_retransmission; |
|
5830 m_retransmission = 0; |
|
5831 } |
|
5832 |
|
5833 EAP_TRACE_DEBUG( |
|
5834 m_am_tools, |
|
5835 TRACE_FLAGS_DEFAULT, |
|
5836 (EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID set %d ms.\n"), |
|
5837 next_retransmission_time)); |
|
5838 |
|
5839 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5840 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5841 } |
|
5842 else |
|
5843 { |
|
5844 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5845 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5846 } |
|
5847 } |
|
5848 else |
|
5849 { |
|
5850 delete m_retransmission; |
|
5851 m_retransmission = 0; |
|
5852 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5853 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5854 } |
|
5855 |
|
5856 } |
|
5857 |
|
5858 //-------------------------------------------------- |
|
5859 |
|
5860 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_group_key_update_timeout() |
|
5861 { |
|
5862 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5863 |
|
5864 EAP_TRACE_DEBUG( |
|
5865 m_am_tools, |
|
5866 TRACE_FLAGS_DEFAULT, |
|
5867 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_group_key_update_timeout(): this = 0x%08x.\n"), |
|
5868 (m_is_client == true) ? "client": "server", |
|
5869 this)); |
|
5870 |
|
5871 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5872 |
|
5873 m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID); |
|
5874 |
|
5875 EAP_TRACE_DEBUG( |
|
5876 m_am_tools, |
|
5877 TRACE_FLAGS_DEFAULT, |
|
5878 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID cancelled.\n"), |
|
5879 (m_is_client == true ? "client": "server"))); |
|
5880 |
|
5881 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5882 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5883 } |
|
5884 |
|
5885 //-------------------------------------------------- |
|
5886 |
|
5887 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_group_key_update_timeout( |
|
5888 const u32_t timeout) |
|
5889 { |
|
5890 eapol_key_state_string_c state_string; |
|
5891 EAP_TRACE_DEBUG( |
|
5892 m_am_tools, |
|
5893 TRACE_FLAGS_DEFAULT, |
|
5894 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_group_key_update_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
5895 (m_is_client == true) ? "client": "server", |
|
5896 this, |
|
5897 get_eapol_key_state(), |
|
5898 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
5899 m_authentication_type, |
|
5900 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
5901 |
|
5902 eap_status_e status = m_key_state_partner->set_timer( |
|
5903 this, |
|
5904 EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID, |
|
5905 0, |
|
5906 timeout); |
|
5907 if (status != eap_status_ok) |
|
5908 { |
|
5909 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5910 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5911 } |
|
5912 |
|
5913 EAP_TRACE_DEBUG( |
|
5914 m_am_tools, |
|
5915 TRACE_FLAGS_DEFAULT, |
|
5916 (EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID set %d ms.\n"), |
|
5917 (m_is_client == true ? "client": "server"), |
|
5918 timeout)); |
|
5919 |
|
5920 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5921 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5922 } |
|
5923 |
|
5924 //-------------------------------------------------- |
|
5925 |
|
5926 // |
|
5927 EAP_FUNC_EXPORT bool eapol_key_state_c::get_marked_removed() |
|
5928 { |
|
5929 return m_marked_removed; |
|
5930 } |
|
5931 |
|
5932 //-------------------------------------------------- |
|
5933 |
|
5934 // |
|
5935 EAP_FUNC_EXPORT void eapol_key_state_c::set_marked_removed() |
|
5936 { |
|
5937 m_marked_removed = true; |
|
5938 } |
|
5939 |
|
5940 //-------------------------------------------------- |
|
5941 |
|
5942 // |
|
5943 EAP_FUNC_EXPORT void eapol_key_state_c::unset_marked_removed() |
|
5944 { |
|
5945 m_marked_removed = false; |
|
5946 } |
|
5947 |
|
5948 //-------------------------------------------------- |
|
5949 |
|
5950 // |
|
5951 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::reset_cached_pmksa() |
|
5952 { |
|
5953 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5954 |
|
5955 eapol_key_state_string_c state_string; |
|
5956 EAP_TRACE_DEBUG( |
|
5957 m_am_tools, |
|
5958 TRACE_FLAGS_DEFAULT, |
|
5959 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"), |
|
5960 (m_is_client == true) ? "client": "server", |
|
5961 this, |
|
5962 get_eapol_key_state(), |
|
5963 state_string.get_eapol_key_state_string(get_eapol_key_state()), |
|
5964 m_authentication_type, |
|
5965 state_string.get_eapol_key_authentication_type_string(m_authentication_type))); |
|
5966 |
|
5967 eap_status_e status = eap_status_ok; |
|
5968 |
|
5969 for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++) |
|
5970 { |
|
5971 m_received_802_1x_keys[key_type] = false; |
|
5972 } |
|
5973 |
|
5974 (void) cancel_retransmission(); |
|
5975 (void) cancel_handshake_timeout(); |
|
5976 (void) cancel_pmksa_caching_timeout(); |
|
5977 (void) cancel_reassociate_timeout(); |
|
5978 (void) cancel_4_way_handshake_start_timeout(); |
|
5979 |
|
5980 if (get_eapol_key_state() == eapol_key_state_preauthenticated) |
|
5981 { |
|
5982 // We must save the preauthenticated PMK and authentication type. |
|
5983 EAP_TRACE_DEBUG( |
|
5984 m_am_tools, |
|
5985 TRACE_FLAGS_DEFAULT, |
|
5986 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): OK save PMKSA.\n"), |
|
5987 (m_is_client == true) ? "client": "server")); |
|
5988 } |
|
5989 else |
|
5990 { |
|
5991 // In other states PMK and authentication type is reset. |
|
5992 EAP_TRACE_DEBUG( |
|
5993 m_am_tools, |
|
5994 TRACE_FLAGS_DEFAULT, |
|
5995 (EAPL("WARNING: EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): removes PMKSA.\n"), |
|
5996 (m_is_client == true) ? "client": "server")); |
|
5997 |
|
5998 if (m_is_client == true) |
|
5999 { |
|
6000 // Only client resets these pameters, test server will need these parameters. |
|
6001 |
|
6002 m_pairwise_PMK_WPXK3.reset(); |
|
6003 |
|
6004 // Cannot reset m_authentication_type and m_eapol_key_state. These are needed later when possible error notification is send to lower layer. |
|
6005 |
|
6006 m_supplicant_MAC_address.reset(); |
|
6007 m_authenticator_MAC_address.reset(); |
|
6008 |
|
6009 m_eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none; |
|
6010 m_eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none; |
|
6011 |
|
6012 m_authenticator_RSNA_IE.reset(); |
|
6013 m_supplicant_RSNA_IE.reset(); |
|
6014 |
|
6015 #if defined(EAP_USE_WPXM) |
|
6016 m_WPXM_WPXK1.reset(); |
|
6017 m_WPXM_WPXK2.reset(); |
|
6018 m_WPXM_WPXC = eapol_key_constant_wpxm_initial_wpxc_counter_value; |
|
6019 |
|
6020 EAP_TRACE_DEBUG( |
|
6021 m_am_tools, |
|
6022 TRACE_FLAGS_DEFAULT, |
|
6023 (EAPL("EAPOL_KEY: eapol_key_state_c::reset_cached_pmksa(): ") |
|
6024 EAPL("Reset m_WPXM_WPXC=%d.\n"), |
|
6025 m_WPXM_WPXC)); |
|
6026 #endif //#if defined(EAP_USE_WPXM) |
|
6027 |
|
6028 } |
|
6029 else |
|
6030 { |
|
6031 set_eapol_key_state(eapol_key_state_none); |
|
6032 } |
|
6033 |
|
6034 m_PMKID.reset(); |
|
6035 m_transient_PTK.reset(); |
|
6036 m_confirmation_KCK.reset(); |
|
6037 m_encryption_KEK.reset(); |
|
6038 m_temporal_TK.reset(); |
|
6039 |
|
6040 // Cannot remove m_send_network_id because it is used |
|
6041 // as a reference of this eapol_key_state_c object. |
|
6042 |
|
6043 m_ANonce.reset(); |
|
6044 m_SNonce.reset(); |
|
6045 |
|
6046 } |
|
6047 |
|
6048 m_received_PMKID.reset(); |
|
6049 m_unicast_cipher_suite_RSNA_IE.reset(); |
|
6050 m_EAPOL_key_IV.reset(); |
|
6051 |
|
6052 if (m_is_client == true) |
|
6053 { |
|
6054 set_key_reply_counter(0ul); |
|
6055 set_client_send_key_reply_counter(0ul); |
|
6056 |
|
6057 // Cannot reset m_eapol_key_handshake_type. This is needed later when possible error notification is send to lower layer. |
|
6058 } |
|
6059 else |
|
6060 { |
|
6061 m_eapol_key_handshake_type = eapol_key_handshake_type_none; |
|
6062 } |
|
6063 |
|
6064 |
|
6065 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6066 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6067 } |
|
6068 |
|
6069 //-------------------------------------------------- |
|
6070 |
|
6071 // |
|
6072 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::reset() |
|
6073 { |
|
6074 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6075 |
|
6076 EAP_TRACE_DEBUG( |
|
6077 m_am_tools, |
|
6078 TRACE_FLAGS_DEFAULT, |
|
6079 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset(): this = 0x%08x.\n"), |
|
6080 (m_is_client == true) ? "client": "server", |
|
6081 this)); |
|
6082 |
|
6083 eap_status_e status = reset_cached_pmksa(); |
|
6084 |
|
6085 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6086 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6087 } |
|
6088 |
|
6089 //-------------------------------------------------- |
|
6090 |
|
6091 // |
|
6092 eap_status_e eapol_key_state_c::create_tkip_mic_failure_message( |
|
6093 eap_buf_chain_wr_c * const sent_packet, |
|
6094 const u32_t eapol_header_offset, |
|
6095 u32_t * const data_length, |
|
6096 u32_t * const buffer_length, |
|
6097 const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type, |
|
6098 const eapol_protocol_version_e received_eapol_version) |
|
6099 { |
|
6100 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6101 eap_status_e status = eap_status_process_general_error; |
|
6102 |
|
6103 EAP_TRACE_DEBUG( |
|
6104 m_am_tools, |
|
6105 TRACE_FLAGS_DEFAULT, |
|
6106 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_tkip_mic_failure_message()\n"), |
|
6107 (m_is_client == true ? "client": "server"))); |
|
6108 |
|
6109 // Only client (Supplicant) could create TKIP MIC failure message. |
|
6110 EAP_ASSERT_ALWAYS(m_is_client == true); |
|
6111 |
|
6112 u32_t eapol_key_data_length |
|
6113 = eapol_RSNA_key_header_c::get_header_length(); |
|
6114 |
|
6115 *buffer_length |
|
6116 = eapol_header_offset |
|
6117 + eapol_key_data_length; |
|
6118 |
|
6119 status = sent_packet->set_buffer_length( |
|
6120 *buffer_length); |
|
6121 if (status != eap_status_ok) |
|
6122 { |
|
6123 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6124 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6125 } |
|
6126 sent_packet->set_data_length( |
|
6127 sent_packet->get_buffer_length()); |
|
6128 |
|
6129 eapol_RSNA_key_header_c eapol_key_message( |
|
6130 m_am_tools, |
|
6131 get_is_RSNA(), |
|
6132 get_is_WPXM(), |
|
6133 sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length), |
|
6134 sent_packet->get_data_length()); |
|
6135 |
|
6136 if (eapol_key_message.get_is_valid() == false) |
|
6137 { |
|
6138 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6139 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
6140 } |
|
6141 |
|
6142 bool pairwise_key = true; |
|
6143 if (tkip_mic_failure_type == eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_group_key) |
|
6144 { |
|
6145 pairwise_key = false; |
|
6146 } |
|
6147 |
|
6148 status = eapol_key_message.reset_header( |
|
6149 0ul, |
|
6150 m_authentication_type, |
|
6151 m_eapol_pairwise_cipher, |
|
6152 get_client_send_key_reply_counter(), |
|
6153 pairwise_key, // Pairwise key type bit. |
|
6154 false, // Install bit is NOT set. |
|
6155 false, // Key Ack bit is NOT set. |
|
6156 true, // Key MIC bit is on. |
|
6157 false, // Secure bit is NOT set. |
|
6158 true, // Error bit is on. |
|
6159 true, // Request bit is on. |
|
6160 false, // STAKey bit is NOT set. |
|
6161 false, // Encrypted Key Data bit is NOT set. |
|
6162 received_eapol_version, |
|
6163 eapol_key_descriptor_type_none); |
|
6164 if (status != eap_status_ok) |
|
6165 { |
|
6166 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6167 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6168 } |
|
6169 |
|
6170 increase_client_send_key_reply_counter(); |
|
6171 |
|
6172 status = eapol_key_message.set_key_data_length(0ul); |
|
6173 if (status != eap_status_ok) |
|
6174 { |
|
6175 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6176 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6177 } |
|
6178 |
|
6179 *data_length |
|
6180 = eapol_key_message.get_header_length() |
|
6181 + eapol_key_message.get_key_data_length(); |
|
6182 |
|
6183 status = eapol_key_message.set_eapol_packet_body_length( |
|
6184 static_cast<u16_t>(*data_length - eapol_header_base_c::get_header_length())); |
|
6185 if (status != eap_status_ok) |
|
6186 { |
|
6187 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6188 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6189 } |
|
6190 |
|
6191 status = create_key_mic(&eapol_key_message, &m_confirmation_KCK); |
|
6192 if (status != eap_status_ok) |
|
6193 { |
|
6194 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6195 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6196 } |
|
6197 |
|
6198 sent_packet->set_data_length( |
|
6199 eapol_header_offset + *data_length); |
|
6200 |
|
6201 TRACE_EAPOL_KEY_MESSAGE( |
|
6202 "Send TKIP MIC failure Message", |
|
6203 &eapol_key_message); |
|
6204 |
|
6205 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6206 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6207 } |
|
6208 |
|
6209 //-------------------------------------------------- |
|
6210 |
|
6211 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::tkip_mic_failure( |
|
6212 const bool fatal_failure_when_true, |
|
6213 const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type) |
|
6214 { |
|
6215 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6216 |
|
6217 EAP_UNREFERENCED_PARAMETER(fatal_failure_when_true); |
|
6218 |
|
6219 EAP_TRACE_DEBUG( |
|
6220 m_am_tools, |
|
6221 TRACE_FLAGS_DEFAULT, |
|
6222 (EAPL("eapol_am_core_symbian_c::tkip_mic_failure(%d, %d).\n"), |
|
6223 fatal_failure_when_true, |
|
6224 tkip_mic_failure_type)); |
|
6225 |
|
6226 eap_status_e status = eap_status_not_supported; |
|
6227 |
|
6228 eap_buf_chain_wr_c sent_packet( |
|
6229 eap_write_buffer, |
|
6230 m_am_tools); |
|
6231 |
|
6232 if (sent_packet.get_is_valid() == false) |
|
6233 { |
|
6234 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
6235 } |
|
6236 |
|
6237 u32_t send_data_length = 0ul; |
|
6238 u32_t send_buffer_length = 0ul; |
|
6239 |
|
6240 status = create_tkip_mic_failure_message( |
|
6241 &sent_packet, |
|
6242 m_eapol_header_offset, |
|
6243 &send_data_length, |
|
6244 &send_buffer_length, |
|
6245 tkip_mic_failure_type, |
|
6246 eapol_protocol_version_2); |
|
6247 if (status != eap_status_ok) |
|
6248 { |
|
6249 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6250 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6251 } |
|
6252 |
|
6253 |
|
6254 status = packet_send( |
|
6255 &m_send_network_id, |
|
6256 &sent_packet, |
|
6257 m_eapol_header_offset, |
|
6258 send_data_length, |
|
6259 send_buffer_length); |
|
6260 if (status != eap_status_ok) |
|
6261 { |
|
6262 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6263 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6264 } |
|
6265 |
|
6266 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6267 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6268 } |
|
6269 |
|
6270 //-------------------------------------------------- |
|
6271 |
|
6272 // |
|
6273 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::set_pairwise_PMK( |
|
6274 const eap_variable_data_c * const key, |
|
6275 const eap_am_network_id_c * const send_network_id) |
|
6276 { |
|
6277 if (key == 0 |
|
6278 || key->get_is_valid_data() == false |
|
6279 || key->get_data_length() == 0ul) |
|
6280 { |
|
6281 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6282 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
6283 } |
|
6284 |
|
6285 u32_t pmk_key_length = key->get_data_length(); |
|
6286 |
|
6287 if (m_authentication_type == eapol_key_authentication_type_none) |
|
6288 { |
|
6289 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6290 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
6291 } |
|
6292 else if (m_authentication_type != eapol_key_authentication_type_802_1X) |
|
6293 { |
|
6294 // Truncate PMK only in WPA and RSN case |
|
6295 if (pmk_key_length > EAPOL_RSNA_PMK_LENGTH_BYTES) |
|
6296 { |
|
6297 pmk_key_length = EAPOL_RSNA_PMK_LENGTH_BYTES; |
|
6298 } |
|
6299 else if (pmk_key_length < EAPOL_RSNA_PMK_LENGTH_BYTES) |
|
6300 { |
|
6301 // No need to expand key. The short key is used as is. |
|
6302 } |
|
6303 } |
|
6304 |
|
6305 |
|
6306 if (send_network_id->get_type() == eapol_ethernet_type_preauthentication) |
|
6307 { |
|
6308 set_eapol_key_state(eapol_key_state_preauthenticated); |
|
6309 } |
|
6310 |
|
6311 |
|
6312 EAP_TRACE_DATA_DEBUG( |
|
6313 m_am_tools, |
|
6314 TRACE_FLAGS_DEFAULT, |
|
6315 (EAPL("eapol_key_state_c::set_pairwise_PMK(): key"), |
|
6316 key->get_data(pmk_key_length), |
|
6317 pmk_key_length)); |
|
6318 |
|
6319 eap_status_e status = m_pairwise_PMK_WPXK3.set_copy_of_buffer( |
|
6320 key->get_data(pmk_key_length), |
|
6321 pmk_key_length); |
|
6322 |
|
6323 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6324 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6325 } |
|
6326 |
|
6327 //-------------------------------------------------- |
|
6328 |
|
6329 // |
|
6330 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::verify_field_is_zero( |
|
6331 const u8_t * const field, |
|
6332 const u32_t field_length) |
|
6333 { |
|
6334 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6335 |
|
6336 eap_status_e status = eap_status_ok; |
|
6337 |
|
6338 for (u32_t ind = 0ul; ind < field_length; ind++) |
|
6339 { |
|
6340 if (field[ind] != 0) |
|
6341 { |
|
6342 status = eap_status_illegal_padding; |
|
6343 break; |
|
6344 } |
|
6345 } |
|
6346 |
|
6347 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6348 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6349 } |
|
6350 |
|
6351 //-------------------------------------------------- |
|
6352 |
|
6353 // |
|
6354 eap_status_e eapol_key_state_c::packet_data_session_key( |
|
6355 eap_variable_data_c * const key, ///< Here is the key. |
|
6356 const eapol_key_type_e key_type, ///< This the type of the key. |
|
6357 const u32_t key_index, ///< This is the index of the key. |
|
6358 const bool key_tx_bit, ///< This is the TX bit of the key. |
|
6359 const u8_t * const key_RSC, ///< This is the RSC counter |
|
6360 const u32_t key_RSC_size ///< This is the size of RSC counter |
|
6361 ) |
|
6362 { |
|
6363 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6364 |
|
6365 eapol_session_key_c * eapol_session_key = new eapol_session_key_c( |
|
6366 m_am_tools, |
|
6367 key, |
|
6368 key_type, |
|
6369 key_index, |
|
6370 key_tx_bit, |
|
6371 key_RSC, |
|
6372 key_RSC_size |
|
6373 ); |
|
6374 if (eapol_session_key == 0) |
|
6375 { |
|
6376 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6377 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
6378 } |
|
6379 |
|
6380 if (eapol_session_key->get_is_valid() == false) |
|
6381 { |
|
6382 delete eapol_session_key; |
|
6383 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6384 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
6385 } |
|
6386 |
|
6387 |
|
6388 eap_status_e status = m_key_state_partner->packet_data_session_key( |
|
6389 &m_send_network_id, |
|
6390 eapol_session_key); |
|
6391 |
|
6392 delete eapol_session_key; |
|
6393 |
|
6394 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6395 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6396 } |
|
6397 |
|
6398 //-------------------------------------------------- |
|
6399 |
|
6400 // |
|
6401 eap_status_e eapol_key_state_c::allow_4_way_handshake() |
|
6402 { |
|
6403 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6404 eap_status_e status = eap_status_process_general_error; |
|
6405 |
|
6406 EAP_TRACE_DEBUG( |
|
6407 m_am_tools, |
|
6408 TRACE_FLAGS_DEFAULT, |
|
6409 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake()\n"), |
|
6410 (m_is_client == true ? "client": "server"))); |
|
6411 |
|
6412 // Only client (supplicant) could allow 4-Way Handshake. |
|
6413 EAP_ASSERT_ALWAYS(m_is_client == true); |
|
6414 |
|
6415 // First check do we need 4-Way Handshake. |
|
6416 if (get_is_RSNA() == true |
|
6417 || get_is_WPA() == true |
|
6418 #if defined(EAP_USE_WPXM) |
|
6419 || get_is_WPXM() == true |
|
6420 #endif //#if defined(EAP_USE_WPXM) |
|
6421 ) |
|
6422 { |
|
6423 // OK, we need 4-Way Handshake. |
|
6424 EAP_TRACE_DEBUG( |
|
6425 m_am_tools, |
|
6426 TRACE_FLAGS_DEFAULT, |
|
6427 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ") |
|
6428 EAPL("Allow 4-Way Handshake, m_authentication_type=%d\n"), |
|
6429 (m_is_client == true ? "client": "server"), |
|
6430 m_authentication_type)); |
|
6431 |
|
6432 m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake; |
|
6433 m_eapol_key_state = eapol_key_state_wait_4_way_handshake_message_1; |
|
6434 } |
|
6435 else if (m_authentication_type == eapol_key_authentication_type_802_1X) |
|
6436 { |
|
6437 // No 4-Way Handshake needed. |
|
6438 // AP will send unicast and broad cast keys in EAPOL key messages. |
|
6439 EAP_TRACE_DEBUG( |
|
6440 m_am_tools, |
|
6441 TRACE_FLAGS_DEFAULT, |
|
6442 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ") |
|
6443 EAPL("Dynamic WEP, m_authentication_type=%d\n"), |
|
6444 (m_is_client == true ? "client": "server"), |
|
6445 m_authentication_type)); |
|
6446 |
|
6447 m_eapol_key_handshake_type = eapol_key_handshake_type_dynamic_WEP; |
|
6448 m_eapol_key_state = eapol_key_state_wait_rc4_key_message; |
|
6449 |
|
6450 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6451 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
6452 } |
|
6453 else |
|
6454 { |
|
6455 // No 4-Way Handshake needed. |
|
6456 EAP_TRACE_DEBUG( |
|
6457 m_am_tools, |
|
6458 TRACE_FLAGS_DEFAULT, |
|
6459 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ") |
|
6460 EAPL("No 4-Way Handshake, m_authentication_type=%d\n"), |
|
6461 (m_is_client == true ? "client": "server"), |
|
6462 m_authentication_type)); |
|
6463 |
|
6464 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6465 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
6466 } |
|
6467 |
|
6468 #if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
6469 // Creates SNonce. This is done here in early phase of authentication. |
|
6470 // This will reduce the CPU load when time critical first message |
|
6471 // of 4-Way handshake is processed. |
|
6472 status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES); |
|
6473 if (status != eap_status_ok) |
|
6474 { |
|
6475 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6476 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6477 } |
|
6478 #endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
6479 |
|
6480 status = init_handshake_timeout(m_handshake_timeout); |
|
6481 if (status != eap_status_ok) |
|
6482 { |
|
6483 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6484 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6485 } |
|
6486 |
|
6487 #if defined(USE_EAPOL_KEY_TEST_FAILURES) |
|
6488 #pragma message ( "WARNING: USE_EAPOL_KEY_TEST_FAILURES compiler flag used. This is test code, NOT for final release." ) |
|
6489 m_create_key_failure = eapol_key_state_wait_4_way_handshake_message_3; |
|
6490 #endif //#if defined(USE_EAPOL_KEY_TEST_FAILURES) |
|
6491 |
|
6492 status = eap_status_ok; |
|
6493 |
|
6494 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6495 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6496 } |
|
6497 |
|
6498 //-------------------------------------------------- |
|
6499 |
|
6500 // |
|
6501 eap_status_e eapol_key_state_c::start_group_key_handshake( |
|
6502 const eap_am_network_id_c * const receive_network_id, |
|
6503 const eapol_protocol_version_e received_eapol_version, |
|
6504 const eapol_key_descriptor_type_e received_key_descriptor_type) |
|
6505 { |
|
6506 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6507 EAP_UNREFERENCED_PARAMETER(receive_network_id); |
|
6508 |
|
6509 eap_status_e status = eap_status_process_general_error; |
|
6510 |
|
6511 // server and client could call this. |
|
6512 |
|
6513 EAP_TRACE_DEBUG( |
|
6514 m_am_tools, |
|
6515 TRACE_FLAGS_DEFAULT, |
|
6516 (EAPL("EAPOL_KEY: %s: eapol_key_state_c::start_group_key_handshake()\n"), |
|
6517 (m_is_client == true ? "client": "server"))); |
|
6518 |
|
6519 if (m_eapol_key_handshake_type != eapol_key_handshake_type_none |
|
6520 && m_eapol_key_handshake_type != eapol_key_handshake_type_group_key_handshake |
|
6521 && m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake) |
|
6522 { |
|
6523 eapol_key_state_string_c state_string; |
|
6524 EAP_TRACE_ERROR( |
|
6525 m_am_tools, |
|
6526 TRACE_FLAGS_DEFAULT, |
|
6527 (EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong handshake type %s\n"), |
|
6528 (m_is_client == true ? "client": "server"), |
|
6529 state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); |
|
6530 |
|
6531 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6532 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); |
|
6533 } |
|
6534 |
|
6535 if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull |
|
6536 && get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull) |
|
6537 { |
|
6538 eapol_key_state_string_c state_string; |
|
6539 EAP_TRACE_ERROR( |
|
6540 m_am_tools, |
|
6541 TRACE_FLAGS_DEFAULT, |
|
6542 (EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong state %s\n"), |
|
6543 (m_is_client == true ? "client": "server"), |
|
6544 state_string.get_eapol_key_state_string(get_eapol_key_state()))); |
|
6545 |
|
6546 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6547 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state); |
|
6548 } |
|
6549 |
|
6550 eap_buf_chain_wr_c sent_packet( |
|
6551 eap_write_buffer, |
|
6552 m_am_tools); |
|
6553 |
|
6554 if (sent_packet.get_is_valid() == false) |
|
6555 { |
|
6556 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
6557 } |
|
6558 |
|
6559 u32_t send_data_length = 0ul; |
|
6560 u32_t send_buffer_length = 0ul; |
|
6561 eapol_key_state_e next_state = eapol_key_state_group_key_handshake_failed; |
|
6562 |
|
6563 if (m_is_client == true) |
|
6564 { |
|
6565 status = create_eapol_key_handshake_message_0( |
|
6566 false, |
|
6567 &sent_packet, |
|
6568 m_eapol_header_offset, |
|
6569 &send_data_length, |
|
6570 &send_buffer_length, |
|
6571 0ul, |
|
6572 received_eapol_version); |
|
6573 if (status != eap_status_ok) |
|
6574 { |
|
6575 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6576 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6577 } |
|
6578 |
|
6579 next_state = eapol_key_state_wait_group_key_handshake_message_1; |
|
6580 } |
|
6581 else |
|
6582 { |
|
6583 |
|
6584 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6585 |
|
6586 increase_key_reply_counter(); |
|
6587 |
|
6588 status = create_group_key_handshake_message_1( |
|
6589 &sent_packet, |
|
6590 m_eapol_header_offset, |
|
6591 &send_data_length, |
|
6592 &send_buffer_length, |
|
6593 received_eapol_version, |
|
6594 received_key_descriptor_type); |
|
6595 if (status != eap_status_ok) |
|
6596 { |
|
6597 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6598 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6599 } |
|
6600 |
|
6601 next_state = eapol_key_state_wait_group_key_handshake_message_2; |
|
6602 #else |
|
6603 |
|
6604 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6605 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); |
|
6606 |
|
6607 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6608 |
|
6609 } |
|
6610 |
|
6611 status = packet_send( |
|
6612 &m_send_network_id, |
|
6613 &sent_packet, |
|
6614 m_eapol_header_offset, |
|
6615 send_data_length, |
|
6616 send_buffer_length); |
|
6617 if (status != eap_status_ok) |
|
6618 { |
|
6619 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6620 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6621 } |
|
6622 |
|
6623 set_eapol_key_state(next_state); |
|
6624 |
|
6625 m_eapol_key_handshake_type = eapol_key_handshake_type_group_key_handshake; |
|
6626 |
|
6627 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6628 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6629 } |
|
6630 |
|
6631 //-------------------------------------------------- |
|
6632 |
|
6633 // |
|
6634 eap_status_e eapol_key_state_c::get_key_length( |
|
6635 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e cipher, |
|
6636 u16_t * const key_length) |
|
6637 { |
|
6638 if (cipher |
|
6639 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP) |
|
6640 { |
|
6641 *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_CCMP; |
|
6642 } |
|
6643 else if (cipher |
|
6644 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP) |
|
6645 { |
|
6646 *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_TKIP; |
|
6647 } |
|
6648 else if (cipher |
|
6649 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40) |
|
6650 { |
|
6651 *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_40; |
|
6652 } |
|
6653 else if (cipher |
|
6654 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104) |
|
6655 { |
|
6656 *key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_104; |
|
6657 } |
|
6658 else |
|
6659 { |
|
6660 *key_length = 0ul; |
|
6661 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6662 return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); |
|
6663 } |
|
6664 |
|
6665 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6666 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
6667 } |
|
6668 |
|
6669 //-------------------------------------------------- |
|
6670 |
|
6671 // |
|
6672 eap_status_e eapol_key_state_c::process_4_way_handshake_message( |
|
6673 const eap_am_network_id_c * const receive_network_id, |
|
6674 eapol_RSNA_key_header_c * const eapol_key_message, |
|
6675 const u32_t packet_length) |
|
6676 { |
|
6677 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6678 eap_status_e status = eap_status_process_general_error; |
|
6679 |
|
6680 |
|
6681 |
|
6682 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6683 if (m_is_client == false |
|
6684 && eapol_key_message->get_key_information_request() == true |
|
6685 && eapol_key_message->get_key_information_key_MIC() == true |
|
6686 && eapol_key_message->get_key_information_key_ack() == false |
|
6687 && eapol_key_message->get_key_information_install() == false |
|
6688 && eapol_key_message->get_key_data_length() == 0ul) |
|
6689 { |
|
6690 // Message 0 to start 4-Way Handshake. Only server handles this. |
|
6691 status = process_4_way_handshake_message_0( |
|
6692 receive_network_id, |
|
6693 eapol_key_message, |
|
6694 packet_length); |
|
6695 } |
|
6696 else |
|
6697 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6698 if (m_is_client == true |
|
6699 && eapol_key_message->get_key_information_key_MIC() == false |
|
6700 && eapol_key_message->get_key_information_key_ack() == true |
|
6701 && eapol_key_message->get_key_information_install() == false) |
|
6702 { |
|
6703 // Message 1 of 4-Way Handshake. Only client handles this. |
|
6704 status = process_4_way_handshake_message_1( |
|
6705 receive_network_id, |
|
6706 eapol_key_message, |
|
6707 packet_length); |
|
6708 } |
|
6709 else |
|
6710 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6711 if (m_is_client == false |
|
6712 && eapol_key_message->get_key_information_key_MIC() == true |
|
6713 && eapol_key_message->get_key_information_key_ack() == false |
|
6714 && eapol_key_message->get_key_information_install() == false |
|
6715 && eapol_key_message->get_key_data_length() != 0ul) |
|
6716 { |
|
6717 // Message 2 of 4-Way Handshake. Only server handles this. |
|
6718 status = process_4_way_handshake_message_2( |
|
6719 receive_network_id, |
|
6720 eapol_key_message, |
|
6721 packet_length); |
|
6722 } |
|
6723 else |
|
6724 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6725 if (m_is_client == true |
|
6726 && eapol_key_message->get_key_information_key_MIC() == true |
|
6727 && eapol_key_message->get_key_information_key_ack() == true |
|
6728 && eapol_key_message->get_key_information_install() == true |
|
6729 && eapol_key_message->get_key_data_length() != 0ul) |
|
6730 { |
|
6731 // Message 3 of 4-Way Handshake. Only client handles this. |
|
6732 status = process_4_way_handshake_message_3( |
|
6733 receive_network_id, |
|
6734 eapol_key_message, |
|
6735 packet_length); |
|
6736 } |
|
6737 else |
|
6738 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6739 if (m_is_client == false |
|
6740 && eapol_key_message->get_key_information_key_MIC() == true |
|
6741 && eapol_key_message->get_key_information_key_ack() == false |
|
6742 && eapol_key_message->get_key_information_install() == false |
|
6743 && eapol_key_message->get_key_data_length() == 0ul) |
|
6744 { |
|
6745 // Message 4 of 4-Way Handshake. Only server handles this. |
|
6746 status = process_4_way_handshake_message_4( |
|
6747 receive_network_id, |
|
6748 eapol_key_message, |
|
6749 packet_length); |
|
6750 } |
|
6751 else |
|
6752 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6753 { |
|
6754 // ERROR. Drop packet. |
|
6755 EAP_TRACE_ERROR( |
|
6756 m_am_tools, |
|
6757 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6758 (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key 4-Way Handshake frame: ") |
|
6759 EAPL("IsClient: %d MIC %d, Key Ack %d, Install %d, Key Length %d\n"), |
|
6760 m_is_client, |
|
6761 eapol_key_message->get_key_information_key_MIC(), |
|
6762 eapol_key_message->get_key_information_key_ack(), |
|
6763 eapol_key_message->get_key_information_install(), |
|
6764 eapol_key_message->get_key_data_length())); |
|
6765 |
|
6766 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6767 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
6768 } |
|
6769 |
|
6770 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6771 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6772 } |
|
6773 |
|
6774 //-------------------------------------------------- |
|
6775 |
|
6776 // |
|
6777 eap_status_e eapol_key_state_c::process_group_key_handshake_message( |
|
6778 const eap_am_network_id_c * const receive_network_id, |
|
6779 eapol_RSNA_key_header_c * const eapol_key_message, |
|
6780 const u32_t packet_length) |
|
6781 { |
|
6782 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6783 eap_status_e status = eap_status_process_general_error; |
|
6784 |
|
6785 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6786 if (m_is_client == false |
|
6787 && eapol_key_message->get_key_information_key_MIC() == true |
|
6788 && eapol_key_message->get_key_information_key_ack() == false |
|
6789 && eapol_key_message->get_key_information_request() == true) |
|
6790 { |
|
6791 // Message 0 of Group Key Handshake. Only server handles this. |
|
6792 status = process_group_key_handshake_message_0( |
|
6793 receive_network_id, |
|
6794 eapol_key_message, |
|
6795 packet_length); |
|
6796 } |
|
6797 else |
|
6798 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6799 if (m_is_client == true |
|
6800 && eapol_key_message->get_key_information_key_MIC() == true |
|
6801 && eapol_key_message->get_key_information_key_ack() == true |
|
6802 && eapol_key_message->get_key_information_request() == false) |
|
6803 { |
|
6804 // Message 1 of Group Key Handshake. Only client handles this. |
|
6805 status = process_group_key_handshake_message_1( |
|
6806 receive_network_id, |
|
6807 eapol_key_message, |
|
6808 packet_length); |
|
6809 } |
|
6810 else |
|
6811 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6812 if (m_is_client == false |
|
6813 && eapol_key_message->get_key_information_key_MIC() == true |
|
6814 && eapol_key_message->get_key_information_key_ack() == false |
|
6815 && eapol_key_message->get_key_information_request() == false) |
|
6816 { |
|
6817 // Message 2 of Group Key Handshake. Only server handles this. |
|
6818 status = process_group_key_handshake_message_2( |
|
6819 receive_network_id, |
|
6820 eapol_key_message, |
|
6821 packet_length); |
|
6822 } |
|
6823 else |
|
6824 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
6825 { |
|
6826 // ERROR. Drop packet. |
|
6827 EAP_TRACE_ERROR( |
|
6828 m_am_tools, |
|
6829 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6830 (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key Group Key Handshake frame: ") |
|
6831 EAPL("MIC %d, Key Ack %d, Request %d\n"), |
|
6832 eapol_key_message->get_key_information_key_MIC(), |
|
6833 eapol_key_message->get_key_information_key_ack(), |
|
6834 eapol_key_message->get_key_information_request())); |
|
6835 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6836 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
6837 } |
|
6838 |
|
6839 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6840 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6841 } |
|
6842 |
|
6843 //-------------------------------------------------- |
|
6844 |
|
6845 // |
|
6846 eap_status_e eapol_key_state_c::process_RSNA_key_descriptor( |
|
6847 const eap_am_network_id_c * const receive_network_id, |
|
6848 eap_general_header_base_c * const packet_data, |
|
6849 const u32_t packet_length) |
|
6850 { |
|
6851 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6852 eap_status_e status = eap_status_process_general_error; |
|
6853 |
|
6854 if (packet_length < eapol_RSNA_key_header_c::get_header_length()) |
|
6855 { |
|
6856 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6857 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); |
|
6858 } |
|
6859 |
|
6860 eapol_RSNA_key_header_c eapol_key_message( |
|
6861 m_am_tools, |
|
6862 get_is_RSNA(), |
|
6863 get_is_WPXM(), |
|
6864 packet_data->get_header_buffer(packet_data->get_header_buffer_length()), |
|
6865 packet_data->get_header_buffer_length()); |
|
6866 if (eapol_key_message.get_is_valid() == false) |
|
6867 { |
|
6868 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6869 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
6870 } |
|
6871 |
|
6872 status = eapol_key_message.check_header(); |
|
6873 if (status != eap_status_ok) |
|
6874 { |
|
6875 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6876 return EAP_STATUS_RETURN(m_am_tools, status); |
|
6877 } |
|
6878 |
|
6879 TRACE_EAPOL_KEY_MESSAGE( |
|
6880 "Received EAPOL Handshake Message", |
|
6881 &eapol_key_message); |
|
6882 |
|
6883 u64_t packet_reply_counter = eapol_key_message.get_key_replay_counter(); |
|
6884 |
|
6885 // compare_u64() function is used because in some platforms |
|
6886 // unsigned 64-bit comparison is actually signed 64-bit comparison, |
|
6887 // because unsigned 64-bit integer is implemented as a signed 64-bit integer. |
|
6888 // This causes failures in test if broken AP sends Key Replay Counter with |
|
6889 // highest bit set 1. |
|
6890 i32_t comparison(m_am_tools->compare_u64(get_key_reply_counter(), packet_reply_counter)); |
|
6891 |
|
6892 if (m_is_client == true) |
|
6893 { |
|
6894 // On client Key Reply Counter must be bigger |
|
6895 // than on any other previous frame. |
|
6896 //if (get_key_reply_counter() > packet_reply_counter) |
|
6897 if (comparison > 0) |
|
6898 { |
|
6899 // ERROR. Drop packet. |
|
6900 EAP_TRACE_ERROR( |
|
6901 m_am_tools, |
|
6902 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6903 (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter\n"))); |
|
6904 EAP_TRACE_DATA_ERROR( |
|
6905 m_am_tools, |
|
6906 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6907 (EAPL("Local Reply Counter"), |
|
6908 &m_key_reply_counter, |
|
6909 sizeof(m_key_reply_counter))); |
|
6910 EAP_TRACE_DATA_ERROR( |
|
6911 m_am_tools, |
|
6912 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6913 (EAPL("Packet Reply Counter"), |
|
6914 &packet_reply_counter, |
|
6915 sizeof(packet_reply_counter))); |
|
6916 |
|
6917 if (get_is_WPXM() == true) |
|
6918 { |
|
6919 // Here we must ignore the Reply Counter failure. |
|
6920 // WPXM seems to work against RSN specification that says |
|
6921 // every packet must be sent with new Reply Counter. |
|
6922 // WPXM starts Group Key Handshake with Reply Counter 0 after successfull |
|
6923 // 4-Way Handshake. |
|
6924 EAP_TRACE_DEBUG( |
|
6925 m_am_tools, |
|
6926 TRACE_FLAGS_DEFAULT, |
|
6927 (EAPL("WARNING: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter in WPXM.\n"))); |
|
6928 } |
|
6929 else |
|
6930 { |
|
6931 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6932 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
6933 } |
|
6934 } |
|
6935 else if (comparison == 0) |
|
6936 { |
|
6937 // This may be re-transmitted request. |
|
6938 // Send the saved previous response |
|
6939 // or process this message again. |
|
6940 EAP_TRACE_DEBUG( |
|
6941 m_am_tools, |
|
6942 TRACE_FLAGS_DEFAULT, |
|
6943 (EAPL("WARNING: EAPOL_KEY: EAPOL-Key frame Reply Counter same as previous request.\n"))); |
|
6944 EAP_TRACE_DATA_DEBUG( |
|
6945 m_am_tools, |
|
6946 TRACE_FLAGS_DEFAULT, |
|
6947 (EAPL("WARNING: Local Reply Counter"), |
|
6948 &m_key_reply_counter, |
|
6949 sizeof(m_key_reply_counter))); |
|
6950 EAP_TRACE_DATA_DEBUG( |
|
6951 m_am_tools, |
|
6952 TRACE_FLAGS_DEFAULT, |
|
6953 (EAPL("WARNING: Packet Reply Counter"), |
|
6954 &packet_reply_counter, |
|
6955 sizeof(packet_reply_counter))); |
|
6956 } |
|
6957 } |
|
6958 else |
|
6959 { |
|
6960 if (eapol_key_message.get_key_information_request() == true) |
|
6961 { |
|
6962 // Reply Counter of request packets are not checked. |
|
6963 comparison = 0; |
|
6964 } |
|
6965 |
|
6966 // On server Key Reply Counter must be same |
|
6967 // as the sent request frame. |
|
6968 if (comparison != 0) |
|
6969 { |
|
6970 // ERROR. Drop packet. |
|
6971 EAP_TRACE_ERROR( |
|
6972 m_am_tools, |
|
6973 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6974 (EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter\n"))); |
|
6975 EAP_TRACE_DATA_ERROR( |
|
6976 m_am_tools, |
|
6977 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6978 (EAPL("Local Reply Counter"), |
|
6979 &m_key_reply_counter, |
|
6980 sizeof(m_key_reply_counter))); |
|
6981 EAP_TRACE_DATA_ERROR( |
|
6982 m_am_tools, |
|
6983 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
6984 (EAPL("Packet Reply Counter"), |
|
6985 &packet_reply_counter, |
|
6986 sizeof(packet_reply_counter))); |
|
6987 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
6988 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
6989 } |
|
6990 } |
|
6991 |
|
6992 |
|
6993 if (eapol_key_message.get_key_information_key_type() == true) |
|
6994 { |
|
6995 // 4-Way Handshake message. |
|
6996 status = process_4_way_handshake_message( |
|
6997 receive_network_id, |
|
6998 &eapol_key_message, |
|
6999 packet_length); |
|
7000 } |
|
7001 else if (eapol_key_message.get_key_information_key_type() == false) |
|
7002 { |
|
7003 // Group Key Handshake message. |
|
7004 status = process_group_key_handshake_message( |
|
7005 receive_network_id, |
|
7006 &eapol_key_message, |
|
7007 packet_length); |
|
7008 } |
|
7009 else |
|
7010 { |
|
7011 // Unknown message received and dropped quietly. |
|
7012 eapol_key_state_string_c state_string; |
|
7013 EAP_TRACE_ERROR( |
|
7014 m_am_tools, |
|
7015 TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, |
|
7016 (EAPL("WARNING: EAPOL_KEY: Handshake in NOT supported in m_eapol_key_handshake_type %s.\n"), |
|
7017 state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type))); |
|
7018 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
7019 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
7020 } |
|
7021 |
|
7022 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
7023 return EAP_STATUS_RETURN(m_am_tools, status); |
|
7024 } |
|
7025 |
|
7026 //-------------------------------------------------- |
|
7027 |
|
7028 // End. |