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 #[must_use]
63 pub unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
64 let ptr = core::ptr::from_ref(buf) as *const Self;
65
66 unsafe { &*ptr }
69 }
70
71 pub fn cast_mut(buf: &mut [u8]) -> TpmResult<&mut Self> {
82 Self::validate(buf)?;
83
84 Ok(unsafe { Self::cast_mut_unchecked(buf) })
88 }
89
90 pub fn cast_prefix_mut(buf: &mut [u8]) -> TpmResult<(&mut Self, &mut [u8])> {
96 let wire_len = Self::validate_prefix(buf)?;
97 let (head, tail) = buf.split_at_mut(wire_len);
98
99 Ok((unsafe { Self::cast_mut_unchecked(head) }, tail))
102 }
103
104 #[must_use]
113 pub unsafe fn cast_mut_unchecked(buf: &mut [u8]) -> &mut Self {
114 let ptr = core::ptr::from_mut(buf) as *mut Self;
115
116 unsafe { &mut *ptr }
119 }
120
121 #[must_use]
123 pub const fn as_bytes(&self) -> &[u8] {
124 &self.0
125 }
126
127 #[must_use]
129 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
130 &mut self.0
131 }
132
133 #[must_use]
135 pub fn size(&self) -> usize {
136 Self::read_size(&self.0)
137 }
138
139 #[must_use]
141 pub fn data(&self) -> &[u8] {
142 &self.0[TPM2B_SIZE_LEN..]
143 }
144
145 #[must_use]
147 pub fn payload(&self) -> &[u8] {
148 self.data()
149 }
150
151 #[must_use]
153 pub fn data_mut(&mut self) -> &mut [u8] {
154 &mut self.0[TPM2B_SIZE_LEN..]
155 }
156
157 #[must_use]
159 pub fn payload_mut(&mut self) -> &mut [u8] {
160 self.data_mut()
161 }
162
163 #[must_use]
165 pub const fn len(&self) -> usize {
166 self.0.len()
167 }
168
169 #[must_use]
171 pub fn is_empty(&self) -> bool {
172 self.size() == 0
173 }
174
175 pub fn validate(buf: &[u8]) -> TpmResult<()> {
182 let wire_len = Self::validate_prefix(buf)?;
183
184 if buf.len() > wire_len {
185 return Err(TpmError::TrailingData(
186 crate::TpmErrorValue::new(wire_len).actual(buf.len() - wire_len),
187 ));
188 }
189
190 Ok(())
191 }
192
193 pub fn validate_prefix(buf: &[u8]) -> TpmResult<usize> {
199 if buf.len() < TPM2B_SIZE_LEN {
200 return Err(TpmError::UnexpectedEnd(
201 crate::TpmErrorValue::new(0).size(TPM2B_SIZE_LEN, buf.len()),
202 ));
203 }
204
205 let payload_len = Self::read_size(buf);
206 if payload_len > CAPACITY {
207 return Err(TpmError::TooManyBytes(
208 crate::TpmErrorValue::new(0).limit(CAPACITY, payload_len),
209 ));
210 }
211
212 let wire_len = TPM2B_SIZE_LEN
213 .checked_add(payload_len)
214 .ok_or(TpmError::IntegerTooLarge(
215 crate::TpmErrorValue::new(0).value_usize(payload_len),
216 ))?;
217
218 if buf.len() < wire_len {
219 return Err(TpmError::UnexpectedEnd(
220 crate::TpmErrorValue::new(TPM2B_SIZE_LEN)
221 .size(payload_len, buf.len().saturating_sub(TPM2B_SIZE_LEN)),
222 ));
223 }
224
225 Ok(wire_len)
226 }
227
228 fn read_size(buf: &[u8]) -> usize {
229 usize::from(u16::from_be_bytes([buf[0], buf[1]]))
230 }
231}
232
233impl<const CAPACITY: usize> TpmCast for Tpm2b<CAPACITY> {
234 fn cast(buf: &[u8]) -> TpmResult<&Self> {
235 Self::cast(buf)
236 }
237
238 fn cast_prefix(buf: &[u8]) -> TpmResult<(&Self, &[u8])> {
239 Self::cast_prefix(buf)
240 }
241
242 unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
243 unsafe { Self::cast_unchecked(buf) }
245 }
246}
247
248impl<const CAPACITY: usize> TpmCastMut for Tpm2b<CAPACITY> {
249 fn cast_mut(buf: &mut [u8]) -> TpmResult<&mut Self> {
250 Self::cast_mut(buf)
251 }
252
253 fn cast_prefix_mut(buf: &mut [u8]) -> TpmResult<(&mut Self, &mut [u8])> {
254 Self::cast_prefix_mut(buf)
255 }
256
257 unsafe fn cast_mut_unchecked(buf: &mut [u8]) -> &mut Self {
258 unsafe { Self::cast_mut_unchecked(buf) }
261 }
262}
263
264impl<'a, const CAPACITY: usize> crate::TpmField<'a> for TpmBuffer<CAPACITY> {
265 type View = &'a Tpm2b<CAPACITY>;
266
267 fn cast_prefix_field(buf: &'a [u8]) -> TpmResult<(Self::View, &'a [u8])> {
268 Tpm2b::<CAPACITY>::cast_prefix(buf)
269 }
270}
271
272impl<const CAPACITY: usize> AsRef<[u8]> for Tpm2b<CAPACITY> {
273 fn as_ref(&self) -> &[u8] {
274 self.as_bytes()
275 }
276}
277
278impl<const CAPACITY: usize> AsMut<[u8]> for Tpm2b<CAPACITY> {
279 fn as_mut(&mut self) -> &mut [u8] {
280 self.as_bytes_mut()
281 }
282}
283
284#[derive(Clone, Copy)]
289pub struct TpmBuffer<const CAPACITY: usize> {
290 size: u16,
291 data: [MaybeUninit<u8>; CAPACITY],
292}
293
294impl<const CAPACITY: usize> TpmBuffer<CAPACITY> {
295 #[must_use]
297 pub const fn new() -> Self {
298 Self {
299 size: 0,
300 data: [const { MaybeUninit::uninit() }; CAPACITY],
301 }
302 }
303
304 pub fn try_push(&mut self, byte: u8) -> TpmResult<()> {
311 if (self.size as usize) >= CAPACITY || self.size == u16::MAX {
312 return Err(TpmError::BufferOverflow(
313 crate::TpmErrorValue::new(self.size as usize)
314 .limit(CAPACITY, self.size as usize + 1),
315 ));
316 }
317 self.data[self.size as usize].write(byte);
318 self.size += 1;
319 Ok(())
320 }
321
322 pub fn try_extend_from_slice(&mut self, slice: &[u8]) -> TpmResult<()> {
329 let current_len = self.size as usize;
330 let new_len = current_len
331 .checked_add(slice.len())
332 .ok_or(TpmError::BufferOverflow(
333 crate::TpmErrorValue::new(current_len)
334 .size(slice.len(), CAPACITY.saturating_sub(current_len)),
335 ))?;
336
337 if new_len > CAPACITY {
338 return Err(TpmError::BufferOverflow(
339 crate::TpmErrorValue::new(current_len).limit(CAPACITY, new_len),
340 ));
341 }
342
343 self.size = u16::try_from(new_len).map_err(|_| {
344 TpmError::BufferOverflow(
345 crate::TpmErrorValue::new(current_len).limit(u16::MAX as usize, new_len),
346 )
347 })?;
348
349 for (dest, src) in self.data[current_len..new_len].iter_mut().zip(slice) {
350 dest.write(*src);
351 }
352 Ok(())
353 }
354}
355
356impl<const CAPACITY: usize> Deref for TpmBuffer<CAPACITY> {
357 type Target = [u8];
358
359 fn deref(&self) -> &Self::Target {
360 let size = self.size as usize;
361
362 unsafe { slice::from_raw_parts(self.data.as_ptr().cast::<u8>(), size) }
365 }
366}
367
368impl<const CAPACITY: usize> Default for TpmBuffer<CAPACITY> {
369 fn default() -> Self {
370 Self::new()
371 }
372}
373
374impl<const CAPACITY: usize> PartialEq for TpmBuffer<CAPACITY> {
375 fn eq(&self, other: &Self) -> bool {
376 **self == **other
377 }
378}
379
380impl<const CAPACITY: usize> Eq for TpmBuffer<CAPACITY> {}
381
382impl<const CAPACITY: usize> Hash for TpmBuffer<CAPACITY> {
383 fn hash<H: Hasher>(&self, state: &mut H) {
384 (**self).hash(state);
385 }
386}
387
388impl<const CAPACITY: usize> TpmSized for TpmBuffer<CAPACITY> {
389 const SIZE: usize = size_of::<TpmUint16>() + CAPACITY;
390 fn len(&self) -> usize {
391 size_of::<TpmUint16>() + self.size as usize
392 }
393}
394
395impl<const CAPACITY: usize> TpmMarshal for TpmBuffer<CAPACITY> {
396 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
397 TpmUint16::from(self.size).marshal(writer)?;
398 writer.write_bytes(self)
399 }
400}
401
402impl<const CAPACITY: usize> TryFrom<&[u8]> for TpmBuffer<CAPACITY> {
403 type Error = TpmError;
404
405 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
406 if slice.len() > CAPACITY {
407 return Err(TpmError::TooManyBytes(
408 crate::TpmErrorValue::new(0).limit(CAPACITY, slice.len()),
409 ));
410 }
411 let mut buffer = Self::new();
412 buffer.try_extend_from_slice(slice)?;
413 Ok(buffer)
414 }
415}
416
417impl<const CAPACITY: usize> AsRef<[u8]> for TpmBuffer<CAPACITY> {
418 fn as_ref(&self) -> &[u8] {
419 self
420 }
421}
422
423impl<const CAPACITY: usize> Debug for TpmBuffer<CAPACITY> {
424 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
425 write!(f, "TpmBuffer(")?;
426 for byte in self.iter() {
427 write!(f, "{byte:02X}")?;
428 }
429 write!(f, ")")
430 }
431}