tpm2_protocol/basic/
buffer.rs1use crate::{TpmMarshal, TpmProtocolError, TpmResult, TpmSized, TpmUnmarshal, TpmWriter};
6use core::{convert::TryFrom, fmt::Debug, mem::size_of, ops::Deref};
7
8#[derive(Clone, Copy, PartialEq, Eq)]
13pub struct TpmBuffer<const CAPACITY: usize> {
14 size: u16,
15 data: [u8; CAPACITY],
16}
17
18impl<const CAPACITY: usize> TpmBuffer<CAPACITY> {
19 #[must_use]
21 pub const fn new() -> Self {
22 Self {
23 size: 0,
24 data: [0; CAPACITY],
25 }
26 }
27
28 pub fn try_push(&mut self, byte: u8) -> TpmResult<()> {
35 if (self.size as usize) >= CAPACITY || self.size == u16::MAX {
36 return Err(TpmProtocolError::OutOfMemory);
37 }
38 self.data[self.size as usize] = byte;
39 self.size += 1;
40 Ok(())
41 }
42
43 pub fn try_extend_from_slice(&mut self, slice: &[u8]) -> TpmResult<()> {
50 let current_len = self.size as usize;
51 let new_len = current_len
52 .checked_add(slice.len())
53 .ok_or(TpmProtocolError::OutOfMemory)?;
54
55 if new_len > CAPACITY {
56 return Err(TpmProtocolError::OutOfMemory);
57 }
58
59 self.size = u16::try_from(new_len).map_err(|_| TpmProtocolError::OutOfMemory)?;
60 self.data[current_len..new_len].copy_from_slice(slice);
61 Ok(())
62 }
63}
64
65impl<const CAPACITY: usize> Deref for TpmBuffer<CAPACITY> {
66 type Target = [u8];
67
68 fn deref(&self) -> &Self::Target {
69 let size = self.size as usize;
70 &self.data[..size]
71 }
72}
73
74impl<const CAPACITY: usize> Default for TpmBuffer<CAPACITY> {
75 fn default() -> Self {
76 Self::new()
77 }
78}
79
80impl<const CAPACITY: usize> TpmSized for TpmBuffer<CAPACITY> {
81 const SIZE: usize = size_of::<u16>() + CAPACITY;
82 fn len(&self) -> usize {
83 size_of::<u16>() + self.size as usize
84 }
85}
86
87impl<const CAPACITY: usize> TpmMarshal for TpmBuffer<CAPACITY> {
88 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
89 self.size.marshal(writer)?;
90 writer.write_bytes(&self.data[..self.size as usize])
91 }
92}
93
94impl<const CAPACITY: usize> TpmUnmarshal for TpmBuffer<CAPACITY> {
95 fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
96 let (native_size, remainder) = u16::unmarshal(buf)?;
97 let size_usize = native_size as usize;
98
99 if size_usize > CAPACITY {
100 return Err(TpmProtocolError::TooManyBytes);
101 }
102
103 if remainder.len() < size_usize {
104 return Err(TpmProtocolError::UnexpectedEnd);
105 }
106
107 let mut buffer = Self::new();
108 buffer.size = native_size;
109 buffer.data[..size_usize].copy_from_slice(&remainder[..size_usize]);
110 Ok((buffer, &remainder[size_usize..]))
111 }
112}
113
114impl<'a, const CAPACITY: usize> TryFrom<&'a [u8]> for TpmBuffer<CAPACITY> {
115 type Error = TpmProtocolError;
116
117 fn try_from(slice: &'a [u8]) -> Result<Self, Self::Error> {
118 if slice.len() > CAPACITY {
119 return Err(TpmProtocolError::TooManyBytes);
120 }
121 let mut buffer = Self::new();
122 let len_u16 = u16::try_from(slice.len()).map_err(|_| TpmProtocolError::OperationFailed)?;
123 buffer.size = len_u16;
124 buffer.data[..slice.len()].copy_from_slice(slice);
125 Ok(buffer)
126 }
127}
128
129impl<const CAPACITY: usize> AsRef<[u8]> for TpmBuffer<CAPACITY> {
130 fn as_ref(&self) -> &[u8] {
131 self
132 }
133}
134
135impl<const CAPACITY: usize> Debug for TpmBuffer<CAPACITY> {
136 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
137 write!(f, "TpmBuffer(")?;
138 for byte in self.iter() {
139 write!(f, "{byte:02X}")?;
140 }
141 write!(f, ")")
142 }
143}