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