tpm2_protocol/parameters.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2025 Opinsys Oy
3// Copyright (c) 2024-2025 Jarkko Sakkinen
4
5use crate::{TpmErrorKind, TpmParse, TpmResult};
6
7/// A helper for parsing data from a TPM parameter buffer, which is
8/// prefixed with a u32 size.
9pub struct TpmParameters<'a> {
10 buf: &'a [u8],
11}
12
13impl<'a> TpmParameters<'a> {
14 /// Creates a new parameter buffer from a slice.
15 ///
16 /// It reads a `u32` size prefix, slices the buffer accordingly, and returns
17 /// the parameter buffer and the remainder of the original buffer.
18 ///
19 /// # Errors
20 ///
21 /// Returns `TpmErrorKind::Boundary` if the buffer is too small to contain
22 /// the size prefix or the data described by the size prefix.
23 /// Returns `TpmErrorKind::ValueTooLarge` if the size prefix exceeds `TPM_MAX_COMMAND_SIZE`.
24 pub fn new(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
25 let (size, buf) = u32::parse(buf)?;
26 let size = size as usize;
27
28 if size > crate::TPM_MAX_COMMAND_SIZE {
29 return Err(TpmErrorKind::ValueTooLarge);
30 }
31
32 if buf.len() < size {
33 return Err(TpmErrorKind::Boundary);
34 }
35 let (param_data, buf) = buf.split_at(size);
36 Ok((Self { buf: param_data }, buf))
37 }
38
39 /// Parses a single value from the buffer, advancing the internal cursor.
40 ///
41 /// # Errors
42 ///
43 /// Returns any error encountered during the parsing of the inner type `T`.
44 pub fn parse<T: TpmParse>(&mut self) -> TpmResult<T> {
45 let (value, rest) = T::parse(self.buf)?;
46 self.buf = rest;
47 Ok(value)
48 }
49
50 /// Checks if the entire parameter buffer has been consumed.
51 #[must_use]
52 pub fn is_empty(&self) -> bool {
53 self.buf.is_empty()
54 }
55}