Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */