tpm2_protocol/basic/
buffer.rs1use crate::{TpmBuild, TpmError, TpmParse, TpmResult, TpmSized, TpmWriter};
6use core::{convert::TryFrom, fmt::Debug, mem::size_of, ops::Deref};
7
8#[repr(C)]
10#[derive(Clone, Copy, PartialEq, Eq)]
11pub struct TpmBuffer<const CAPACITY: usize> {
12 size: u16,
13 data: [u8; CAPACITY],
14}
15
16impl<const CAPACITY: usize> TpmBuffer<CAPACITY> {
17 #[must_use]
19 pub const fn new() -> Self {
20 Self {
21 size: 0,
22 data: [0; CAPACITY],
23 }
24 }
25
26 fn size(&self) -> u16 {
28 u16::from_be(self.size)
29 }
30
31 fn set_size(&mut self, size: u16) {
33 self.size = size.to_be();
34 }
35}
36
37impl<const CAPACITY: usize> Deref for TpmBuffer<CAPACITY> {
38 type Target = [u8];
39
40 fn deref(&self) -> &Self::Target {
41 let size = self.size() as usize;
42 &self.data[..size]
43 }
44}
45
46impl<const CAPACITY: usize> Default for TpmBuffer<CAPACITY> {
47 fn default() -> Self {
48 Self::new()
49 }
50}
51
52impl<const CAPACITY: usize> TpmSized for TpmBuffer<CAPACITY> {
53 const SIZE: usize = size_of::<u16>() + CAPACITY;
54 fn len(&self) -> usize {
55 size_of::<u16>() + self.size() as usize
56 }
57}
58
59impl<const CAPACITY: usize> TpmBuild for TpmBuffer<CAPACITY> {
60 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
61 let native_size = self.size();
62 native_size.build(writer)?;
63 writer.write_bytes(&self.data[..native_size as usize])
64 }
65}
66
67impl<const CAPACITY: usize> TpmParse for TpmBuffer<CAPACITY> {
68 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
69 let (native_size, remainder) = u16::parse(buf)?;
70 let size_usize = native_size as usize;
71
72 if size_usize > CAPACITY {
73 return Err(TpmError::CapacityExceeded);
74 }
75
76 if remainder.len() < size_usize {
77 return Err(TpmError::DataTruncated);
78 }
79
80 let mut buffer = Self::new();
81 buffer.set_size(native_size);
82 buffer.data[..size_usize].copy_from_slice(&remainder[..size_usize]);
83 Ok((buffer, &remainder[size_usize..]))
84 }
85}
86
87impl<const CAPACITY: usize> TryFrom<&[u8]> for TpmBuffer<CAPACITY> {
88 type Error = TpmError;
89
90 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
91 if slice.len() > CAPACITY {
92 return Err(TpmError::CapacityExceeded);
93 }
94 let mut buffer = Self::new();
95 let len_u16 = u16::try_from(slice.len())?;
96 buffer.set_size(len_u16);
97 buffer.data[..slice.len()].copy_from_slice(slice);
98 Ok(buffer)
99 }
100}
101
102impl<const CAPACITY: usize> AsRef<[u8]> for TpmBuffer<CAPACITY> {
103 fn as_ref(&self) -> &[u8] {
104 self
105 }
106}
107
108impl<const CAPACITY: usize> Debug for TpmBuffer<CAPACITY> {
109 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
110 write!(f, "TpmBuffer(")?;
111 for byte in self.iter() {
112 write!(f, "{byte:02X}")?;
113 }
114 write!(f, ")")
115 }
116}