use lora_packet::{AppKey, FNwkSIntKey, LoraPacket, NwkKey, NwkSKey, SNwkSIntKey, V1_0MicKeys, V1_1MicKeys};
fn hex_to_vec(s: &str) -> Vec<u8> {
hex::decode(s).expect("valid hex string")
}
fn key_from_hex(s: &str) -> [u8; 16] {
let v = hex_to_vec(s);
let mut arr = [0u8; 16];
arr.copy_from_slice(&v);
arr
}
#[test]
fn should_calculate_and_verify_correct_data_packet_mic_1() {
let bytes = hex_to_vec("40F17DBE4900020001954378762B11FF0D");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_s_key = NwkSKey::new(key_from_hex("44024241ed4ce9a68c6a8bc055233fd3"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0x2b, 0x11, 0xff, 0x0d]);
assert!(packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_calculate_and_verify_correct_data_packet_mic_2() {
let bytes = hex_to_vec("40F17DBE49000300012A3518AF");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_s_key = NwkSKey::new(key_from_hex("44024241ed4ce9a68c6a8bc055233fd3"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0x2a, 0x35, 0x18, 0xaf]);
assert!(packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_detect_incorrect_data_packet_mic() {
let bytes = hex_to_vec("40F17DBE49000300012A3518AA");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_s_key = NwkSKey::new(key_from_hex("44024241ed4ce9a68c6a8bc055233fd3"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0x2a, 0x35, 0x18, 0xaf]);
assert!(!packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_calculate_and_verify_correct_data_packet_mic_for_ack() {
let bytes = hex_to_vec("60f17dbe4920020001f9d65d27");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_s_key = NwkSKey::new(key_from_hex("44024241ed4ce9a68c6a8bc055233fd3"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0xf9, 0xd6, 0x5d, 0x27]);
assert!(packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn recalculate_mic_overwrites_existing_data_packet_mic() {
let bytes = hex_to_vec("60f17dbe4920020001f9d65d27");
let mut packet = LoraPacket::from_wire(&bytes).unwrap();
packet.mic = [0xEE, 0xEE, 0xEE, 0xEE];
assert_eq!(packet.mic, [0xEE, 0xEE, 0xEE, 0xEE]);
let nwk_s_key = NwkSKey::new(key_from_hex("44024241ed4ce9a68c6a8bc055233fd3"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
..Default::default()
};
assert!(!packet.verify_mic_v1_0(&keys).unwrap());
packet.recalculate_mic_v1_0(&keys).unwrap();
assert!(packet.verify_mic_v1_0(&keys).unwrap());
assert_eq!(packet.mic, [0xf9, 0xd6, 0x5d, 0x27]);
}
#[test]
fn recalculate_mic_updates_phy_payload() {
let bytes = hex_to_vec("40f17dbe490002000195437876eeeeeeee");
let expected_phy_payload = hex_to_vec("40f17dbe4900020001954378762b11ff0d");
let mut packet = LoraPacket::from_wire(&bytes).unwrap();
assert_eq!(packet.mic, [0xEE, 0xEE, 0xEE, 0xEE]);
let nwk_s_key = NwkSKey::new(key_from_hex("44024241ed4ce9a68c6a8bc055233fd3"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
..Default::default()
};
assert!(!packet.verify_mic_v1_0(&keys).unwrap());
packet.recalculate_mic_v1_0(&keys).unwrap();
assert!(packet.verify_mic_v1_0(&keys).unwrap());
assert_eq!(packet.mic, [0x2b, 0x11, 0xff, 0x0d]);
assert_eq!(packet.phy_payload, expected_phy_payload);
}
#[test]
fn should_calculate_and_verify_correct_join_request_mic() {
let bytes = hex_to_vec("0039363463336913AA05693574323831330489C65B1304");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let app_key = AppKey::new(key_from_hex("98929b92c49edba9676d646d3b612456"));
let keys = V1_0MicKeys {
app_key: Some(&app_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0xc6, 0x5b, 0x13, 0x04]);
assert!(packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_detect_incorrect_join_request_mic() {
let bytes = hex_to_vec("0039363463336913AA05693574323831330489C65B1305");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let app_key = AppKey::new(key_from_hex("98929b92c49edba9676d646d3b612456"));
let keys = V1_0MicKeys {
app_key: Some(&app_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0xc6, 0x5b, 0x13, 0x04]);
assert!(!packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_calculate_and_verify_correct_join_accept_mic() {
let bytes = hex_to_vec("20386337CCBBAAE7CD2C010000D9D0A6E7");
let ja = lora_packet::JoinAccept::from_plaintext(&bytes).unwrap();
let app_key = AppKey::new(key_from_hex("98929b92c49edba9676d646d3b612456"));
let mhdr = lora_packet::Mhdr::new(bytes[0]);
let mut mic_bytes = [0u8; 4];
mic_bytes.copy_from_slice(&bytes[bytes.len() - 4..]);
let packet = LoraPacket {
phy_payload: bytes.clone(),
mhdr,
mic: mic_bytes,
payload: lora_packet::Payload::JoinAccept(ja),
};
let keys = V1_0MicKeys {
app_key: Some(&app_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0xd9, 0xd0, 0xa6, 0xe7]);
assert!(packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_detect_incorrect_join_accept_mic() {
let bytes = hex_to_vec("20386337CCBBAAE7CD2C010000D9D0A6E8");
let ja = lora_packet::JoinAccept::from_plaintext(&bytes).unwrap();
let app_key = AppKey::new(key_from_hex("98929b92c49edba9676d646d3b612456"));
let mhdr = lora_packet::Mhdr::new(bytes[0]);
let mut mic_bytes = [0u8; 4];
mic_bytes.copy_from_slice(&bytes[bytes.len() - 4..]);
let packet = LoraPacket {
phy_payload: bytes.clone(),
mhdr,
mic: mic_bytes,
payload: lora_packet::Payload::JoinAccept(ja),
};
let keys = V1_0MicKeys {
app_key: Some(&app_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0xd9, 0xd0, 0xa6, 0xe7]);
assert!(!packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_calculate_and_verify_mic_with_32bit_fcnts() {
let bytes = hex_to_vec("40F17DBE4900020001954378762B11FF0D");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_s_key = NwkSKey::new(key_from_hex("44024241ed4ce9a68c6a8bc055233fd3"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
f_cnt_msb: 0x0000,
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0x2b, 0x11, 0xff, 0x0d]);
assert!(packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_calculate_and_verify_mic_in_port_0() {
let bytes = hex_to_vec("4006DC00FCC07400000244925050");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_s_key = NwkSKey::new(key_from_hex("581c4d08ef04cda30b1fef7a8b2c74b8"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
f_cnt_msb: 0x0000,
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0x44, 0x92, 0x50, 0x50]);
assert!(packet.verify_mic_v1_0(&keys).unwrap());
}
#[test]
fn should_calculate_mic_when_1_0_used_matteo_packets() {
let bytes = hex_to_vec("40F7EC10E081000002015A171220B0C6D6470FC3");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_s_key = NwkSKey::new(key_from_hex("17da125f3d55b28cc16a8111bd1d6c0b"));
let keys = V1_0MicKeys {
nwk_s_key: Some(&nwk_s_key),
f_cnt_msb: 0x0000,
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_0(&keys).unwrap(), [0xd6, 0x47, 0x0f, 0xc3]);
}
#[test]
fn should_calculate_and_verify_join_request_mic_1_1() {
let bytes = hex_to_vec("00010000000000000001000000000000000ce83685eb17");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let nwk_key = NwkKey::new(key_from_hex("01010101010101010101010101010101"));
let keys = V1_1MicKeys {
nwk_key: Some(&nwk_key),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_1(&keys).unwrap(), [0x36, 0x85, 0xeb, 0x17]);
assert!(packet.verify_mic_v1_1(&keys).unwrap());
}
#[test]
fn should_detect_incorrect_join_request_mic_1_1() {
let bytes = hex_to_vec("00010000000000000001000000000000000ce83685eb17");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let wrong_key = NwkKey::new(key_from_hex("02020202020202020202020202020202"));
let keys = V1_1MicKeys {
nwk_key: Some(&wrong_key),
..Default::default()
};
assert_ne!(packet.calculate_mic_v1_1(&keys).unwrap(), [0x36, 0x85, 0xeb, 0x17]);
assert!(!packet.verify_mic_v1_1(&keys).unwrap());
}
#[test]
fn should_calculate_and_verify_unconfirmed_data_up_mic_1_1() {
let bytes = hex_to_vec("40736310e080000000c86c36165131");
let packet = LoraPacket::from_wire(&bytes).unwrap();
let f_nwk_s_int_key = FNwkSIntKey::new(key_from_hex("e163635133105cc690cb2d57ba9c31b9"));
let s_nwk_s_int_key = SNwkSIntKey::new(key_from_hex("05ec7c795b2f0b5bcdfa710db52b9d8f"));
let keys = V1_1MicKeys {
f_nwk_s_int_key: Some(&f_nwk_s_int_key),
s_nwk_s_int_key: Some(&s_nwk_s_int_key),
f_cnt_msb: 0x0000,
conf_fcnt_down_tx_dr_tx_ch: Some([0x00, 0x00, 0x00, 0x01]),
..Default::default()
};
assert_eq!(packet.calculate_mic_v1_1(&keys).unwrap(), [0x36, 0x16, 0x51, 0x31]);
assert!(packet.verify_mic_v1_1(&keys).unwrap());
}