/src/wireshark/epan/crypt/dot11decrypt_util.h
Line | Count | Source |
1 | | /** @file |
2 | | * |
3 | | * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting |
4 | | * Copyright (c) 2006 CACE Technologies, Davis (California) |
5 | | * All rights reserved. |
6 | | * |
7 | | * SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) |
8 | | */ |
9 | | |
10 | | #ifndef _DOT11DECRYPT_UTIL_H |
11 | | #define _DOT11DECRYPT_UTIL_H |
12 | | |
13 | | #include "dot11decrypt_int.h" |
14 | | |
15 | | /** |
16 | | * @brief Constructs the AAD (Additional Authentication Data) for a 802.11 MAC frame. |
17 | | * |
18 | | * @param wh Pointer to the DOT11DECRYPT_MAC_FRAME structure containing the MAC header. |
19 | | * @param A1 Pointer to the first address field of the MAC frame. |
20 | | * @param A2 Pointer to the second address field of the MAC frame. |
21 | | * @param A3 Pointer to the third address field of the MAC frame. |
22 | | * @param aad Buffer to store the constructed AAD. |
23 | | * @param aad_len Pointer to store the length of the constructed AAD. |
24 | | */ |
25 | | void dot11decrypt_construct_aad( |
26 | | PDOT11DECRYPT_MAC_FRAME wh, |
27 | | const uint8_t *A1, |
28 | | const uint8_t *A2, |
29 | | const uint8_t *A3, |
30 | | uint8_t *aad, |
31 | | size_t *aad_len); |
32 | | |
33 | | /** |
34 | | * @brief Extracts the AAD addresses for nonce calculation. |
35 | | * |
36 | | * Reference: IEEE 802.11-2024 12.5.4.3.3 Construct AAD, |
37 | | * IEEE 802.11be-2024 12.5.2.3.3 Construct AAD, 12.5.2.3.4 Construct CCM nonce, |
38 | | * 12.5.4.3.4 Construct GCM nonce. |
39 | | * |
40 | | * @param wh Pointer to the MAC frame structure. |
41 | | * @param ap_mld_mac Pointer to the Access Point's Multi-Link MAC address. |
42 | | * @param sta_mld_mac Pointer to the Station's Multi-Link MAC address. |
43 | | * @param A1 Pointer to store the first address component. |
44 | | * @param A2 Pointer to store the second address component. |
45 | | * @param A3 Pointer to store the third address component. |
46 | | */ |
47 | | static inline void dot11decrypt_get_nonce_aad_addrs( |
48 | | PDOT11DECRYPT_MAC_FRAME wh, |
49 | | const uint8_t *ap_mld_mac, |
50 | | const uint8_t *sta_mld_mac, |
51 | | const uint8_t **A1, |
52 | | const uint8_t **A2, |
53 | | const uint8_t **A3 |
54 | | ) |
55 | 0 | { |
56 | 0 | *A1 = wh->addr1; |
57 | 0 | *A2 = wh->addr2; |
58 | 0 | *A3 = wh->addr3; |
59 | |
|
60 | 0 | if (ap_mld_mac && !(wh->addr1[0] & 1) && |
61 | 0 | DOT11DECRYPT_TYPE(wh->fc[0]) == DOT11DECRYPT_TYPE_DATA) { |
62 | 0 | uint8_t ds = wh->fc[1] & DOT11DECRYPT_FC1_DIR_MASK; |
63 | 0 | if (ds == IEEE80211_FC1_DIR_TODS) { |
64 | 0 | *A1 = ap_mld_mac; |
65 | 0 | *A2 = sta_mld_mac; |
66 | 0 | } else if (ds == IEEE80211_FC1_DIR_FROMDS) { |
67 | 0 | *A1 = sta_mld_mac; |
68 | 0 | *A2 = ap_mld_mac; |
69 | 0 | } |
70 | | // TODO 4 addr support |
71 | |
|
72 | 0 | if (DOT11DECRYPT_IS_QOS_DATA(wh)) { |
73 | 0 | PDOT11DECRYPT_MAC_FRAME_QOS qwh = (PDOT11DECRYPT_MAC_FRAME_QOS)wh; |
74 | | // The MPDU is an A-MSDU. |
75 | | // A3 is BSSID and shall be set to MLD MAC of the AP MLD when building AAD. |
76 | 0 | if (qwh->qos[0] & 0x80) |
77 | 0 | *A3 = ap_mld_mac; |
78 | 0 | } |
79 | 0 | } |
80 | 0 | } Unexecuted instantiation: dot11decrypt.c:dot11decrypt_get_nonce_aad_addrs Unexecuted instantiation: dot11decrypt_util.c:dot11decrypt_get_nonce_aad_addrs Unexecuted instantiation: dot11decrypt_ccmp.c:dot11decrypt_get_nonce_aad_addrs Unexecuted instantiation: dot11decrypt_gcmp.c:dot11decrypt_get_nonce_aad_addrs |
81 | | |
82 | | /** |
83 | | * @brief IEEE 802.11-2016 12.7.1.2 PRF (Pseudo Random Function) |
84 | | * |
85 | | * @param key Derivation input key. |
86 | | * @param key_len Length of the key in bytes. |
87 | | * @param label Unique label for each different purpose of the PRF (named 'A' in the standard). |
88 | | * @param context Provides context to identify the derived key (named 'B' in the standard). |
89 | | * @param context_len Length of context in bytes. |
90 | | * @param hash_algo Hash algorithm to use for the PRF. |
91 | | * See gcrypt available hash algorithms: |
92 | | * https://gnupg.org/documentation/manuals/gcrypt/Available-hash-algorithms.html |
93 | | * @param[out] output Derived key. |
94 | | * @param output_len Length of derived key in bytes. |
95 | | * @return false on error |
96 | | */ |
97 | | bool |
98 | | dot11decrypt_prf(const uint8_t *key, size_t key_len, |
99 | | const char *label, |
100 | | const uint8_t *context, size_t context_len, |
101 | | int hash_algo, |
102 | | uint8_t *output, size_t output_len); |
103 | | |
104 | | /** |
105 | | * @brief Perform a KDF (Key Derivation Function) using the specified parameters. |
106 | | * |
107 | | * Reference: IEEE 802.11-2016 |
108 | | * 12.7.1.7.2 Key derivation function (KDF) |
109 | | * |
110 | | * @param key Derivation input key. |
111 | | * @param key_len Length of the key in bytes. |
112 | | * @param label A string identifying the purpose of the keys derived using this KDF. |
113 | | * @param context Provides context to identify the derived key. |
114 | | * @param context_len Length of context in bytes. |
115 | | * @param hash_algo Hash algorithm to use for the KDF. |
116 | | * See gcrypt available hash algorithms: |
117 | | * https://gnupg.org/documentation/manuals/gcrypt/Available-hash-algorithms.html |
118 | | * @param[out] output Derived key. |
119 | | * @param output_len Length of derived key in bytes. |
120 | | * @return false on error |
121 | | */ |
122 | | bool |
123 | | dot11decrypt_kdf(const uint8_t *key, size_t key_len, |
124 | | const char *label, |
125 | | const uint8_t *context, size_t context_len, |
126 | | int hash_algo, |
127 | | uint8_t *output, size_t output_len); |
128 | | |
129 | | /** |
130 | | * @brief Derive PMK-R0 using the provided parameters |
131 | | * |
132 | | * Derive PMK-R0 and PMKR0Name. See IEEE 802.11-2016 12.7.1.7.3 PMK-R0 |
133 | | * |
134 | | * @param xxkey PSK / MPMK or certain part of MSK. |
135 | | * @param xxkey_len Length of xxkey in bytes. |
136 | | * @param ssid SSID |
137 | | * @param ssid_len Length of SSID in bytes. |
138 | | * @param mdid MDID (Mobility Domain Identifier). |
139 | | * @param r0kh_id PMK-R0 key holder identifier in the Authenticator. |
140 | | * @param r0kh_id_len Length of r0kh_id in bytes. |
141 | | * @param s0kh_id PMK-R0 key holder in the Supplicant (STA mac address) |
142 | | * @param hash_algo Hash algorithm to use for the KDF. |
143 | | * See gcrypt available hash algorithms: |
144 | | * https://gnupg.org/documentation/manuals/gcrypt/Available-hash-algorithms.html |
145 | | * @param[out] pmk_r0 Pairwise master key, first level |
146 | | * @param pmk_r0_len Length of pmk_r0 in bytes. |
147 | | * @param[out] pmk_r0_name Pairwise master key (PMK) R0 name. |
148 | | */ |
149 | | bool |
150 | | dot11decrypt_derive_pmk_r0(const uint8_t *xxkey, size_t xxkey_len, |
151 | | const uint8_t *ssid, size_t ssid_len, |
152 | | const uint8_t mdid[2], |
153 | | const uint8_t *r0kh_id, size_t r0kh_id_len, |
154 | | const uint8_t s0kh_id[DOT11DECRYPT_MAC_LEN], |
155 | | int hash_algo, |
156 | | uint8_t *pmk_r0, |
157 | | size_t *pmk_r0_len, |
158 | | uint8_t pmk_r0_name[16]); |
159 | | |
160 | | /** |
161 | | * @brief Derive PMK-R1 from PMK-R0 using a key derivation function. |
162 | | * |
163 | | * Derive PMK-R1 and PMKR1Name. See IEEE 802.11-2016 12.7.1.7.4 PMK-R1 |
164 | | * |
165 | | * @param pmk_r0 Pointer to the PMK-R0 buffer. |
166 | | * @param pmk_r0_len Length of the PMK-R0 buffer. |
167 | | * @param pmk_r0_name Name associated with PMK-R0. |
168 | | * @param r1kh_id R1KH ID for the key derivation. |
169 | | * @param s1kh_id S1KH ID for the key derivation. |
170 | | * @param hash_algo Hash algorithm to use for the key derivation. |
171 | | * @param pmk_r1 Pointer to the buffer where the derived PMK-R1 will be stored. |
172 | | * @param pmk_r1_len Pointer to the length of the PMK-R1 buffer, which will be updated with the actual length of the derived PMK-R1. |
173 | | * @param pmk_r1_name Pointer to the buffer where the name for the derived PMK-R1 will be stored. |
174 | | * @return true if the derivation was successful, false otherwise. |
175 | | */ |
176 | | bool |
177 | | dot11decrypt_derive_pmk_r1(const uint8_t *pmk_r0, size_t pmk_r0_len, |
178 | | const uint8_t *pmk_r0_name, |
179 | | const uint8_t *r1kh_id, const uint8_t *s1kh_id, |
180 | | int hash_algo, |
181 | | uint8_t *pmk_r1, size_t *pmk_r1_len, |
182 | | uint8_t *pmk_r1_name); |
183 | | |
184 | | /** |
185 | | * @brief Derive the FT PTK using the provided parameters. |
186 | | * |
187 | | * Derive PTK for FT AKMS. See IEE 802.11-2016 12.7.1.7.5 PTK |
188 | | * |
189 | | * PTK = KDF-Hash-Length(PMK-R1, "FT-PTK", SNonce || ANonce || BSSID || STA-ADDR) |
190 | | * PTKName = Truncate-128( |
191 | | * SHA-256(PMKR1Name || "FT-PTKN" || SNonce || ANonce || BSSID || STA-ADDR)) |
192 | | * |
193 | | * @param pmk_r1 Pointer to the PMK_R1 value. |
194 | | * @param pmk_r1_len Length of the PMK_R1 value. |
195 | | * @param pmk_r1_name Name associated with the PMK_R1. |
196 | | * @param snonce Session nonce. |
197 | | * @param anonce Authenticator nonce. |
198 | | * @param bssid Base station address. |
199 | | * @param sta_addr Station address. |
200 | | * @param hash_algo Hash algorithm to use. |
201 | | * @param ptk Pointer to store the derived PTK. |
202 | | * @param ptk_len Length of the PTK buffer. |
203 | | * @param ptk_name Name associated with the PTK. |
204 | | * @return void |
205 | | */ |
206 | | bool |
207 | | dot11decrypt_derive_ft_ptk(const uint8_t *pmk_r1, size_t pmk_r1_len, |
208 | | const uint8_t *pmk_r1_name, |
209 | | const uint8_t *snonce, const uint8_t *anonce, |
210 | | const uint8_t *bssid, const uint8_t *sta_addr, |
211 | | int hash_algo, |
212 | | uint8_t *ptk, const size_t ptk_len, uint8_t *ptk_name); |
213 | | #endif /* _DOT11DECRYPT_UTIL_H */ |
214 | | |
215 | | /* |
216 | | * Editor modelines |
217 | | * |
218 | | * Local Variables: |
219 | | * c-basic-offset: 4 |
220 | | * tab-width: 8 |
221 | | * indent-tabs-mode: nil |
222 | | * End: |
223 | | * |
224 | | * ex: set shiftwidth=4 tabstop=8 expandtab: |
225 | | * :indentSize=4:tabSize=8:noTabs=true: |
226 | | */ |