tpm2_protocol/
buffer.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::{build_tpm2b, parse_tpm2b, TpmBuild, TpmErrorKind, TpmParse, TpmResult, TpmSized};
6use core::{convert::TryFrom, fmt::Debug, mem::size_of, ops::Deref};
7
8#[derive(Clone, Copy, PartialEq, Eq)]
9pub struct TpmBuffer<const CAPACITY: usize> {
10    bytes: [u8; CAPACITY],
11    len: usize,
12}
13
14impl<const CAPACITY: usize> TpmBuffer<CAPACITY> {
15    #[must_use]
16    pub const fn new() -> Self {
17        Self {
18            bytes: [0; CAPACITY],
19            len: 0,
20        }
21    }
22}
23
24impl<const CAPACITY: usize> Deref for TpmBuffer<CAPACITY> {
25    type Target = [u8];
26
27    fn deref(&self) -> &Self::Target {
28        &self.bytes[..self.len]
29    }
30}
31
32impl<const CAPACITY: usize> Default for TpmBuffer<CAPACITY> {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl<const CAPACITY: usize> TpmSized for TpmBuffer<CAPACITY> {
39    const SIZE: usize = size_of::<u16>() + CAPACITY;
40    fn len(&self) -> usize {
41        size_of::<u16>() + self.len
42    }
43}
44
45impl<const CAPACITY: usize> TpmBuild for TpmBuffer<CAPACITY> {
46    fn build(&self, writer: &mut crate::TpmWriter) -> TpmResult<()> {
47        build_tpm2b(writer, self)
48    }
49}
50
51impl<const CAPACITY: usize> TpmParse for TpmBuffer<CAPACITY> {
52    fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
53        let (bytes, remainder) = parse_tpm2b(buf)?;
54        let buffer = Self::try_from(bytes)?;
55        Ok((buffer, remainder))
56    }
57}
58
59impl<const CAPACITY: usize> TryFrom<&[u8]> for TpmBuffer<CAPACITY> {
60    type Error = TpmErrorKind;
61
62    fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
63        if slice.len() > CAPACITY {
64            return Err(TpmErrorKind::CapacityExceeded);
65        }
66        let mut buffer = Self::new();
67        buffer.bytes[..slice.len()].copy_from_slice(slice);
68        buffer.len = slice.len();
69        Ok(buffer)
70    }
71}
72
73impl<const CAPACITY: usize> AsRef<[u8]> for TpmBuffer<CAPACITY> {
74    fn as_ref(&self) -> &[u8] {
75        &self.bytes[..self.len]
76    }
77}
78
79impl<const CAPACITY: usize> Debug for TpmBuffer<CAPACITY> {
80    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81        write!(f, "TpmBuffer(")?;
82        for byte in self.iter() {
83            write!(f, "{byte:02X}")?;
84        }
85        write!(f, ")")
86    }
87}