tpm2_protocol/basic/
buffer.rs1use crate::{
6 TpmCast, TpmCastMut, TpmError, TpmMarshal, TpmResult, TpmSized, TpmWriter, basic::TpmUint16,
7};
8use core::{
9 convert::TryFrom,
10 fmt::Debug,
11 hash::{Hash, Hasher},
12 mem::{MaybeUninit, size_of},
13 ops::Deref,
14 slice,
15};
16
17const TPM2B_SIZE_LEN: usize = size_of::<TpmUint16>();
18
19#[repr(transparent)]
21pub struct Tpm2b<const CAPACITY: usize>([u8]);
22
23impl<const CAPACITY: usize> Tpm2b<CAPACITY> {
24 pub fn cast(buf: &[u8]) -> TpmResult<&Self> {
35 Self::validate(buf)?;
36
37 Ok(unsafe { Self::cast_unchecked(buf) })
40 }
41
42 pub fn cast_prefix(buf: &[u8]) -> TpmResult<(&Self, &[u8])> {
48 let wire_len = Self::validate_prefix(buf)?;
49 let (head, tail) = buf.split_at(wire_len);
50
51 Ok((unsafe { Self::cast_unchecked(head) }, tail))
54 }
55
56 pub fn cast_mut(buf: &mut [u8]) -> TpmResult<&mut Self> {
67 Self::validate(buf)?;
68
69 Ok(unsafe { Self::cast_mut_unchecked(buf) })
73 }
74
75 pub fn cast_prefix_mut(buf: &mut [u8]) -> TpmResult<(&mut Self, &mut [u8])> {
81 let wire_len = Self::validate_prefix(buf)?;
82 let (head, tail) = buf.split_at_mut(wire_len);
83
84 Ok((unsafe { Self::cast_mut_unchecked(head) }, tail))
87 }
88
89 #[must_use]
91 pub const fn as_bytes(&self) -> &[u8] {
92 &self.0
93 }
94
95 #[must_use]
97 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
98 &mut self.0
99 }
100
101 #[must_use]
103 pub fn size(&self) -> usize {
104 Self::read_size(&self.0)
105 }
106
107 #[must_use]
109 pub fn data(&self) -> &[u8] {
110 &self.0[TPM2B_SIZE_LEN..]
111 }
112
113 #[must_use]
115 pub fn data_mut(&mut self) -> &mut [u8] {
116 &mut self.0[TPM2B_SIZE_LEN..]
117 }
118
119 #[must_use]
121 pub const fn len(&self) -> usize {
122 self.0.len()
123 }
124
125 #[must_use]
127 pub fn is_empty(&self) -> bool {
128 self.size() == 0
129 }
130
131 pub fn validate(buf: &[u8]) -> TpmResult<()> {
138 let wire_len = Self::validate_prefix(buf)?;
139
140 if buf.len() > wire_len {
141 return Err(TpmError::TrailingData {
142 offset: wire_len,
143 actual: buf.len() - wire_len,
144 });
145 }
146
147 Ok(())
148 }
149
150 pub fn validate_prefix(buf: &[u8]) -> TpmResult<usize> {
156 if buf.len() < TPM2B_SIZE_LEN {
157 return Err(TpmError::UnexpectedEnd {
158 offset: 0,
159 needed: TPM2B_SIZE_LEN,
160 available: buf.len(),
161 });
162 }
163
164 let payload_len = Self::read_size(buf);
165 if payload_len > CAPACITY {
166 return Err(TpmError::TooManyBytes {
167 offset: 0,
168 limit: CAPACITY,
169 actual: payload_len,
170 });
171 }
172
173 let wire_len =
174 TPM2B_SIZE_LEN
175 .checked_add(payload_len)
176 .ok_or(TpmError::IntegerTooLarge {
177 offset: 0,
178 value: crate::tpm_value(payload_len),
179 })?;
180
181 if buf.len() < wire_len {
182 return Err(TpmError::UnexpectedEnd {
183 offset: TPM2B_SIZE_LEN,
184 needed: payload_len,
185 available: buf.len().saturating_sub(TPM2B_SIZE_LEN),
186 });
187 }
188
189 Ok(wire_len)
190 }
191
192 fn read_size(buf: &[u8]) -> usize {
193 usize::from(u16::from_be_bytes([buf[0], buf[1]]))
194 }
195}
196
197impl<const CAPACITY: usize> TpmCast for Tpm2b<CAPACITY> {
198 fn cast(buf: &[u8]) -> TpmResult<&Self> {
199 Self::cast(buf)
200 }
201
202 fn cast_prefix(buf: &[u8]) -> TpmResult<(&Self, &[u8])> {
203 Self::cast_prefix(buf)
204 }
205
206 unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
207 unsafe { Self::cast_unchecked(buf) }
209 }
210}
211
212impl<const CAPACITY: usize> TpmCastMut for Tpm2b<CAPACITY> {
213 fn cast_mut(buf: &mut [u8]) -> TpmResult<&mut Self> {
214 Self::cast_mut(buf)
215 }
216
217 fn cast_prefix_mut(buf: &mut [u8]) -> TpmResult<(&mut Self, &mut [u8])> {
218 Self::cast_prefix_mut(buf)
219 }
220
221 unsafe fn cast_mut_unchecked(buf: &mut [u8]) -> &mut Self {
222 unsafe { Self::cast_mut_unchecked(buf) }
225 }
226}
227
228impl<'a, const CAPACITY: usize> crate::TpmField<'a> for TpmBuffer<CAPACITY> {
229 type View = &'a Tpm2b<CAPACITY>;
230
231 fn cast_prefix_field(buf: &'a [u8]) -> TpmResult<(Self::View, &'a [u8])> {
232 Tpm2b::<CAPACITY>::cast_prefix(buf)
233 }
234}
235
236crate::tpm_byte_view!(Tpm2b<const CAPACITY: usize>);
237
238#[derive(Clone, Copy)]
243pub struct TpmBuffer<const CAPACITY: usize> {
244 size: u16,
245 data: [MaybeUninit<u8>; CAPACITY],
246}
247
248impl<const CAPACITY: usize> TpmBuffer<CAPACITY> {
249 #[must_use]
251 pub const fn new() -> Self {
252 Self {
253 size: 0,
254 data: [const { MaybeUninit::uninit() }; CAPACITY],
255 }
256 }
257
258 pub fn try_push(&mut self, byte: u8) -> TpmResult<()> {
265 if (self.size as usize) >= CAPACITY || self.size == u16::MAX {
266 return Err(TpmError::BufferOverflow {
267 offset: self.size as usize,
268 needed: 1,
269 available: CAPACITY.saturating_sub(self.size as usize),
270 });
271 }
272 self.data[self.size as usize].write(byte);
273 self.size += 1;
274 Ok(())
275 }
276
277 pub fn try_extend_from_slice(&mut self, slice: &[u8]) -> TpmResult<()> {
284 let current_len = self.size as usize;
285 let new_len = current_len
286 .checked_add(slice.len())
287 .ok_or(TpmError::BufferOverflow {
288 offset: current_len,
289 needed: slice.len(),
290 available: CAPACITY.saturating_sub(current_len),
291 })?;
292
293 if new_len > CAPACITY {
294 return Err(TpmError::BufferOverflow {
295 offset: current_len,
296 needed: slice.len(),
297 available: CAPACITY.saturating_sub(current_len),
298 });
299 }
300
301 self.size = u16::try_from(new_len).map_err(|_| TpmError::BufferOverflow {
302 offset: current_len,
303 needed: slice.len(),
304 available: (u16::MAX as usize).saturating_sub(current_len),
305 })?;
306
307 for (dest, src) in self.data[current_len..new_len].iter_mut().zip(slice) {
308 dest.write(*src);
309 }
310 Ok(())
311 }
312}
313
314impl<const CAPACITY: usize> Deref for TpmBuffer<CAPACITY> {
315 type Target = [u8];
316
317 fn deref(&self) -> &Self::Target {
318 let size = self.size as usize;
319
320 unsafe { slice::from_raw_parts(self.data.as_ptr().cast::<u8>(), size) }
323 }
324}
325
326impl<const CAPACITY: usize> Default for TpmBuffer<CAPACITY> {
327 fn default() -> Self {
328 Self::new()
329 }
330}
331
332impl<const CAPACITY: usize> PartialEq for TpmBuffer<CAPACITY> {
333 fn eq(&self, other: &Self) -> bool {
334 **self == **other
335 }
336}
337
338impl<const CAPACITY: usize> Eq for TpmBuffer<CAPACITY> {}
339
340impl<const CAPACITY: usize> Hash for TpmBuffer<CAPACITY> {
341 fn hash<H: Hasher>(&self, state: &mut H) {
342 (**self).hash(state);
343 }
344}
345
346impl<const CAPACITY: usize> TpmSized for TpmBuffer<CAPACITY> {
347 const SIZE: usize = size_of::<TpmUint16>() + CAPACITY;
348 fn len(&self) -> usize {
349 size_of::<TpmUint16>() + self.size as usize
350 }
351}
352
353impl<const CAPACITY: usize> TpmMarshal for TpmBuffer<CAPACITY> {
354 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
355 TpmUint16::from(self.size).marshal(writer)?;
356 writer.write_bytes(self)
357 }
358}
359
360impl<const CAPACITY: usize> TryFrom<&[u8]> for TpmBuffer<CAPACITY> {
361 type Error = TpmError;
362
363 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
364 if slice.len() > CAPACITY {
365 return Err(TpmError::TooManyBytes {
366 offset: 0,
367 limit: CAPACITY,
368 actual: slice.len(),
369 });
370 }
371 let mut buffer = Self::new();
372 buffer.try_extend_from_slice(slice)?;
373 Ok(buffer)
374 }
375}
376
377impl<const CAPACITY: usize> AsRef<[u8]> for TpmBuffer<CAPACITY> {
378 fn as_ref(&self) -> &[u8] {
379 self
380 }
381}
382
383impl<const CAPACITY: usize> Debug for TpmBuffer<CAPACITY> {
384 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
385 write!(f, "TpmBuffer(")?;
386 for byte in self.iter() {
387 write!(f, "{byte:02X}")?;
388 }
389 write!(f, ")")
390 }
391}