1use super::{
6 tpmu::{
7 TpmuHa, TpmuPublicId, TpmuPublicParms, TpmuSensitiveComposite, TpmuSignature,
8 TpmuSymKeyBits, TpmuSymMode,
9 },
10 Tpm2bAuth, Tpm2bDigest, TpmAlgId, TpmRh, TpmSt, TpmaObject,
11};
12use crate::{
13 tpm_struct, tpm_tagged_struct, TpmBuild, TpmErrorKind, TpmParse, TpmParseTagged, TpmResult,
14 TpmSized, TpmTagged, TpmWriter, TPM_MAX_COMMAND_SIZE,
15};
16
17#[derive(Debug, PartialEq, Eq, Clone)]
18pub struct TpmtPublic {
19 pub object_type: TpmAlgId,
20 pub name_alg: TpmAlgId,
21 pub object_attributes: TpmaObject,
22 pub auth_policy: Tpm2bDigest,
23 pub parameters: TpmuPublicParms,
24 pub unique: TpmuPublicId,
25}
26
27impl TpmTagged for TpmtPublic {
28 type Tag = TpmAlgId;
29 type Value = TpmuPublicParms;
30}
31
32impl TpmSized for TpmtPublic {
33 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
34 fn len(&self) -> usize {
35 self.object_type.len()
36 + self.name_alg.len()
37 + self.object_attributes.len()
38 + self.auth_policy.len()
39 + self.parameters.len()
40 + self.unique.len()
41 }
42}
43
44impl TpmBuild for TpmtPublic {
45 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
46 self.object_type.build(writer)?;
47 self.name_alg.build(writer)?;
48 self.object_attributes.build(writer)?;
49 self.auth_policy.build(writer)?;
50 self.parameters.build(writer)?;
51 self.unique.build(writer)
52 }
53}
54
55impl TpmParse for TpmtPublic {
56 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
57 let (object_type, buf) = TpmAlgId::parse(buf)?;
58 let (name_alg, buf) = TpmAlgId::parse(buf)?;
59 let (object_attributes, buf) = TpmaObject::parse(buf)?;
60 let (auth_policy, buf) = Tpm2bDigest::parse(buf)?;
61 let (parameters, buf) = TpmuPublicParms::parse_tagged(object_type, buf)?;
62 let (unique, buf) = TpmuPublicId::parse_tagged(object_type, buf)?;
63
64 let public_area = Self {
65 object_type,
66 name_alg,
67 object_attributes,
68 auth_policy,
69 parameters,
70 unique,
71 };
72
73 Ok((public_area, buf))
74 }
75}
76
77impl Default for TpmtPublic {
78 fn default() -> Self {
79 Self {
80 object_type: TpmAlgId::Null,
81 name_alg: TpmAlgId::Null,
82 object_attributes: TpmaObject::empty(),
83 auth_policy: Tpm2bDigest::default(),
84 parameters: TpmuPublicParms::Null,
85 unique: TpmuPublicId::Null,
86 }
87 }
88}
89
90tpm_struct! {
91 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
92 pub struct TpmtScheme {
93 pub scheme: TpmAlgId,
94 }
95}
96
97tpm_struct! {
98 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
99 pub struct TpmtKdfScheme {
100 pub scheme: TpmAlgId,
101 }
102}
103
104tpm_struct! {
105 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
106 pub struct TpmtRsaDecrypt {
107 pub scheme: TpmtScheme,
108 }
109}
110
111#[derive(Debug, PartialEq, Eq, Clone, Default)]
112pub struct TpmtSensitive {
113 pub sensitive_type: TpmAlgId,
114 pub auth_value: Tpm2bAuth,
115 pub seed_value: Tpm2bDigest,
116 pub sensitive: TpmuSensitiveComposite,
117}
118
119impl TpmtSensitive {
120 pub fn from_private_bytes(
126 key_alg: TpmAlgId,
127 private_bytes: &[u8],
128 ) -> Result<Self, TpmErrorKind> {
129 let sensitive = match key_alg {
130 TpmAlgId::Rsa => TpmuSensitiveComposite::Rsa(
131 crate::data::Tpm2bPrivateKeyRsa::try_from(private_bytes)?,
132 ),
133 TpmAlgId::Ecc => TpmuSensitiveComposite::Ecc(crate::data::Tpm2bEccParameter::try_from(
134 private_bytes,
135 )?),
136 TpmAlgId::KeyedHash => TpmuSensitiveComposite::Bits(
137 crate::data::Tpm2bSensitiveData::try_from(private_bytes)?,
138 ),
139 TpmAlgId::SymCipher => {
140 TpmuSensitiveComposite::Sym(crate::data::Tpm2bSymKey::try_from(private_bytes)?)
141 }
142 _ => return Err(TpmErrorKind::InvalidValue),
143 };
144
145 Ok(Self {
146 sensitive_type: key_alg,
147 auth_value: Tpm2bAuth::default(),
148 seed_value: Tpm2bDigest::default(),
149 sensitive,
150 })
151 }
152}
153
154impl TpmTagged for TpmtSensitive {
155 type Tag = TpmAlgId;
156 type Value = TpmuSensitiveComposite;
157}
158
159impl TpmSized for TpmtSensitive {
160 const SIZE: usize =
161 TpmAlgId::SIZE + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
162 fn len(&self) -> usize {
163 self.sensitive_type.len()
164 + self.auth_value.len()
165 + self.seed_value.len()
166 + self.sensitive.len()
167 }
168}
169
170impl TpmBuild for TpmtSensitive {
171 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
172 self.sensitive_type.build(writer)?;
173 self.auth_value.build(writer)?;
174 self.seed_value.build(writer)?;
175 self.sensitive.build(writer)
176 }
177}
178
179impl TpmParse for TpmtSensitive {
180 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
181 let (sensitive_type, buf) = TpmAlgId::parse(buf)?;
182 let (auth_value, buf) = Tpm2bAuth::parse(buf)?;
183 let (seed_value, buf) = Tpm2bDigest::parse(buf)?;
184 let (sensitive, buf) = TpmuSensitiveComposite::parse_tagged(sensitive_type, buf)?;
185
186 Ok((
187 Self {
188 sensitive_type,
189 auth_value,
190 seed_value,
191 sensitive,
192 },
193 buf,
194 ))
195 }
196}
197
198#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
199pub struct TpmtSymDef {
200 pub algorithm: TpmAlgId,
201 pub key_bits: TpmuSymKeyBits,
202 pub mode: TpmuSymMode,
203}
204
205impl TpmTagged for TpmtSymDef {
206 type Tag = TpmAlgId;
207 type Value = TpmuSymKeyBits;
208}
209
210impl TpmSized for TpmtSymDef {
211 const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
212 fn len(&self) -> usize {
213 if self.algorithm == TpmAlgId::Null {
214 self.algorithm.len()
215 } else {
216 self.algorithm.len() + self.key_bits.len() + self.mode.len()
217 }
218 }
219}
220
221impl TpmBuild for TpmtSymDef {
222 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
223 self.algorithm.build(writer)?;
224 if self.algorithm != TpmAlgId::Null {
225 self.key_bits.build(writer)?;
226 self.mode.build(writer)?;
227 }
228 Ok(())
229 }
230}
231
232impl TpmParse for TpmtSymDef {
233 fn parse(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
234 let (algorithm, buf) = TpmAlgId::parse(buf)?;
235 if algorithm == TpmAlgId::Null {
236 return Ok((
237 Self {
238 algorithm,
239 key_bits: TpmuSymKeyBits::Null,
240 mode: TpmuSymMode::Null,
241 },
242 buf,
243 ));
244 }
245
246 let (key_bits, buf) = TpmuSymKeyBits::parse_tagged(algorithm, buf)?;
247 let (mode, buf) = TpmuSymMode::parse_tagged(algorithm, buf)?;
248 Ok((
249 Self {
250 algorithm,
251 key_bits,
252 mode,
253 },
254 buf,
255 ))
256 }
257}
258
259pub type TpmtSymDefObject = TpmtSymDef;
260
261tpm_struct! {
262 #[derive(Debug, PartialEq, Eq, Clone, Default)]
263 pub struct TpmtTkCreation {
264 pub tag: TpmSt,
265 pub hierarchy: TpmRh,
266 pub digest: Tpm2bDigest,
267 }
268}
269
270tpm_struct! {
271 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
272 pub struct TpmtTkVerified {
273 pub tag: TpmSt,
274 pub hierarchy: TpmRh,
275 pub digest: Tpm2bDigest,
276 }
277}
278
279tpm_struct! {
280 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
281 pub struct TpmtTkAuth {
282 pub tag: TpmSt,
283 pub hierarchy: TpmRh,
284 pub digest: Tpm2bDigest,
285 }
286}
287
288tpm_struct! {
289 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
290 pub struct TpmtTkHashcheck {
291 pub tag: TpmSt,
292 pub hierarchy: TpmRh,
293 pub digest: Tpm2bDigest,
294 }
295}
296
297tpm_tagged_struct! {
298 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
299 pub struct TpmtHa {
300 pub hash_alg: TpmAlgId,
301 pub digest: TpmuHa,
302 }
303}
304
305impl Default for TpmtHa {
306 fn default() -> Self {
307 Self {
308 hash_alg: TpmAlgId::Null,
309 digest: TpmuHa::default(),
310 }
311 }
312}
313
314tpm_tagged_struct! {
315 #[derive(Debug, PartialEq, Eq, Clone)]
316 pub struct TpmtSignature {
317 pub sig_alg: TpmAlgId,
318 pub signature: TpmuSignature,
319 }
320}