| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| #![feature(test)] |
| #![deny(warnings)] |
| |
| #[macro_use] |
| extern crate bitfield; |
| #[macro_use] |
| extern crate nom; |
| extern crate test; |
| |
| use nom::{be_u16, be_u64, be_u8}; |
| |
| // IEEE Std 802.1X-2010, 11.9, Table 11-5 |
| pub enum KeyDescriptor { |
| Rc4 = 1, |
| Ieee802dot11 = 2, |
| } |
| |
| // IEEE Std 802.1X-2010, 11.3.1 |
| pub enum ProtocolVersion { |
| Ieee802dot1x2010 = 3, |
| } |
| |
| // IEEE Std 802.1X-2010, 11.3.2, Table 11-3 |
| pub enum PacketType { |
| Eap = 0, |
| Start = 1, |
| Logoff = 2, |
| Key = 3, |
| AsfAlert = 4, |
| Mka = 5, |
| AnnouncementGeneric = 6, |
| AnnouncementSpecific = 7, |
| AnnouncementReq = 8, |
| } |
| |
| // IEEE Std 802.11-2016, 12.7.2, Figure 12-33 |
| bitfield! { |
| pub struct KeyInformation(u16); |
| impl Debug; |
| pub key_descriptor_version, set_key_descriptor_version: 2, 0; |
| pub key_type, set_key_type: 3, 3; |
| // Bit 4-5 reserved. |
| pub install, set_install: 6; |
| pub key_ack, set_key_ack: 7; |
| pub key_mic, set_key_mic: 8; |
| pub secure, set_secure: 9; |
| pub error, set_error: 10; |
| pub request, set_request: 11; |
| pub encrypted_key_data, set_encrypted_key_data: 12; |
| pub smk_message, set_smk_message: 13; |
| value, _: 15,0; |
| // Bit 14-15 reserved. |
| } |
| |
| impl Default for KeyInformation { |
| fn default() -> KeyInformation { |
| KeyInformation(0) |
| } |
| } |
| |
| // IEEE Std 802.11-2016, 12.7.2, Figure 12-32 |
| #[derive(Default, Debug)] |
| pub struct KeyFrame<'a> { |
| pub version: u8, |
| pub packet_type: u8, |
| pub packet_body_len: u16, |
| |
| pub descriptor_type: u8, |
| pub key_info: KeyInformation, |
| pub key_len: u16, |
| pub key_replay_counter: u64, |
| pub key_nonce: &'a [u8], // 32 octets |
| pub key_iv: &'a [u8], // 16 octets |
| pub key_rsc: u64, |
| // 8 octests reserved. |
| pub key_mic: &'a [u8], // AKM dependent size |
| pub key_data_len: u16, |
| pub key_data: &'a [u8], |
| } |
| |
| named_args!(pub key_frame_from_bytes(mic_size: u16) <KeyFrame>, |
| do_parse!( |
| version: be_u8 >> |
| packet_type: verify!(be_u8, |v:u8| v == PacketType::Key as u8) >> |
| packet_body_len: be_u16 >> |
| |
| descriptor_type: be_u8 >> |
| key_info: map!(be_u16, KeyInformation) >> |
| key_len: be_u16 >> |
| key_replay_counter: be_u64 >> |
| key_nonce: take!(32) >> |
| key_iv: take!(16) >> |
| key_rsc: be_u64 >> |
| take!(8 /* reserved octets */) >> |
| key_mic: take!(mic_size) >> |
| key_data_len: be_u16 >> |
| key_data: take!(key_data_len) >> |
| eof!() >> |
| (KeyFrame{ |
| version: version, |
| packet_type: packet_type, |
| packet_body_len: packet_body_len, |
| descriptor_type: descriptor_type, |
| key_info: key_info, |
| key_len: key_len, |
| key_replay_counter: key_replay_counter, |
| key_mic: key_mic, |
| key_rsc: key_rsc, |
| key_iv: key_iv, |
| key_nonce: key_nonce, |
| key_data_len: key_data_len, |
| key_data: key_data, |
| }) |
| ) |
| ); |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| use test::{black_box, Bencher}; |
| |
| #[bench] |
| fn bench_key_frame_from_bytes(b: &mut Bencher) { |
| let frame: Vec<u8> = vec![ |
| 0x01, 0x03, 0x00, 0x5f, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, |
| 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, |
| 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x54, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, |
| 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, |
| 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, |
| 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, |
| 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, |
| 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x02, |
| 0x03, |
| ]; |
| b.iter(|| key_frame_from_bytes(&frame, black_box(16))); |
| } |
| |
| #[test] |
| fn test_no_key_frame() { |
| let frame: Vec<u8> = vec![ |
| 0x01, 0x01, 0x00, 0x5f, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, |
| 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, |
| 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, |
| ]; |
| let result = key_frame_from_bytes(&frame, 16); |
| assert_eq!(result.is_done(), false); |
| } |
| |
| #[test] |
| fn test_too_long() { |
| let frame: Vec<u8> = vec![ |
| 0x01, 0x03, 0x00, 0x5f, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, |
| 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, |
| 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x03, 0x01, 0x02, 0x03, 0x04, |
| ]; |
| let result = key_frame_from_bytes(&frame, 16); |
| assert_eq!(result.is_done(), false); |
| } |
| |
| #[test] |
| fn test_too_short() { |
| let frame: Vec<u8> = vec![ |
| 0x01, 0x03, 0x00, 0x5f, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, |
| 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, |
| 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x03, 0x01, |
| ]; |
| let result = key_frame_from_bytes(&frame, 16); |
| assert_eq!(result.is_done(), false); |
| } |
| |
| #[test] |
| fn test_correct_packet() { |
| let frame: Vec<u8> = vec![ |
| 0x01, 0x03, 0x00, 0x5f, 0x02, 0x00, 0x8a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x01, 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, |
| 0xfe, 0xc3, 0xb9, 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, |
| 0xf8, 0xc7, 0xca, 0x55, 0x86, 0xbc, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x03, 0x01, 0x02, 0x03, |
| ]; |
| let result = key_frame_from_bytes(&frame, 16); |
| assert_eq!(result.is_done(), true); |
| let keyframe: KeyFrame = result.unwrap().1; |
| assert_eq!(keyframe.version, 1); |
| assert_eq!(keyframe.packet_type, 3); |
| assert_eq!(keyframe.packet_body_len, 95); |
| assert_eq!(keyframe.descriptor_type, 2); |
| assert_eq!(keyframe.key_info.value(), 0x008a); |
| assert_eq!(keyframe.key_info.key_descriptor_version(), 2); |
| assert_eq!(keyframe.key_info.key_ack(), true); |
| assert_eq!(keyframe.key_len, 16); |
| assert_eq!(keyframe.key_replay_counter, 1); |
| let nonce: Vec<u8> = vec![ |
| 0x39, 0x5c, 0xc7, 0x6e, 0x1a, 0xe9, 0x9f, 0xa0, 0xb1, 0x22, 0x79, 0xfe, 0xc3, 0xb9, |
| 0xa9, 0x9e, 0x1d, 0x9a, 0x21, 0xb8, 0x47, 0x51, 0x38, 0x98, 0x25, 0xf8, 0xc7, 0xca, |
| 0x55, 0x86, 0xbc, 0xda, |
| ]; |
| assert_eq!(&keyframe.key_nonce[..], &nonce[..]); |
| assert_eq!(keyframe.key_rsc, 0); |
| let mic = [0; 16]; |
| assert_eq!(&keyframe.key_mic[..], mic); |
| assert_eq!(keyframe.key_data_len, 3); |
| let data: Vec<u8> = vec![0x01, 0x02, 0x03]; |
| assert_eq!(&keyframe.key_data[..], &data[..]); |
| } |
| } |