1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45use crate::key::exchange::handshake::group_key::supplicant::Supplicant;
6use crate::key::exchange::{self};
7use crate::rsna::{Dot11VerifiedKeyFrame, NegotiatedProtection, Role, UpdateSink};
8use crate::{rsn_ensure, Error};
9use bytes::Bytes;
10use zerocopy::SplitByteSlice;
1112mod supplicant;
1314#[derive(Debug, PartialEq)]
15enum RoleHandler {
16 Supplicant(Supplicant),
17}
1819// Struct which carries EAPOL key frames which comply with IEEE Std 802.11-2016, 12.7.2 and
20// IEEE Std 802.11-2016, 12.7.7.
21pub struct GroupKeyHandshakeFrame<B: SplitByteSlice> {
22 frame: Dot11VerifiedKeyFrame<B>,
23}
2425impl<B: SplitByteSlice> GroupKeyHandshakeFrame<B> {
26#[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
27pub fn from_verified(frame: Dot11VerifiedKeyFrame<B>, role: Role) -> Result<Self, Error> {
28// Safe since the frame will be wrapped again in a `Dot11VerifiedKeyFrame` when being accessed.
29let raw_frame = frame.unsafe_get_raw();
3031let sender = match role {
32 Role::Supplicant => Role::Authenticator,
33 Role::Authenticator => Role::Supplicant,
34 };
3536let key_info = raw_frame.key_frame_fields.key_info();
3738// IEEE Std 802.11-2016, 12.7.7.2 & IEEE Std 802.11-2016, 12.7.7.3
39rsn_ensure!(
40 key_info.key_type() == eapol::KeyType::GROUP_SMK,
41"only group key messages are allowed in Group Key Handshake"
42);
43rsn_ensure!(
44 !key_info.install(),
45"installbit must not be set in Group Key Handshake messages"
46);
47rsn_ensure!(key_info.key_mic(), "MIC bit must be set in Group Key Handshake messages");
48rsn_ensure!(key_info.secure(), "secure bit must be set in Group Key Handshake messages");
49rsn_ensure!(!key_info.error(), "error bit must not be set in Group Key Handshake messages");
50rsn_ensure!(
51 !key_info.request(),
52"request bit must not be set in Group Key Handshake messages"
53);
5455// IEEE Std 802.11-2016, 12.7.7.2 requires the key length to be set to 0 in
56 // group key handshakes messages. Some routers, such as Apple Airport Extreme
57 // violate this specification and do send the pairwise cipher key length in group
58 // key messages as well. To support interoperability, the key length is allowed to
59 // be arbitrary as it's not used in the Group Key handshake.
6061 // IEEE Std 802.11-2016, 12.7.7.2 requires the nonce to be zeroed in group key handshakes
62 // messages. Some routers, such as Apple Airport Extreme violate this specification and do
63 // send a nonce other than zero. To support interoperability, the nonce is allowed to
64 // be an arbitrary value as it's not used in the Group Key handshake.
6566match &sender {
67// IEEE Std 802.11-2016, 12.7.7.2
68Role::Authenticator => {
69rsn_ensure!(
70 key_info.key_ack(),
71"ACK bit must be set in 1st message of Group Key Handshake"
72);
7374// WFA, WPA1 Spec. 3.1, Chapter 2.2.4
75 // WPA1 does not use the encrypted key data bit, so we don't bother checking it.
76if raw_frame.key_frame_fields.descriptor_type != eapol::KeyDescriptor::LEGACY_WPA1 {
77rsn_ensure!(
78 key_info.encrypted_key_data(),
79"encrypted data bit must be set in 1st message of Group Key Handshake"
80);
81 }
8283// IEEE Std 802.11-2016, 12.7.7.2 requires the key frame's IV to be zero'ed when
84 // using 802.1X-2004. Some routers, such as Linksys, violate this constraint.
85 // The IV is not used in the Group Key Handshake, thus, ignoring this requirement is
86 // safe.
8788 // RSC is currently not taken into account.
89}
90// IEEE Std 802.11-2016, 12.7.7.3
91Role::Supplicant => {
92rsn_ensure!(
93 !key_info.key_ack(),
94"ACK bit must not be set in 2nd message of Group Key Handshake"
95);
96rsn_ensure!(
97 !key_info.encrypted_key_data(),
98"encrypted data bit must not be set in 2nd message of Group Key Handshake"
99);
100rsn_ensure!(
101 is_zero(&raw_frame.key_frame_fields.key_iv[..]),
102"IV must be zero in 2nd message of Group Key Handshake"
103);
104rsn_ensure!(
105 raw_frame.key_frame_fields.key_rsc.to_native() == 0,
106"RSC must be zero in 2nd message of Group Key Handshake"
107);
108 }
109 };
110111Ok(GroupKeyHandshakeFrame { frame })
112 }
113114pub fn get(self) -> Dot11VerifiedKeyFrame<B> {
115self.frame
116 }
117}
118119#[derive(Debug, Clone, PartialEq)]
120pub struct Config {
121pub role: Role,
122pub protection: NegotiatedProtection,
123}
124125#[derive(Debug, PartialEq)]
126pub struct GroupKey(RoleHandler);
127128impl GroupKey {
129#[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
130pub fn new(cfg: Config, kck: &[u8], kek: &[u8]) -> Result<GroupKey, Error> {
131let handler = match &cfg.role {
132 Role::Supplicant => RoleHandler::Supplicant(Supplicant {
133 cfg,
134 kck: Bytes::copy_from_slice(kck),
135 kek: Bytes::copy_from_slice(kek),
136 }),
137_ => {
138return Err(Error::GenericError(
139"Authenticator not yet support in Group-Key Handshake".to_string(),
140 ))
141 }
142 };
143144Ok(GroupKey(handler))
145 }
146147pub fn destroy(self) -> exchange::Config {
148match self.0 {
149 RoleHandler::Supplicant(s) => exchange::Config::GroupKeyHandshake(s.destroy()),
150 }
151 }
152153#[allow(clippy::result_large_err, reason = "mass allow for https://fxbug.dev/381896734")]
154pub fn on_eapol_key_frame<B: SplitByteSlice>(
155&mut self,
156 update_sink: &mut UpdateSink,
157 frame: Dot11VerifiedKeyFrame<B>,
158 ) -> Result<(), Error> {
159match &mut self.0 {
160 RoleHandler::Supplicant(s) => {
161let frame = GroupKeyHandshakeFrame::from_verified(frame, Role::Supplicant)?;
162 s.on_eapol_key_frame(update_sink, frame)
163 }
164 }
165 }
166}
167168fn is_zero(slice: &[u8]) -> bool {
169 slice.iter().all(|&x| x == 0)
170}
171172#[cfg(test)]
173mod tests {
174use super::*;
175use crate::rsna::test_util;
176use wlan_common::ie::rsn::fake_wpa2_s_rsne;
177178fn verify_group_key_frame(key_frame: eapol::KeyFrameBuf, role: Role) {
179let protection =
180 NegotiatedProtection::from_rsne(&fake_wpa2_s_rsne()).expect("error getting RNSE");
181let parsed_frame = eapol::KeyFrameRx::parse(test_util::mic_len(), &key_frame[..])
182 .expect("failed to parse group key frame");
183let frame = Dot11VerifiedKeyFrame::from_frame(parsed_frame, &role, &protection, 0)
184 .expect("couldn't verify frame");
185 GroupKeyHandshakeFrame::from_verified(frame, role).expect("error verifying group_frame");
186 }
187188fn fake_key_frame() -> eapol::KeyFrameTx {
189let mut key_frame_fields = eapol::KeyFrameFields::default();
190 key_frame_fields.descriptor_type = eapol::KeyDescriptor::IEEE802DOT11;
191 key_frame_fields.set_key_info(eapol::KeyInformation(0b01001110000010));
192 eapol::KeyFrameTx::new(
193 eapol::ProtocolVersion::IEEE802DOT1X2004,
194 key_frame_fields,
195vec![],
196 test_util::mic_len(),
197 )
198 }
199200#[test]
201fn zeroed_iv_8021x2004() {
202let mut key_frame = fake_key_frame();
203 key_frame.protocol_version = eapol::ProtocolVersion::IEEE802DOT1X2004;
204let key_frame = key_frame
205 .serialize()
206 .finalize_with_mic(&vec![0u8; test_util::mic_len()][..])
207 .expect("failed to construct key frame");
208 verify_group_key_frame(key_frame, Role::Supplicant);
209 }
210211#[test]
212fn random_iv_8021x2004() {
213let mut key_frame = fake_key_frame();
214 key_frame.protocol_version = eapol::ProtocolVersion::IEEE802DOT1X2004;
215// IEEE does not allow random IV in combination with 802.1X-2004.
216key_frame.key_frame_fields.key_iv.copy_from_slice(&[1; 16]);
217let key_frame = key_frame
218 .serialize()
219 .finalize_with_mic(&vec![0u8; test_util::mic_len()][..])
220 .expect("failed to construct key frame");
221 verify_group_key_frame(key_frame, Role::Supplicant);
222 }
223224#[test]
225fn zeroed_iv_8021x2001() {
226let mut key_frame = fake_key_frame();
227 key_frame.protocol_version = eapol::ProtocolVersion::IEEE802DOT1X2001;
228let key_frame = key_frame
229 .serialize()
230 .finalize_with_mic(&vec![0u8; test_util::mic_len()][..])
231 .expect("failed to construct key frame");
232 verify_group_key_frame(key_frame, Role::Supplicant);
233 }
234235#[test]
236fn random_iv_8021x2001() {
237let mut key_frame = fake_key_frame();
238 key_frame.protocol_version = eapol::ProtocolVersion::IEEE802DOT1X2001;
239 key_frame.key_frame_fields.key_iv.copy_from_slice(&[1; 16]);
240let key_frame = key_frame
241 .serialize()
242 .finalize_with_mic(&vec![0u8; test_util::mic_len()][..])
243 .expect("failed to construct key frame");
244 verify_group_key_frame(key_frame, Role::Supplicant);
245 }
246}