3 * Copyright (c) 2006 CACE Technologies, Davis (California)
6 * SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
9 #ifndef _DOT11DECRYPT_SYSTEM_H
10 #define _DOT11DECRYPT_SYSTEM_H
12 /************************************************************************/
13 /* Constant definitions */
15 /* General definitions */
16 #define DOT11DECRYPT_RET_SUCCESS 0
17 #define DOT11DECRYPT_RET_UNSUCCESS 1
19 #define DOT11DECRYPT_RET_NO_DATA 1
20 #define DOT11DECRYPT_RET_WRONG_DATA_SIZE 2
21 #define DOT11DECRYPT_RET_REQ_DATA 3
22 #define DOT11DECRYPT_RET_NO_VALID_HANDSHAKE 4
23 #define DOT11DECRYPT_RET_NO_DATA_ENCRYPTED 5
25 #define DOT11DECRYPT_RET_SUCCESS_HANDSHAKE -1
27 #define DOT11DECRYPT_MAX_KEYS_NR 64
29 /* Decryption algorithms fields size definition (bytes) */
30 #define DOT11DECRYPT_WPA_NONCE_LEN 32
31 #define DOT11DECRYPT_WPA_PTK_MAX_LEN 88 /* TKIP 48, CCMP 64, GCMP-256 88 bytes */
32 #define DOT11DECRYPT_WPA_MICKEY_MAX_LEN 24
34 #define DOT11DECRYPT_WEP_128_KEY_LEN 16 /* 128 bits */
36 /* General 802.11 constants */
37 #define DOT11DECRYPT_MAC_LEN 6
38 #define DOT11DECRYPT_RADIOTAP_HEADER_LEN 24
40 #define DOT11DECRYPT_EAPOL_MAX_LEN 1024U
42 #define DOT11DECRYPT_TK_LEN 16
44 /* Max length of capture data */
45 #define DOT11DECRYPT_MAX_CAPLEN 8192
47 #define DOT11DECRYPT_WEP_IVLEN 3 /* 24bit */
48 #define DOT11DECRYPT_WEP_KIDLEN 1 /* 1 octet */
49 #define DOT11DECRYPT_WEP_ICV 4
50 #define DOT11DECRYPT_WEP_HEADER DOT11DECRYPT_WEP_IVLEN + DOT11DECRYPT_WEP_KIDLEN
51 #define DOT11DECRYPT_WEP_TRAILER DOT11DECRYPT_WEP_ICV
54 * 802.11i defines an extended IV for use with non-WEP ciphers.
55 * When the EXTIV bit is set in the key id byte an additional
56 * 4 bytes immediately follow the IV for TKIP. For CCMP the
57 * EXTIV bit is likewise set but the 8 bytes represent the
58 * CCMP header rather than IV+extended-IV.
60 #define DOT11DECRYPT_RSNA_EXTIV 0x20
61 #define DOT11DECRYPT_RSNA_EXTIVLEN 4 /* extended IV length */
62 #define DOT11DECRYPT_TKIP_MICLEN 8 /* trailing MIC */
64 #define DOT11DECRYPT_RSNA_HEADER DOT11DECRYPT_WEP_HEADER + DOT11DECRYPT_RSNA_EXTIVLEN
66 #define DOT11DECRYPT_CCMP_HEADER DOT11DECRYPT_RSNA_HEADER
67 #define DOT11DECRYPT_CCMP_TRAILER 8 /* IEEE 802.11-2016 12.5.3.2 CCMP MPDU format */
68 #define DOT11DECRYPT_CCMP_256_TRAILER 16 /* IEEE 802.11-2016 12.5.3.2 CCMP MPDU format */
70 #define DOT11DECRYPT_GCMP_HEADER 8 /* IEEE 802.11-206 12.5.5.2 GCMP MPDU format */
71 #define DOT11DECRYPT_GCMP_TRAILER 16
73 #define DOT11DECRYPT_TKIP_HEADER DOT11DECRYPT_RSNA_HEADER
74 #define DOT11DECRYPT_TKIP_TRAILER DOT11DECRYPT_TKIP_MICLEN + DOT11DECRYPT_WEP_ICV
76 #define DOT11DECRYPT_CRC_LEN 4
78 /************************************************************************/
84 #include "dot11decrypt_user.h"
85 #include "ws_symbol_export.h"
87 /************************************************************************/
88 /* Macro definitions */
90 /************************************************************************/
91 /* Type definitions */
93 typedef struct _DOT11DECRYPT_SEC_ASSOCIATION_ID
{
94 unsigned char bssid
[DOT11DECRYPT_MAC_LEN
];
95 unsigned char sta
[DOT11DECRYPT_MAC_LEN
];
96 } DOT11DECRYPT_SEC_ASSOCIATION_ID
, *PDOT11DECRYPT_SEC_ASSOCIATION_ID
;
98 typedef struct _DOT11DECRYPT_SEC_ASSOCIATION
{
99 /* This is for reassociations. A linked list of old security
100 * associations is kept. GCS
102 struct _DOT11DECRYPT_SEC_ASSOCIATION
* next
;
104 DOT11DECRYPT_SEC_ASSOCIATION_ID saId
;
105 DOT11DECRYPT_KEY_ITEM
*key
;
110 uint8_t key_ver
; /* Key descriptor version */
111 unsigned char nonce
[DOT11DECRYPT_WPA_NONCE_LEN
];
112 /* used to derive PTK, ANonce stored, SNonce taken */
113 /* the 2nd packet of the 4W handshake */
116 int tmp_group_cipher
; /* Keep between HS msg 2 and 3 */
117 unsigned char ptk
[DOT11DECRYPT_WPA_PTK_MAX_LEN
]; /* session key used in decryption algorithm */
122 } DOT11DECRYPT_SEC_ASSOCIATION
, *PDOT11DECRYPT_SEC_ASSOCIATION
;
124 typedef struct _DOT11DECRYPT_CONTEXT
{
126 DOT11DECRYPT_KEY_ITEM keys
[DOT11DECRYPT_MAX_KEYS_NR
];
128 char pkt_ssid
[DOT11DECRYPT_WPA_SSID_MAX_LEN
];
130 } DOT11DECRYPT_CONTEXT
, *PDOT11DECRYPT_CONTEXT
;
132 typedef enum _DOT11DECRYPT_HS_MSG_TYPE
{
133 DOT11DECRYPT_HS_MSG_TYPE_INVALID
= 0,
134 DOT11DECRYPT_HS_MSG_TYPE_4WHS_1
,
135 DOT11DECRYPT_HS_MSG_TYPE_4WHS_2
,
136 DOT11DECRYPT_HS_MSG_TYPE_4WHS_3
,
137 DOT11DECRYPT_HS_MSG_TYPE_4WHS_4
,
138 DOT11DECRYPT_HS_MSG_TYPE_GHS_1
,
139 DOT11DECRYPT_HS_MSG_TYPE_GHS_2
140 } DOT11DECRYPT_HS_MSG_TYPE
;
142 typedef struct _DOT11DECRYPT_FTE
{
151 } DOT11DECRYPT_FTE
, *PDOT11DECRYPT_FTE
;
153 typedef struct _DOT11DECRYPT_EAPOL_PARSED
{
154 DOT11DECRYPT_HS_MSG_TYPE msg_type
;
161 uint16_t key_data_len
;
162 uint8_t group_cipher
;
171 /* For fast bss transition akms */
173 DOT11DECRYPT_FTE fte
;
174 } DOT11DECRYPT_EAPOL_PARSED
, *PDOT11DECRYPT_EAPOL_PARSED
;
176 typedef struct _DOT11DECRYPT_ASSOC_PARSED
178 uint8_t frame_subtype
;
179 uint8_t group_cipher
;
183 DOT11DECRYPT_FTE fte
;
191 uint16_t gtk_subelem_key_len
;
192 uint8_t bssid
[DOT11DECRYPT_MAC_LEN
];
193 uint8_t sa
[DOT11DECRYPT_MAC_LEN
];
194 uint8_t da
[DOT11DECRYPT_MAC_LEN
];
195 } DOT11DECRYPT_ASSOC_PARSED
, *PDOT11DECRYPT_ASSOC_PARSED
;
197 /************************************************************************/
198 /* Function prototype declarations */
205 * This will try to decrypt a 802.11 frame.
206 * @param ctx [IN] Pointer to the current context
207 * @param data [IN] Pointer to a buffer with an 802.11 frame, including MAC
209 * @param data_off [IN] Payload offset (aka the MAC header length)
210 * @param data_len [IN] Total length of the MAC header and the payload
211 * @param decrypt_data [OUT] Pointer to a buffer that will contain
212 * decrypted data. Must have room for at least DOT11DECRYPT_MAX_CAPLEN bytes.
213 * @param decrypt_len [OUT] Length of decrypted data.
214 * @param key [OUT] Pointer to a preallocated key structure containing
215 * the key used during the decryption process (if done). If this parameter
216 * is set to NULL, the key will be not returned.
218 * - DOT11DECRYPT_RET_SUCCESS: Decryption has been done (decrypt_data and
219 * decrypt_length will contain the packet data decrypted and the length of
221 * - DOT11DECRYPT_RET_NO_DATA: The packet is not a data packet
222 * - DOT11DECRYPT_RET_WRONG_DATA_SIZE: The size of the packet is below the
224 * - DOT11DECRYPT_RET_REQ_DATA: Required data is not available and the
225 * processing must be interrupted
226 * - DOT11DECRYPT_RET_NO_DATA_ENCRYPTED: Not encrypted
227 * - DOT11DECRYPT_RET_UNSUCCESS: Generic unspecified error (decrypt_data
228 * and decrypt_length will be not modified).
230 * The decrypted buffer should be allocated for a size equal or greater
231 * than the packet data buffer size. Before decryption process original
232 * data is copied in the buffer pointed by decrypt_data not to modify the
235 * The length of decrypted data will consider the entire 802.11 frame
236 * (thus the MAC header, the frame body and the recalculated FCS -if
237 * initially present-)
239 * This function is not thread-safe when used in parallel with context
240 * management functions on the same context.
243 extern int Dot11DecryptDecryptPacket(
244 PDOT11DECRYPT_CONTEXT ctx
,
246 const unsigned data_off
,
247 const unsigned data_len
,
248 unsigned char *decrypt_data
,
249 uint32_t *decrypt_len
,
250 PDOT11DECRYPT_KEY_ITEM key
)
254 * This will try to decrypt the encrypted keydata field of an EAPOL KEY frame.
255 * @param ctx [IN] Pointer to the current context
256 * @param eapol_parsed [IN] Extracted/Parsed pieces of eapol frame
257 * @param bssid [IN] bssid of AP
258 * @param sta [IN] sta MAC address
259 * @param decrypted_data [OUT] Pointer to a buffer that will contain
260 * decrypted data. Must have room for at least DOT11DECRYPT_EAPOL_MAX_LEN bytes.
261 * @param decrypted_len [OUT] Length of decrypted data.
262 * @param key [OUT] Pointer to a preallocated key structure containing
263 * the key used during the decryption process (if done). If this parameter
264 * is set to NULL, the key will be not returned.
266 * - DOT11DECRYPT_RET_SUCCESS: Decryption has been done (decrypt_data and
267 * decrypt_length will contain the packet data decrypted and the length of
269 * - DOT11DECRYPT_RET_UNSUCCESS: Generic unspecified error (decrypt_data
270 * and decrypt_length will be not modified).
273 Dot11DecryptDecryptKeyData(PDOT11DECRYPT_CONTEXT ctx
,
274 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
275 const unsigned char bssid
[DOT11DECRYPT_MAC_LEN
],
276 const unsigned char sta
[DOT11DECRYPT_MAC_LEN
],
277 unsigned char *decrypted_data
, unsigned *decrypted_len
,
278 PDOT11DECRYPT_KEY_ITEM key
)
282 * This will try to extract keys from an EAPOL frame and add corresponding
283 * SAs to current context. eapol_parsed must contain the already parsed EAPOL
284 * key frame and for frames that contain encrypted EAPOL keydata the keydata
285 * must first be decrypted with Dot11DecryptDecryptKeyData before calling this
287 * @param ctx [IN] Pointer to the current context
288 * @param eapol_parsed [IN] Extracted/Parsed pieces of eapol frame
289 * @param eapol_raw [IN] Pointer to a buffer with an EAPOL frame
290 * @param tot_len [IN] Total length of the EAPOL frame
291 * @param bssid [IN] bssid of AP
292 * @param sta [IN] sta MAC address
294 * - DOT11DECRYPT_RET_REQ_DATA: Required data is not available and the
295 * processing must be interrupted
296 * - DOT11DECRYPT_RET_UNSUCCESS: Generic unspecified error (decrypt_data
297 * and decrypt_length will be not modified).
298 * - DOT11DECRYPT_RET_SUCCESS_HANDSHAKE: An eapol handshake packet was successfuly parsed
299 * and key information extracted.
300 * - DOT11DECRYPT_RET_NO_VALID_HANDSHAKE: The handshake is invalid or was not used
301 * for some reason. For encrypted packets decryption was still successful.
303 * This function is not thread-safe when used in parallel with context
304 * management functions on the same context.
306 extern int Dot11DecryptScanEapolForKeys(
307 PDOT11DECRYPT_CONTEXT ctx
,
308 PDOT11DECRYPT_EAPOL_PARSED eapol_parsed
,
309 const uint8_t *eapol_raw
,
310 const unsigned tot_len
,
311 const unsigned char bssid
[DOT11DECRYPT_MAC_LEN
],
312 const unsigned char sta
[DOT11DECRYPT_MAC_LEN
])
316 * This will try to extract keys from an FT (re)association frame and add
317 * corresponding SAs to current context. assoc_parsed must contain the already
318 * parsed association frame content. If the FT BSS Transition IE contains an
319 * encrypted GTK subelem and decryption is successful the decrypted GTK will
320 * be returned in decrypted_gtk.
321 * @param ctx [IN] Pointer to the current context
322 * @param assoc_parsed [IN] Extracted/Parsed pieces of association frame
323 * @param decrypted_gtk [OUT] Buffer for decrypted GTK subelem
324 * @param decrypted_len [OUT] Decrypted GTK subelem key length
325 * @param used_key [OUT] Buffer to hold the key used during the decryption process.
327 * - DOT11DECRYPT_RET_UNSUCCESS: Generic unspecified error (decrypted_gtk
328 * and decrypted_len will be not modified).
329 * - DOT11DECRYPT_RET_SUCCESS_HANDSHAKE: An association frame was successfuly parsed
330 * and key information extracted.
331 * - DOT11DECRYPT_RET_NO_VALID_HANDSHAKE: The association is invalid or no matching
332 * key for decryption was found.
335 Dot11DecryptScanFtAssocForKeys(
336 const PDOT11DECRYPT_CONTEXT ctx
,
337 const PDOT11DECRYPT_ASSOC_PARSED assoc_parsed
,
338 uint8_t *decrypted_gtk
, size_t *decrypted_len
,
339 DOT11DECRYPT_KEY_ITEM
* used_key
);
342 * This will try to extract keys from a TDLS action frame (without MAC headers)
343 * and add corresponding SAs to current context.
344 * @param ctx [IN] Pointer to the current context
345 * @param data [IN] Pointer to a buffer with a TDLS action frame
346 * @param tot_len [IN] Total length of the TDLS action frame
348 * - DOT11DECRYPT_RET_REQ_DATA: Required data is not available and the
349 * processing must be interrupted
350 * - DOT11DECRYPT_RET_SUCCESS_HANDSHAKE: The TDLS action frame was successfuly parsed
351 * and key information extracted.
352 * - DOT11DECRYPT_RET_NO_VALID_HANDSHAKE: No keys extracted
354 extern int Dot11DecryptScanTdlsForKeys(
355 PDOT11DECRYPT_CONTEXT ctx
,
357 const unsigned tot_len
)
361 * These are helper functions to retrieve KCK, KEK, TK portion of PTK
362 * for a certain "key"
363 * @param key [IN] Pointer to a key structure containing the key retrieved
364 * from functions Dot11DecryptDecryptPacket, Dot11DecryptKeydata
365 * @param kck [OUT] Pointer to the KCK/KEK/TK portion of PTK.
366 * @return length in bytes of KCK/KEK/TK
369 Dot11DecryptGetKCK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **kck
);
372 Dot11DecryptGetKEK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **kek
);
375 Dot11DecryptGetTK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **tk
);
378 Dot11DecryptGetGTK(const PDOT11DECRYPT_KEY_ITEM key
, const uint8_t **gtk
);
381 * It sets a new keys collection to use during packet processing.
382 * Any key should be well-formed, thus: it should have a defined key
383 * type and the specified length should be conforming WEP or WPA/WPA2
384 * standards. A general WEP keys could be of any length (in the range
385 * defined in DOT11DECRYPT_KEY_ITEM), if a specific WEP key is used, the
386 * length of the key will be the one specified in 802.11i-2004 (40 bits or
388 * For WPA/WPA2 the password (passphrase and SSID), the PSK and the PMK
389 * are in alternative, as explain in the DOT11DECRYPT_KEY_ITEM structure
391 * @param ctx [IN] pointer to the current context
392 * @param keys [IN] an array of keys to set.
393 * @param keys_nr [IN] the size of the keys array
394 * @return The number of keys correctly inserted in the current database.
395 * @note Before inserting new keys, the current database will be cleaned.
397 * This function is not thread-safe when used in parallel with context
398 * management functions and the packet process function on the same
401 extern int Dot11DecryptSetKeys(
402 PDOT11DECRYPT_CONTEXT ctx
,
403 DOT11DECRYPT_KEY_ITEM keys
[],
404 const size_t keys_nr
)
408 * Sets the "last seen" SSID. This allows us to pick up previous
409 * SSIDs and use them when "wildcard" passphrases are specified
410 * in the preferences.
411 * @param ctx [IN|OUT] pointer to a preallocated context structure
412 * @param pkt_ssid [IN] pointer to the packet's SSID
413 * @param pkt_ssid_len [IN] length of the packet's SSID
415 * DOT11DECRYPT_RET_SUCCESS: The key has been set.
416 * DOT11DECRYPT_RET_UNSUCCESS: The has not been set, e.g. the length was
419 int Dot11DecryptSetLastSSID(
420 PDOT11DECRYPT_CONTEXT ctx
,
426 * Initialize a context used to manage decryption and keys collection.
427 * @param ctx [IN|OUT] pointer to a preallocated context structure
429 * DOT11DECRYPT_RET_SUCCESS: the context has been successfully initialized
430 * DOT11DECRYPT_RET_UNSUCCESS: the context has not been initialized
432 * Only a correctly initialized context can be used to manage decryption
433 * processes and keys.
435 * This function is not thread-safe when used in parallel with context
436 * management functions and the packet process function on the same context.
439 int Dot11DecryptInitContext(
440 PDOT11DECRYPT_CONTEXT ctx
)
444 * Clean up the specified context. After the cleanup the pointer should
445 * not be used anymore.
446 * @param ctx [IN|OUT] pointer to the current context structure
448 * DOT11DECRYPT_RET_SUCCESS: the context has been successfully initialized
449 * DOT11DECRYPT_RET_UNSUCCESS: the context has not been initialized
451 * This function is not thread-safe when used in parallel with context
452 * management functions and the packet process function on the same
456 int Dot11DecryptDestroyContext(
457 PDOT11DECRYPT_CONTEXT ctx
)
464 #endif /* _DOT11DECRYPT_SYSTEM_H */