leodos_protocols/datalink/security/sdls/
security_header.rs1use super::{Error, SecurityAssociation};
4
5#[derive(Debug)]
15pub struct SecurityHeader<'a> {
16 spi: u16,
17 iv: &'a [u8],
18 sn: &'a [u8],
19 pl: &'a [u8],
20}
21
22impl<'a> SecurityHeader<'a> {
23 pub fn parse(
26 sa: &SecurityAssociation,
27 bytes: &'a [u8],
28 ) -> Result<Self, Error> {
29 let hdr_size = sa.header_size();
30 if bytes.len() < hdr_size {
31 return Err(Error::FrameTooShort);
32 }
33
34 let spi =
35 u16::from_be_bytes([bytes[0], bytes[1]]);
36 let mut pos = 2;
37
38 let iv_len = sa.iv_len as usize;
39 let iv = &bytes[pos..pos + iv_len];
40 pos += iv_len;
41
42 let sn_len = sa.sn_len as usize;
43 let sn = &bytes[pos..pos + sn_len];
44 pos += sn_len;
45
46 let pl_len = sa.pl_len as usize;
47 let pl = &bytes[pos..pos + pl_len];
48
49 Ok(Self { spi, iv, sn, pl })
50 }
51
52 pub fn spi(&self) -> u16 {
54 self.spi
55 }
56
57 pub fn iv(&self) -> &[u8] {
59 self.iv
60 }
61
62 pub fn sequence_number(&self) -> &[u8] {
64 self.sn
65 }
66
67 pub fn sequence_number_value(&self) -> u64 {
69 let mut buf = [0u8; 8];
70 let len = self.sn.len();
71 if len > 0 {
72 let start = 8 - len;
73 buf[start..].copy_from_slice(self.sn);
74 }
75 u64::from_be_bytes(buf)
76 }
77
78 pub fn pad_length(&self) -> u16 {
80 let len = self.pl.len();
81 if len == 0 {
82 return 0;
83 }
84 let mut buf = [0u8; 2];
85 let start = 2 - len;
86 buf[start..].copy_from_slice(self.pl);
87 u16::from_be_bytes(buf)
88 }
89}
90
91#[derive(Debug)]
95pub struct SecurityTrailer<'a> {
96 mac: &'a [u8],
97}
98
99impl<'a> SecurityTrailer<'a> {
100 pub fn parse(
102 sa: &SecurityAssociation,
103 bytes: &'a [u8],
104 ) -> Result<Self, Error> {
105 let mac_len = sa.mac_len as usize;
106 if bytes.len() < mac_len {
107 return Err(Error::FrameTooShort);
108 }
109 Ok(Self {
110 mac: &bytes[..mac_len],
111 })
112 }
113
114 pub fn mac(&self) -> &[u8] {
116 self.mac
117 }
118}