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}