eapol/
lib.rs

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.
4
5#![cfg_attr(feature = "benchmarks", feature(test))]
6
7use core::mem;
8use log::warn;
9use thiserror::Error;
10use wlan_bitfield::bitfield;
11use wlan_common::append::{Append, BufferTooSmall};
12use wlan_common::big_endian::{BigEndianU16, BigEndianU64};
13use wlan_common::buffer_reader::BufferReader;
14use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, Unaligned};
15
16#[derive(Debug, Error)]
17pub enum Error {
18    #[error("unexpected end of buffer while parsing frame")]
19    FrameTruncated,
20    #[error("buffer too short to write frame")]
21    BufferTooShort,
22    #[error("attempted to parse the wrong frame type")]
23    WrongEapolFrame,
24    #[error("packet body length is {} but {} bytes are available", _0, _1)]
25    WrongPacketBodyLength(u16, u16),
26    #[error("failed to calculate mic: {}", _0)]
27    MicFunctionFailed(anyhow::Error),
28    #[error("expected mic length of {} but got a mic of length {}", _0, _1)]
29    WrongMicLen(usize, usize),
30    #[error("called finalize with a mic, but key_mic is false")]
31    UnexpectedMic,
32    #[error("called finalize without a mic, but key_mic is true")]
33    ExpectedMic,
34}
35
36impl From<BufferTooSmall> for Error {
37    fn from(_src: BufferTooSmall) -> Error {
38        Error::BufferTooShort
39    }
40}
41
42pub enum Frame<B: SplitByteSlice> {
43    Key(KeyFrameRx<B>),
44    Unsupported(Ref<B, EapolFields>),
45}
46
47impl<B: SplitByteSlice> Frame<B> {
48    pub fn parse_fixed_fields(bytes: B) -> Result<Ref<B, EapolFields>, Error> {
49        let mut reader = BufferReader::new(bytes);
50        reader.read().ok_or(Error::FrameTruncated)
51    }
52}
53
54// IEEE Std 802.11-2016, 12.7.2, Figure 12-32
55#[derive(Debug)]
56pub struct KeyFrameRx<B: SplitByteSlice> {
57    pub eapol_fields: Ref<B, EapolFields>,
58    pub key_frame_fields: Ref<B, KeyFrameFields>,
59    pub key_mic: B, /* AKM dependent size */
60    // 2 octets omitted - key data length is calculated from key_data.len()
61    pub key_data: B,
62}
63
64impl<B: SplitByteSlice> KeyFrameRx<B> {
65    pub fn parse(mic_len: usize, eapol_pdu_buf: B) -> Result<Self, Error> {
66        let mut reader = BufferReader::new(eapol_pdu_buf);
67        let eapol_fields = reader.read::<EapolFields>().ok_or(Error::FrameTruncated)?;
68        if eapol_fields.packet_body_len.to_native() > reader.bytes_remaining() as u16 {
69            return Err(Error::WrongPacketBodyLength(
70                eapol_fields.packet_body_len.to_native(),
71                reader.bytes_remaining() as u16,
72            ));
73        }
74        match eapol_fields.packet_type {
75            PacketType::KEY => {
76                let key_frame_fields = reader.read().ok_or(Error::FrameTruncated)?;
77                let key_mic = reader.read_bytes(mic_len).ok_or(Error::FrameTruncated)?;
78                let key_data_len =
79                    reader.read_unaligned::<BigEndianU16>().ok_or(Error::FrameTruncated)?;
80                let key_data = reader
81                    .read_bytes(key_data_len.get().to_native().into())
82                    .ok_or(Error::FrameTruncated)?;
83                // Some APs add additional bytes to the 802.1X body. This is odd, but doesn't break anything.
84                match reader.peek_remaining().len() {
85                    0 => (),
86                    extra => warn!(bytes = extra; "Ignoring extra bytes in eapol frame body"),
87                }
88                Ok(KeyFrameRx { eapol_fields, key_frame_fields, key_mic, key_data })
89            }
90            _ => Err(Error::WrongEapolFrame),
91        }
92    }
93
94    pub fn to_bytes(&self, clear_mic: bool) -> Vec<u8> {
95        let mut buf = Vec::new();
96        self.write_into(clear_mic, &mut buf).unwrap(); // Write to Vec never fails
97        buf.into()
98    }
99
100    /// Populates buf with the underlying bytes of this keyframe.
101    ///
102    /// If clear_mic is true, the MIC field will be populated with zeroes. This should be used when
103    /// recalculating the frame MIC during a key exchange.
104    pub fn write_into<A: Append>(&self, clear_mic: bool, buf: &mut A) -> Result<(), Error> {
105        let required_size =
106            self.eapol_fields.packet_body_len.to_native() as usize + mem::size_of::<EapolFields>();
107        if !buf.can_append(required_size) {
108            return Err(Error::BufferTooShort);
109        }
110        buf.append_value(self.eapol_fields.as_bytes())?;
111        buf.append_value(self.key_frame_fields.as_bytes())?;
112        if clear_mic {
113            buf.append_bytes_zeroed(self.key_mic.len())?;
114        } else {
115            buf.append_bytes(self.key_mic.as_bytes())?;
116        }
117        buf.append_value(&BigEndianU16::from_native(self.key_data.len() as u16))?;
118        buf.append_bytes(&self.key_data)?;
119        Ok(())
120    }
121}
122
123#[derive(Debug, Clone)]
124pub struct KeyFrameTx {
125    pub protocol_version: ProtocolVersion,
126    pub key_frame_fields: KeyFrameFields,
127    mic_len: usize,
128    key_data: Vec<u8>,
129}
130
131const KEY_DATA_LEN_BYTES: usize = 2;
132
133impl KeyFrameTx {
134    pub fn new(
135        protocol_version: ProtocolVersion,
136        key_frame_fields: KeyFrameFields,
137        key_data: Vec<u8>,
138        mic_len: usize,
139    ) -> Self {
140        KeyFrameTx { protocol_version, key_frame_fields, mic_len, key_data }
141    }
142
143    pub fn serialize(self) -> KeyFrameTxFinalizer {
144        KeyFrameTxFinalizer::new(
145            self.protocol_version,
146            self.key_frame_fields,
147            self.key_data,
148            self.mic_len,
149        )
150    }
151}
152
153/// KeyFrameTxFinalizer stores a key frame that has been serialized into a buffer, but which may
154/// still require the addition of a MIC before it can be transmitted.
155pub struct KeyFrameTxFinalizer {
156    buf: Vec<u8>,
157    mic_offset: Option<usize>,
158    mic_len: usize,
159}
160
161impl KeyFrameTxFinalizer {
162    fn new(
163        version: ProtocolVersion,
164        key_frame_fields: KeyFrameFields,
165        key_data: Vec<u8>,
166        mic_len: usize,
167    ) -> Self {
168        let packet_body_len =
169            mem::size_of::<KeyFrameFields>() + mic_len + KEY_DATA_LEN_BYTES + key_data.len();
170        let size = mem::size_of::<EapolFields>() + packet_body_len;
171        let packet_body_len = BigEndianU16::from_native(packet_body_len as u16);
172        // The Vec implementation of Append will never fail to append, so none of the expects
173        // here should ever trigger.
174        let mut buf = Vec::with_capacity(size);
175        buf.append_value(&EapolFields { version, packet_type: PacketType::KEY, packet_body_len })
176            .expect("bad eapol allocation");
177        buf.append_value(&key_frame_fields).expect("bad eapol allocation");
178        let mic_offset = if KeyInformation(key_frame_fields.key_info.to_native()).key_mic() {
179            Some(mem::size_of::<EapolFields>() + mem::size_of::<KeyFrameFields>())
180        } else {
181            None
182        };
183        buf.append_bytes_zeroed(mic_len as usize).expect("bad eapol allocation");
184        buf.append_value(&BigEndianU16::from_native(key_data.len() as u16))
185            .expect("bad eapol allocation");
186        buf.append_bytes(&key_data[..]).expect("bad eapol allocation");
187        KeyFrameTxFinalizer { buf: buf.into(), mic_offset, mic_len }
188    }
189
190    /// Access a key frame buffer that may still need to have its MIC field populated. This should
191    /// generally only be used when calculating the MIC to pass to finalize_with_mic.
192    pub fn unfinalized_buf(&self) -> &[u8] {
193        &self.buf[..]
194    }
195
196    /// Generate a final key frame buffer. Fails if the given MIC is the wrong size, or if the
197    /// key_mic bit is not set for this frame.
198    pub fn finalize_with_mic(mut self, mic: &[u8]) -> Result<KeyFrameBuf, Error> {
199        match self.mic_offset {
200            Some(offset) => {
201                if self.mic_len != mic.len() {
202                    Err(Error::WrongMicLen(self.mic_len, mic.len()))
203                } else {
204                    self.buf[offset..offset + self.mic_len].copy_from_slice(mic);
205                    Ok(KeyFrameBuf { buf: self.buf, mic_len: self.mic_len })
206                }
207            }
208            None => Err(Error::UnexpectedMic),
209        }
210    }
211
212    /// Generate a final key frame buffer. Fails if the key_mic bit is set for this frame.
213    pub fn finalize_without_mic(self) -> Result<KeyFrameBuf, Error> {
214        match self.mic_offset {
215            None => Ok(KeyFrameBuf { buf: self.buf, mic_len: self.mic_len }),
216            _ => Err(Error::ExpectedMic),
217        }
218    }
219}
220
221/// A KeyFrameBuf is a wrapper for a Vec<u8> that is guaranteed to contain a parseable
222/// eapol key frame.
223#[derive(Debug, PartialEq, Eq, Clone)]
224pub struct KeyFrameBuf {
225    buf: Vec<u8>,
226    mic_len: usize,
227}
228
229impl KeyFrameBuf {
230    /// A FinalizedKeyFrameBuf guarantees that the buffer can be parsed as a KeyFrame, so this
231    /// should always succeed. Panics if the parse somehow fails.
232    pub fn keyframe(&self) -> KeyFrameRx<&[u8]> {
233        KeyFrameRx::parse(self.mic_len, &self.buf[..])
234            .expect("finalized eapol keyframe buffer failed to parse")
235    }
236
237    /// A mutable keyframe may be rendered invalid, violating the KeyFrameBuf contract, so this
238    /// instead populates the passed buffer with the keyframe contents. Panics if the parse somehow
239    /// fails.
240    pub fn copy_keyframe_mut<'a>(&self, buf: &'a mut Vec<u8>) -> KeyFrameRx<&'a mut [u8]> {
241        buf.extend_from_slice(&self.buf[..]);
242        KeyFrameRx::parse(self.mic_len, &mut buf[..])
243            .expect("finalized eapol keyframe buffer failed to parse")
244    }
245}
246
247impl std::ops::Deref for KeyFrameBuf {
248    type Target = [u8];
249
250    fn deref(&self) -> &Self::Target {
251        &self.buf[..]
252    }
253}
254
255impl From<KeyFrameBuf> for Vec<u8> {
256    fn from(src: KeyFrameBuf) -> Vec<u8> {
257        src.buf
258    }
259}
260
261// IEEE Std 802.1X-2010, 11.9, Table 11-5
262#[derive(
263    IntoBytes,
264    KnownLayout,
265    FromBytes,
266    Immutable,
267    Debug,
268    Clone,
269    Copy,
270    PartialEq,
271    Eq,
272    Unaligned,
273    Default,
274)]
275#[repr(C)]
276pub struct KeyDescriptor(u8);
277
278impl KeyDescriptor {
279    pub const RESERVED: Self = Self(0);
280    pub const RC4: Self = Self(1);
281    pub const IEEE802DOT11: Self = Self(2);
282
283    // This descriptor is specified by the WiFi Alliance WPA standard rather than IEEE.
284    pub const LEGACY_WPA1: Self = Self(254);
285}
286
287// IEEE Std 802.11-2016, 12.7.2 b.2)
288#[derive(Debug, Clone, PartialEq, Eq, Default)]
289#[repr(C)]
290pub struct KeyType(bool);
291
292impl KeyType {
293    pub const GROUP_SMK: Self = Self(false);
294    pub const PAIRWISE: Self = Self(true);
295}
296
297// IEEE Std 802.1X-2010, 11.3.1
298#[derive(
299    IntoBytes,
300    KnownLayout,
301    FromBytes,
302    Immutable,
303    Debug,
304    Clone,
305    Copy,
306    Unaligned,
307    PartialEq,
308    Eq,
309    PartialOrd,
310    Ord,
311)]
312#[repr(C)]
313pub struct ProtocolVersion(u8);
314
315impl ProtocolVersion {
316    pub const IEEE802DOT1X2001: Self = Self(1);
317    pub const IEEE802DOT1X2004: Self = Self(2);
318    pub const IEEE802DOT1X2010: Self = Self(3);
319}
320
321// IEEE Std 802.1X-2010, 11.3.2, Table 11-3
322#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, Debug, Clone, Copy, PartialEq, Eq)]
323#[repr(C)]
324pub struct PacketType(u8);
325
326impl PacketType {
327    pub const EAP: Self = Self(0);
328    pub const START: Self = Self(1);
329    pub const LOGOFF: Self = Self(2);
330    pub const KEY: Self = Self(3);
331    pub const ASF_ALERT: Self = Self(4);
332    pub const MKA: Self = Self(5);
333    pub const ANNOUNCEMENT_GENERIC: Self = Self(6);
334    pub const ANNOUNCEMENT_SPECIFIC: Self = Self(7);
335    pub const ANNOUNCEMENT_REQ: Self = Self(8);
336}
337
338// IEEE Std 802.11-2016, 12.7.2, Figure 12-33
339#[bitfield(
340    0..=2   key_descriptor_version,
341    3       key_type as KeyType(bool),
342    // WFA, WPA1 Spec. 3.1, Chapter 2.2.4, Key Information.
343    // These bits are reserved for non-WPA1 protection.
344    4..=5   legacy_wpa1_key_id,
345    6       install,
346    7       key_ack,
347    8       key_mic,
348    9       secure,
349    10      error,
350    11      request,
351    12      encrypted_key_data,
352    13      smk_message,
353    14..=15 _, // reserved
354)]
355#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, PartialEq, Clone, Default)]
356#[repr(C)]
357pub struct KeyInformation(pub u16);
358
359#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, Debug, Clone, Unaligned)]
360#[repr(C, packed)]
361pub struct EapolFields {
362    pub version: ProtocolVersion,
363    pub packet_type: PacketType,
364    pub packet_body_len: BigEndianU16,
365}
366
367// IEEE Std 802.11-2016, 12.7.2, Figure 12-32
368#[derive(IntoBytes, KnownLayout, FromBytes, Immutable, Default, Debug, Clone, Unaligned)]
369#[repr(C, packed)]
370pub struct KeyFrameFields {
371    pub descriptor_type: KeyDescriptor,
372    key_info: BigEndianU16,
373    pub key_len: BigEndianU16,
374    pub key_replay_counter: BigEndianU64,
375    pub key_nonce: [u8; 32],
376    pub key_iv: [u8; 16],
377    pub key_rsc: BigEndianU64,
378    _reserved: [u8; 8],
379}
380
381impl KeyFrameFields {
382    pub fn new(
383        descriptor_type: KeyDescriptor,
384        key_info: KeyInformation,
385        key_len: u16,
386        key_replay_counter: u64,
387        key_nonce: [u8; 32],
388        key_iv: [u8; 16],
389        key_rsc: u64,
390    ) -> Self {
391        let KeyInformation(key_info) = key_info;
392        Self {
393            descriptor_type,
394            key_info: BigEndianU16::from_native(key_info),
395            key_len: BigEndianU16::from_native(key_len),
396            key_replay_counter: BigEndianU64::from_native(key_replay_counter),
397            key_nonce,
398            key_iv,
399            key_rsc: BigEndianU64::from_native(key_rsc),
400            _reserved: [0u8; 8],
401        }
402    }
403
404    pub fn key_info(&self) -> KeyInformation {
405        KeyInformation(self.key_info.to_native())
406    }
407    pub fn set_key_info(&mut self, key_info: KeyInformation) {
408        let KeyInformation(key_info) = key_info;
409        self.key_info = BigEndianU16::from_native(key_info);
410    }
411}
412
413pub fn to_array<A>(slice: &[u8]) -> A
414where
415    A: Sized + Default + AsMut<[u8]>,
416{
417    let mut array = Default::default();
418    <A as AsMut<[u8]>>::as_mut(&mut array).clone_from_slice(slice);
419    array
420}
421
422#[cfg(test)]
423mod tests {
424    use super::*;
425    use wlan_common::assert_variant;
426    use wlan_common::buffer_writer::BufferWriter;
427
428    #[cfg(feature = "benchmarks")]
429    mod benches {
430        use super::*;
431        use test::{black_box, Bencher};
432
433        #[bench]
434        fn bench_key_frame_from_bytes(b: &mut Bencher) {
435            let frame: Vec<u8> = vec![
436                0x01, 0x03, 0x00, 0xb3, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
437                0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
438                0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
439                0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443                0x54, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01,
444                0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
445                0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02,
446                0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01,
447                0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
448                0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02,
449                0x03,
450            ];
451            b.iter(|| KeyFrameRx::parse(black_box(16), &frame[..]));
452        }
453    }
454
455    #[test]
456    fn test_key_info() {
457        let value = 0b1010_0000_0000_0000u16;
458        let key_info = KeyInformation(value);
459        assert_eq!(key_info.key_descriptor_version(), 0);
460        assert!(key_info.smk_message());
461        let cloned = key_info.clone();
462        assert_eq!(key_info, cloned);
463    }
464
465    #[test]
466    fn test_not_key_frame() {
467        let frame: Vec<u8> = vec![
468            0x01, 0x01, 0x00, 0x5f, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
469            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
470            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
471            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475            0x00,
476        ];
477        let result = KeyFrameRx::parse(16, &frame[..]);
478        assert_variant!(result, Err(Error::WrongEapolFrame));
479    }
480
481    #[test]
482    fn test_padding_okay() {
483        let frame: Vec<u8> = vec![
484            0x01, 0x03, 0x00, 0x63, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
485            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
486            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
487            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491            0x03, 0x01, 0x02, 0x03, 0x04,
492        ];
493        KeyFrameRx::parse(16, &frame[..]).expect("parsing keyframe failed");
494    }
495
496    #[test]
497    fn test_padding_past_pdu_len_okay() {
498        let frame: Vec<u8> = vec![
499            0x01, 0x03, 0x00, 0x62, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
500            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
501            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
502            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506            0x03, 0x01, 0x02, 0x03, 0x04,
507        ];
508        KeyFrameRx::parse(16, &frame[..]).expect("parsing keyframe failed");
509    }
510
511    #[test]
512    fn test_too_short() {
513        let frame: Vec<u8> = vec![
514            0x01, 0x03, 0x00, 0x60, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
515            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
516            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
517            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521            0x03, 0x01,
522        ];
523        let result = KeyFrameRx::parse(16, &frame[..]);
524        assert_variant!(result, Err(Error::FrameTruncated));
525    }
526
527    #[test]
528    fn test_bad_packet_body_len() {
529        let frame: Vec<u8> = vec![
530            0x01, 0x03, 0x00, 0xff, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
531            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
532            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
533            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
535            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
536            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537            0x03, 0x01, 0x02, 0x03,
538        ];
539        let result = KeyFrameRx::parse(16, &frame[..]);
540        assert_variant!(result, Err(Error::WrongPacketBodyLength(0xff, 0x62)));
541    }
542
543    #[test]
544    fn test_dynamic_mic_size() {
545        let frame: Vec<u8> = vec![
546            0x01, 0x03, 0x00, 0x72, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
547            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
548            0x07, 0x08, 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1,
549            0x22, 0x79, 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38,
550            0x98, 0x25, 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00,
551            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554            0x00, 0x00, 0x03, 0x01, 0x02, 0x03,
555        ];
556        KeyFrameRx::parse(32, &frame[..]).expect("parsing keyframe failed");
557    }
558
559    #[test]
560    fn test_as_bytes() {
561        let frame: Vec<u8> = vec![
562            0x01, 0x03, 0x00, 0x62, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
563            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
564            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
565            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569            0x03, 0x01, 0x02, 0x03,
570        ];
571        let keyframe = KeyFrameRx::parse(16, &frame[..]).expect("parsing keyframe failed");
572        verify_as_bytes_result(keyframe, false, &frame[..]);
573    }
574
575    #[test]
576    fn test_as_bytes_dynamic_mic_size() {
577        let frame: Vec<u8> = vec![
578            0x01, 0x03, 0x00, 0x72, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
579            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
580            0x07, 0x08, 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1,
581            0x22, 0x79, 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38,
582            0x98, 0x25, 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00,
583            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586            0x00, 0x00, 0x03, 0x01, 0x02, 0x03,
587        ];
588        let keyframe = KeyFrameRx::parse(32, &frame[..]).expect("parsing keyframe failed");
589        verify_as_bytes_result(keyframe, false, &frame[..]);
590    }
591
592    #[test]
593    fn test_as_bytes_buffer_too_small() {
594        let frame: Vec<u8> = vec![
595            0x01, 0x03, 0x00, 0x72, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
596            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
597            0x07, 0x08, 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1,
598            0x22, 0x79, 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38,
599            0x98, 0x25, 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00,
600            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603            0x00, 0x00, 0x03, 0x01, 0x02, 0x03,
604        ];
605        let keyframe = KeyFrameRx::parse(32, &frame[..]).expect("parsing keyframe failed");
606        let mut buf = [0u8; 40];
607        let mut writer = BufferWriter::new(&mut buf[..]);
608        let result = keyframe.write_into(true, &mut writer);
609        assert_variant!(result, Err(Error::BufferTooShort));
610    }
611
612    #[test]
613    fn test_as_bytes_clear_mic() {
614        #[rustfmt::skip]
615            let frame: Vec<u8> = vec![
616                0x01, 0x03, 0x00, 0x62, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
617                0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
618                0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
619                0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622                // MIC
623                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
624                0x0F, 0x10,
625                0x00, 0x03, 0x01, 0x02, 0x03,
626            ];
627        let keyframe = KeyFrameRx::parse(16, &frame[..]).expect("parsing keyframe failed");
628
629        #[rustfmt::skip]
630            let expected: Vec<u8> = vec![
631                0x01, 0x03, 0x00, 0x62, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
632                0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
633                0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
634                0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637                // Cleared MIC
638                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639                0x00, 0x00,
640                0x00, 0x03, 0x01, 0x02, 0x03,
641            ];
642        verify_as_bytes_result(keyframe, true, &expected[..]);
643    }
644
645    fn verify_as_bytes_result(keyframe: KeyFrameRx<&[u8]>, clear_mic: bool, expected: &[u8]) {
646        let mut buf = Vec::with_capacity(128);
647        keyframe.write_into(clear_mic, &mut buf).expect("failed to convert keyframe to bytes");
648        let written = buf.len();
649        let left_over = buf.split_off(written);
650        assert_eq!(&buf[..], expected);
651        assert!(left_over.iter().all(|b| *b == 0));
652    }
653
654    #[test]
655    fn test_correct_packet() {
656        let frame: Vec<u8> = vec![
657            0x01, 0x03, 0x00, 0x62, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
658            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
659            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
660            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664            0x03, 0x01, 0x02, 0x03,
665        ];
666        let result = KeyFrameRx::parse(16, &frame[..]);
667        let keyframe = result.expect("parsing keyframe failed");
668        assert_eq!({ keyframe.eapol_fields.version }, ProtocolVersion::IEEE802DOT1X2001);
669        assert_eq!({ keyframe.eapol_fields.packet_type }, PacketType::KEY);
670        assert_eq!(keyframe.eapol_fields.packet_body_len.to_native(), 98);
671        assert_eq!({ keyframe.key_frame_fields.descriptor_type }, KeyDescriptor::IEEE802DOT11);
672        assert_eq!(keyframe.key_frame_fields.key_info(), KeyInformation(0x008a));
673        assert_eq!(keyframe.key_frame_fields.key_info().key_descriptor_version(), 2);
674        assert!(keyframe.key_frame_fields.key_info().key_ack());
675        assert_eq!(keyframe.key_frame_fields.key_len.to_native(), 16);
676        assert_eq!(keyframe.key_frame_fields.key_replay_counter.to_native(), 1);
677        let nonce: Vec<u8> = vec![
678            0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, 0xfe, 0xc3, 0xb9,
679            0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, 0xf8, 0xc7, 0xca,
680            0x55, 0x86, 0xbc, 0xda,
681        ];
682        assert_eq!(&keyframe.key_frame_fields.key_nonce[..], &nonce[..]);
683        assert_eq!(keyframe.key_frame_fields.key_rsc.to_native(), 0);
684        let mic = [0; 16];
685        assert_eq!(&keyframe.key_mic[..], mic);
686        let data: Vec<u8> = vec![0x01, 0x02, 0x03];
687        assert_eq!(&keyframe.key_data[..], &data[..]);
688    }
689
690    #[test]
691    fn test_correct_construct() {
692        let expected_frame: Vec<u8> = vec![
693            0x01, 0x03, 0x00, 0x62, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
694            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
695            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
696            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700            0x03, 0x01, 0x02, 0x03,
701        ];
702        let nonce: [u8; 32] = [
703            0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, 0xfe, 0xc3, 0xb9,
704            0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, 0xf8, 0xc7, 0xca,
705            0x55, 0x86, 0xbc, 0xda,
706        ];
707        let iv = [0u8; 16];
708        let data: Vec<u8> = vec![0x01, 0x02, 0x03];
709        let new_frame = KeyFrameTx::new(
710            ProtocolVersion::IEEE802DOT1X2001,
711            KeyFrameFields::new(
712                KeyDescriptor::IEEE802DOT11,
713                KeyInformation(0x008a),
714                16,
715                1,
716                nonce,
717                iv,
718                0,
719            ),
720            data,
721            16,
722        )
723        .serialize()
724        .finalize_without_mic()
725        .expect("failed to construct eapol keyframe without mic");
726        assert_eq!(&new_frame[..], &expected_frame[..]);
727    }
728
729    #[test]
730    fn test_construct_wrong_mic() {
731        let nonce: [u8; 32] = [
732            0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, 0xfe, 0xc3, 0xb9,
733            0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, 0xf8, 0xc7, 0xca,
734            0x55, 0x86, 0xbc, 0xda,
735        ];
736        let iv = [0u8; 16];
737        let data: Vec<u8> = vec![0x01, 0x02, 0x03];
738        let mut new_frame = KeyFrameTx::new(
739            ProtocolVersion::IEEE802DOT1X2001,
740            KeyFrameFields::new(
741                KeyDescriptor::IEEE802DOT11,
742                KeyInformation(0x018a),
743                16,
744                1,
745                nonce,
746                iv,
747                0,
748            ),
749            data,
750            16,
751        );
752        new_frame
753            .clone()
754            .serialize()
755            .finalize_without_mic()
756            .expect_err("should fail when finalizing keyframe without expected mic");
757        new_frame.key_frame_fields.key_info = BigEndianU16::from_native(0x008a);
758        new_frame
759            .serialize()
760            .finalize_with_mic(&vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16][..])
761            .expect_err("should fail when finalizing keyframe with unexpected mic");
762    }
763
764    #[test]
765    fn test_construct_with_mic() {
766        #[rustfmt::skip]
767        let expected_frame: Vec<u8> = vec![
768            0x01, 0x03, 0x00, 0x62, 0x02, 0x01, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
769            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
770            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
771            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
772            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774            // MIC
775            0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
776            0xff, 0x00,
777            0x00, 0x03, 0x01, 0x02, 0x03,
778        ];
779        #[rustfmt::skip]
780        let zeroed_mic_frame: Vec<u8> = vec![
781            0x01, 0x03, 0x00, 0x62, 0x02, 0x01, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
782            0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79,
783            0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25,
784            0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787            // MIC
788            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789            0x00, 0x00,
790            0x00, 0x03, 0x01, 0x02, 0x03,
791        ];
792        let nonce: [u8; 32] = [
793            0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, 0xfe, 0xc3, 0xb9,
794            0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, 0xf8, 0xc7, 0xca,
795            0x55, 0x86, 0xbc, 0xda,
796        ];
797        let iv = [0u8; 16];
798        let data: Vec<u8> = vec![0x01, 0x02, 0x03];
799        let mic = vec![
800            0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
801            0xff, 0x00,
802        ];
803
804        let new_frame = KeyFrameTx::new(
805            ProtocolVersion::IEEE802DOT1X2001,
806            KeyFrameFields::new(
807                KeyDescriptor::IEEE802DOT11,
808                KeyInformation(0x018a),
809                16,
810                1,
811                nonce,
812                iv,
813                0,
814            ),
815            data,
816            16,
817        )
818        .serialize();
819        assert_eq!(new_frame.unfinalized_buf(), &zeroed_mic_frame[..]);
820        let new_frame = new_frame
821            .finalize_with_mic(&mic[..])
822            .expect("failed to finalize eapol keyframe with mic");
823        assert_eq!(&new_frame[..], &expected_frame[..]);
824    }
825}