tss_esapi/structures/buffers/
sensitive.rs

1// Copyright 2022 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3use crate::{
4    structures::Sensitive,
5    traits::{Marshall, UnMarshall},
6    tss2_esys::{TPM2B_SENSITIVE, TPMT_SENSITIVE},
7    Error, Result, WrapperErrorKind,
8};
9use log::error;
10use std::{
11    convert::{TryFrom, TryInto},
12    mem::size_of,
13    ops::Deref,
14};
15use zeroize::Zeroize;
16
17/// Sensitive data buffer.
18///
19/// # Details
20/// Corresponds to `TPM2B_SENSITIVE`. The contents of
21/// the buffer can be unmarshalled into a [Sensitive]
22/// structure.
23#[derive(Debug, Clone, PartialEq, Eq, Zeroize)]
24#[zeroize(drop)]
25pub struct SensitiveBuffer(Vec<u8>);
26
27impl SensitiveBuffer {
28    pub const MAX_SIZE: usize = size_of::<TPMT_SENSITIVE>();
29
30    pub fn value(&self) -> &[u8] {
31        &self.0
32    }
33}
34
35impl Deref for SensitiveBuffer {
36    type Target = Vec<u8>;
37
38    fn deref(&self) -> &Self::Target {
39        &self.0
40    }
41}
42
43impl TryFrom<Vec<u8>> for SensitiveBuffer {
44    type Error = Error;
45
46    fn try_from(bytes: Vec<u8>) -> Result<Self> {
47        if bytes.len() > Self::MAX_SIZE {
48            error!(
49                "Error: Invalid Vec<u8> size ({} > {})",
50                bytes.len(),
51                Self::MAX_SIZE
52            );
53            return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
54        }
55        Ok(SensitiveBuffer(bytes))
56    }
57}
58
59impl TryFrom<&[u8]> for SensitiveBuffer {
60    type Error = Error;
61
62    fn try_from(bytes: &[u8]) -> Result<Self> {
63        if bytes.len() > Self::MAX_SIZE {
64            error!(
65                "Error: Invalid &[u8] size ({} > {})",
66                bytes.len(),
67                Self::MAX_SIZE
68            );
69            return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
70        }
71        Ok(SensitiveBuffer(bytes.to_vec()))
72    }
73}
74
75impl TryFrom<TPM2B_SENSITIVE> for SensitiveBuffer {
76    type Error = Error;
77
78    fn try_from(tss: TPM2B_SENSITIVE) -> Result<Self> {
79        let size = tss.size as usize;
80        if size > Self::MAX_SIZE {
81            error!("Error: Invalid buffer size ({} > {})", size, Self::MAX_SIZE);
82            return Err(Error::local_error(WrapperErrorKind::WrongParamSize));
83        }
84        let sensitive = Sensitive::try_from(tss.sensitiveArea)?;
85        Ok(SensitiveBuffer(sensitive.marshall()?))
86    }
87}
88
89impl TryFrom<SensitiveBuffer> for TPM2B_SENSITIVE {
90    type Error = Error;
91
92    fn try_from(native: SensitiveBuffer) -> Result<Self> {
93        let mut buffer = TPM2B_SENSITIVE {
94            size: native.0.len() as u16,
95            ..Default::default()
96        };
97        let sensitive = Sensitive::unmarshall(&native.0)?;
98        buffer.sensitiveArea = sensitive.into();
99        Ok(buffer)
100    }
101}
102
103impl TryFrom<SensitiveBuffer> for Sensitive {
104    type Error = Error;
105
106    fn try_from(buf: SensitiveBuffer) -> Result<Self> {
107        Sensitive::unmarshall(&buf.0)
108    }
109}
110
111impl TryFrom<Sensitive> for SensitiveBuffer {
112    type Error = Error;
113
114    fn try_from(sensitive: Sensitive) -> Result<SensitiveBuffer> {
115        Ok(SensitiveBuffer(sensitive.marshall()?))
116    }
117}
118
119impl Marshall for SensitiveBuffer {
120    const BUFFER_SIZE: usize = size_of::<TPM2B_SENSITIVE>();
121
122    /// Produce a marshalled [`TPM2B_SENSITIVE`]
123    fn marshall(&self) -> Result<Vec<u8>> {
124        let mut buffer = vec![0; Self::BUFFER_SIZE];
125        let mut offset = 0;
126
127        let ret = Error::from_tss_rc(unsafe {
128            crate::tss2_esys::Tss2_MU_TPM2B_SENSITIVE_Marshal(
129                &self.clone().try_into()?,
130                buffer.as_mut_ptr(),
131                Self::BUFFER_SIZE.try_into().map_err(|e| {
132                    error!("Failed to convert size of buffer to TSS size_t type: {}", e);
133                    Error::local_error(WrapperErrorKind::InvalidParam)
134                })?,
135                &mut offset,
136            )
137        });
138
139        if !ret.is_success() {
140            return Err(ret);
141        }
142
143        let checked_offset = usize::try_from(offset).map_err(|e| {
144            error!("Failed to parse offset as usize: {}", e);
145            Error::local_error(WrapperErrorKind::InvalidParam)
146        })?;
147
148        buffer.truncate(checked_offset);
149
150        Ok(buffer)
151    }
152}
153
154impl UnMarshall for SensitiveBuffer {
155    /// Unmarshall the structure from [`TPM2B_SENSITIVE`]
156    fn unmarshall(marshalled_data: &[u8]) -> Result<Self> {
157        let mut dest = TPM2B_SENSITIVE::default();
158        let mut offset = 0;
159
160        let ret = Error::from_tss_rc(unsafe {
161            crate::tss2_esys::Tss2_MU_TPM2B_SENSITIVE_Unmarshal(
162                marshalled_data.as_ptr(),
163                marshalled_data.len().try_into().map_err(|e| {
164                    error!("Failed to convert length of marshalled data: {}", e);
165                    Error::local_error(WrapperErrorKind::InvalidParam)
166                })?,
167                &mut offset,
168                &mut dest,
169            )
170        });
171
172        if !ret.is_success() {
173            return Err(ret);
174        }
175
176        SensitiveBuffer::try_from(dest)
177    }
178}