1use crate::{
6 tpm2b, tpm2b_struct, tpm_bitflags, tpm_bool, tpm_enum, tpm_hash_size, tpm_struct, tpml,
7 TpmBuffer, TpmBuild, TpmErrorKind, TpmParse, TpmParseTagged, TpmResult, TpmSized, TpmTagged,
8 TpmWriter, TPM_MAX_COMMAND_SIZE,
9};
10use core::{
11 convert::TryFrom,
12 fmt::{self, Debug, Display, Formatter},
13 mem::size_of,
14 ops::Deref,
15};
16
17pub const MAX_DIGEST_SIZE: usize = 64;
18pub const MAX_ECC_KEY_BYTES: usize = 66;
19pub const MAX_SYM_KEY_BYTES: usize = 32;
20pub const MAX_LABEL_SIZE: usize = 32;
21pub const MAX_RSA_KEY_BYTES: usize = 512;
22pub const MAX_SENSITIVE_DATA: usize = 256;
23pub const MAX_NV_BUFFER_SIZE: usize = 2048;
24pub const MAX_TIMEOUT: usize = 8;
25pub const MAX_CONTEXT_DATA: usize = 1664;
26pub const MAX_DATA_SIZE: usize = 256;
27pub const MAX_EVENT_SIZE: usize = 1024;
28pub const MAX_BUFFER_SIZE: usize = 1024;
29pub const MAX_OPERAND_SIZE: usize = 1024;
30pub const MAX_PRIVATE_SIZE: usize = 1408;
31pub const MAX_PRIVATE_VENDOR_SPECIFIC_SIZE: usize = 1024;
32
33tpm2b!(Tpm2b, TPM_MAX_COMMAND_SIZE);
34tpm2b!(Tpm2bAuth, MAX_DIGEST_SIZE);
35tpm2b!(Tpm2bContextSensitive, MAX_CONTEXT_DATA);
36tpm2b!(Tpm2bData, MAX_DATA_SIZE);
37tpm2b!(Tpm2bDerive, MAX_DIGEST_SIZE);
38tpm2b!(Tpm2bDigest, MAX_DIGEST_SIZE);
39tpm2b!(Tpm2bEccParameter, MAX_ECC_KEY_BYTES);
40tpm2b!(Tpm2bEncryptedSecret, MAX_ECC_KEY_BYTES);
41tpm2b!(Tpm2bEvent, MAX_EVENT_SIZE);
42tpm2b!(Tpm2bIv, MAX_SYM_KEY_BYTES);
43tpm2b!(Tpm2bLabel, MAX_LABEL_SIZE);
44tpm2b!(Tpm2bMaxBuffer, MAX_BUFFER_SIZE);
45tpm2b!(Tpm2bMaxNvBuffer, MAX_NV_BUFFER_SIZE);
46tpm2b!(Tpm2bName, { MAX_DIGEST_SIZE + 2 });
47tpm2b!(Tpm2bNonce, MAX_DIGEST_SIZE);
48tpm2b!(Tpm2bOperand, MAX_OPERAND_SIZE);
49tpm2b!(Tpm2bPrivate, MAX_PRIVATE_SIZE);
50tpm2b!(Tpm2bPrivateKeyRsa, MAX_RSA_KEY_BYTES);
51tpm2b!(Tpm2bPrivateVendorSpecific, MAX_PRIVATE_VENDOR_SPECIFIC_SIZE);
52tpm2b!(Tpm2bPublicKeyRsa, MAX_RSA_KEY_BYTES);
53tpm2b!(Tpm2bSensitiveData, MAX_SENSITIVE_DATA);
54tpm2b!(Tpm2bSymKey, MAX_SYM_KEY_BYTES);
55tpm2b!(Tpm2bTimeout, MAX_TIMEOUT);
56
57tpm_enum! {
58 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash, Default)]
62 pub enum TpmAlgId(u16) {
63 (Error, 0x0000, "TPM_ALG_ERROR"),
64 (Rsa, 0x0001, "TPM_ALG_RSA"),
65 (Sha1, 0x0004, "TPM_ALG_SHA1"),
66 (Hmac, 0x0005, "TPM_ALG_HMAC"),
67 (Aes, 0x0006, "TPM_ALG_AES"),
68 (Mgf1, 0x0007, "TPM_ALG_MGF1"),
69 (KeyedHash, 0x0008, "TPM_ALG_KEYEDHASH"),
70 (Xor, 0x000A, "TPM_ALG_XOR"),
71 (Sha256, 0x000B, "TPM_ALG_SHA256"),
72 (Sha384, 0x000C, "TPM_ALG_SHA384"),
73 (Sha512, 0x000D, "TPM_ALG_SHA512"),
74 #[default]
76 (Null, 0x0010, "TPM_ALG_NULL"),
77 (Sm3_256, 0x0012, "TPM_ALG_SM3_256"),
78 (Sm4, 0x0013, "TPM_ALG_SM4"),
79 (Rsassa, 0x0014, "TPM_ALG_RSASSA"),
80 (Rsaes, 0x0015, "TPM_ALG_RSAES"),
81 (Rsapss, 0x0016, "TPM_ALG_RSAPSS"),
82 (Oaep, 0x0017, "TPM_ALG_OAEP"),
83 (Ecdsa, 0x0018, "TPM_ALG_ECDSA"),
84 (Ecdh, 0x0019, "TPM_ALG_ECDH"),
85 (Ecdaa, 0x001A, "TPM_ALG_ECDAA"),
86 (Sm2, 0x001B, "TPM_ALG_SM2"),
87 (Ecschnorr, 0x001C, "TPM_ALG_ECSCHNORR"),
88 (Ecmqv, 0x001D, "TPM_ALG_ECMQV"),
89 (Kdf1Sp800_56A, 0x0020, "TPM_ALG_KDF1_SP800_56A"),
90 (Kdf2, 0x0021, "TPM_ALG_KDF2"),
91 (Kdf1Sp800_108, 0x0022, "TPM_ALG_KDF1_SP800_108"),
92 (Ecc, 0x0023, "TPM_ALG_ECC"),
93 (SymCipher, 0x0025, "TPM_ALG_SYMCIPHER"),
94 (Camellia, 0x0026, "TPM_ALG_CAMELLIA"),
95 (Ctr, 0x0040, "TPM_ALG_CTR"),
96 (Ofb, 0x0041, "TPM_ALG_OFB"),
97 (Cbc, 0x0042, "TPM_ALG_CBC"),
98 (Cfb, 0x0043, "TPM_ALG_CFB"),
99 (Ecb, 0x0044, "TPM_ALG_ECB"),
100 }
101}
102
103tpm_enum! {
104 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
106 pub enum TpmCap(u32) {
107 (Algs, 0x0000_0000, "TPM_CAP_ALGS"),
108 (Handles, 0x0000_0001, "TPM_CAP_HANDLES"),
109 (Commands, 0x0000_0002, "TPM_CAP_COMMANDS"),
110 (PpCommands, 0x0000_0003, "TPM_CAP_PP_COMMANDS"),
111 (AuditCommands, 0x0000_0004, "TPM_CAP_AUDIT_COMMANDS"),
112 (Pcrs, 0x0000_0005, "TPM_CAP_PCRS"),
113 (TpmProperties, 0x0000_0006, "TPM_CAP_TPM_PROPERTIES"),
114 (PcrProperties, 0x0000_0007, "TPM_CAP_PCR_PROPERTIES"),
115 (EccCurves, 0x0000_0008, "TPM_CAP_ECC_CURVES"),
116 (AuthPolicies, 0x0000_0009, "TPM_CAP_AUTH_POLICIES"),
117 }
118}
119
120tpm_enum! {
121 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
125 pub enum TpmCc(u32) {
126 (NvUndefineSpaceSpecial, 0x0000_011F, "TPM_CC_NV_UndefineSpaceSpecial"),
127 (EvictControl, 0x0000_0120, "TPM_CC_EvictControl"),
128 (HierarchyControl, 0x0000_0121, "TPM_CC_HierarchyControl"),
129 (NvUndefineSpace, 0x0000_0122, "TPM_CC_NV_UndefineSpace"),
130 (ChangeEps, 0x0000_0124, "TPM_CC_ChangeEPS"),
131 (ChangePps, 0x0000_0125, "TPM_CC_ChangePPS"),
132 (Clear, 0x0000_0126, "TPM_CC_Clear"),
133 (ClearControl, 0x0000_0127, "TPM_CC_ClearControl"),
134 (ClockSet, 0x0000_0128, "TPM_CC_ClockSet"),
135 (HierarchyChangeAuth, 0x0000_0129, "TPM_CC_HierarchyChangeAuth"),
136 (NvDefineSpace, 0x0000_012A, "TPM_CC_NV_DefineSpace"),
137 (PcrAllocate, 0x0000_012B, "TPM_CC_PCR_Allocate"),
138 (PcrSetAuthPolicy, 0x0000_012C, "TPM_CC_PCR_SetAuthPolicy"),
139 (PpCommands, 0x0000_012D, "TPM_CC_PP_Commands"),
140 (SetPrimaryPolicy, 0x0000_012E, "TPM_CC_SetPrimaryPolicy"),
141 (FieldUpgradeStart, 0x0000_012F, "TPM_CC_FieldUpgradeStart"),
142 (ClockRateAdjust, 0x0000_0130, "TPM_CC_ClockRateAdjust"),
143 (CreatePrimary, 0x0000_0131, "TPM_CC_CreatePrimary"),
144 (NvGlobalWriteLock, 0x0000_0132, "TPM_CC_NV_GlobalWriteLock"),
145 (GetCommandAuditDigest, 0x0000_0133, "TPM_CC_GetCommandAuditDigest"),
146 (NvIncrement, 0x0000_0134, "TPM_CC_NV_Increment"),
147 (NvSetBits, 0x0000_0135, "TPM_CC_NV_SetBits"),
148 (NvExtend, 0x0000_0136, "TPM_CC_NV_Extend"),
149 (NvWrite, 0x0000_0137, "TPM_CC_NV_Write"),
150 (NvWriteLock, 0x0000_0138, "TPM_CC_NV_WriteLock"),
151 (DictionaryAttackLockReset, 0x0000_0139, "TPM_CC_DictionaryAttackLockReset"),
152 (DictionaryAttackParameters, 0x0000_013A, "TPM_CC_DictionaryAttackParameters"),
153 (NvChangeAuth, 0x0000_013B, "TPM_CC_NV_ChangeAuth"),
154 (PcrEvent, 0x0000_013C, "TPM_CC_PCR_Event"),
155 (PcrReset, 0x0000_013D, "TPM_CC_PCR_Reset"),
156 (SequenceComplete, 0x0000_013E, "TPM_CC_SequenceComplete"),
157 (SetAlgorithmSet, 0x0000_013F, "TPM_CC_SetAlgorithmSet"),
158 (SetCommandCodeAuditStatus, 0x0000_0140, "TPM_CC_SetCommandCodeAuditStatus"),
159 (FieldUpgradeData, 0x0000_0141, "TPM_CC_FieldUpgradeData"),
160 (IncrementalSelfTest, 0x0000_0142, "TPM_CC_IncrementalSelfTest"),
161 (SelfTest, 0x0000_0143, "TPM_CC_SelfTest"),
162 (Startup, 0x0000_0144, "TPM_CC_Startup"),
163 (Shutdown, 0x0000_0145, "TPM_CC_Shutdown"),
164 (StirRandom, 0x0000_0146, "TPM_CC_StirRandom"),
165 (ActivateCredential, 0x0000_0147, "TPM_CC_ActivateCredential"),
166 (Certify, 0x0000_0148, "TPM_CC_Certify"),
167 (PolicyNv, 0x0000_0149, "TPM_CC_PolicyNV"),
168 (CertifyCreation, 0x0000_014A, "TPM_CC_CertifyCreation"),
169 (Duplicate, 0x0000_014B, "TPM_CC_Duplicate"),
170 (GetTime, 0x0000_014C, "TPM_CC_GetTime"),
171 (GetSessionAuditDigest, 0x0000_014D, "TPM_CC_GetSessionAuditDigest"),
172 (NvRead, 0x0000_014E, "TPM_CC_NV_Read"),
173 (NvReadLock, 0x0000_014F, "TPM_CC_NV_ReadLock"),
174 (ObjectChangeAuth, 0x0000_0150, "TPM_CC_ObjectChangeAuth"),
175 (PolicySecret, 0x0000_0151, "TPM_CC_PolicySecret"),
176 (Rewrap, 0x0000_0152, "TPM_CC_Rewrap"),
177 (Create, 0x0000_0153, "TPM_CC_Create"),
178 (EcdhZGen, 0x0000_0154, "TPM_CC_ECDH_ZGen"),
179 (Hmac, 0x0000_0155, "TPM_CC_HMAC"),
180 (Import, 0x0000_0156, "TPM_CC_Import"),
181 (Load, 0x0000_0157, "TPM_CC_Load"),
182 (Quote, 0x0000_0158, "TPM_CC_Quote"),
183 (RsaDecrypt, 0x0000_0159, "TPM_CC_RSA_Decrypt"),
184 (HmacStart, 0x0000_015B, "TPM_CC_HMAC_Start"),
185 (SequenceUpdate, 0x0000_015C, "TPM_CC_SequenceUpdate"),
186 (Sign, 0x0000_015D, "TPM_CC_Sign"),
187 (Unseal, 0x0000_015E, "TPM_CC_Unseal"),
188 (PolicySigned, 0x0000_0160, "TPM_CC_PolicySigned"),
189 (ContextLoad, 0x0000_0161, "TPM_CC_ContextLoad"),
190 (ContextSave, 0x0000_0162, "TPM_CC_ContextSave"),
191 (EcdhKeygen, 0x0000_0163, "TPM_CC_ECDH_KeyGen"),
192 (EncryptDecrypt, 0x0000_0164, "TPM_CC_EncryptDecrypt"),
193 (FlushContext, 0x0000_0165, "TPM_CC_FlushContext"),
194 (LoadExternal, 0x0000_0167, "TPM_CC_LoadExternal"),
195 (MakeCredential, 0x0000_0168, "TPM_CC_MakeCredential"),
196 (NvReadPublic, 0x0000_0169, "TPM_CC_NV_ReadPublic"),
197 (PolicyAuthorize, 0x0000_016A, "TPM_CC_PolicyAuthorize"),
198 (PolicyAuthValue, 0x0000_016B, "TPM_CC_PolicyAuthValue"),
199 (PolicyCommandCode, 0x0000_016C, "TPM_CC_PolicyCommandCode"),
200 (PolicyCounterTimer, 0x0000_016D, "TPM_CC_PolicyCounterTimer"),
201 (PolicyCpHash, 0x0000_016E, "TPM_CC_PolicyCpHash"),
202 (PolicyLocality, 0x0000_016F, "TPM_CC_PolicyLocality"),
203 (PolicyNameHash, 0x0000_0170, "TPM_CC_PolicyNameHash"),
204 (PolicyOR, 0x0000_0171, "TPM_CC_PolicyOR"),
205 (PolicyTicket, 0x0000_0172, "TPM_CC_PolicyTicket"),
206 (ReadPublic, 0x0000_0173, "TPM_CC_ReadPublic"),
207 (RsaEncrypt, 0x0000_0174, "TPM_CC_RSA_Encrypt"),
208 (StartAuthSession, 0x0000_0176, "TPM_CC_StartAuthSession"),
209 (VerifySignature, 0x0000_0177, "TPM_CC_VerifySignature"),
210 (EccParameters, 0x0000_0178, "TPM_CC_ECC_Parameters"),
211 (FirmwareRead, 0x0000_0179, "TPM_CC_FirmwareRead"),
212 (GetCapability, 0x0000_017A, "TPM_CC_GetCapability"),
213 (GetRandom, 0x0000_017B, "TPM_CC_GetRandom"),
214 (GetTestResult, 0x0000_017C, "TPM_CC_GetTestResult"),
215 (Hash, 0x0000_017D, "TPM_CC_Hash"),
216 (PcrRead, 0x0000_017E, "TPM_CC_PCR_Read"),
217 (PolicyPcr, 0x0000_017F, "TPM_CC_PolicyPCR"),
218 (PolicyRestart, 0x0000_0180, "TPM_CC_PolicyRestart"),
219 (ReadClock, 0x0000_0181, "TPM_CC_ReadClock"),
220 (PcrExtend, 0x0000_0182, "TPM_CC_PCR_Extend"),
221 (PcrSetAuthValue, 0x0000_0183, "TPM_CC_PCR_SetAuthValue"),
222 (NvCertify, 0x0000_0184, "TPM_CC_NV_Certify"),
223 (EventSequenceComplete, 0x0000_0185, "TPM_CC_EventSequenceComplete"),
224 (HashSequenceStart, 0x0000_0186, "TPM_CC_HashSequenceStart"),
225 (PolicyPhysicalPresence, 0x0000_0187, "TPM_CC_PolicyPhysicalPresence"),
226 (PolicyDuplicationSelect, 0x0000_0188, "TPM_CC_PolicyDuplicationSelect"),
227 (PolicyGetDigest, 0x0000_0189, "TPM_CC_PolicyGetDigest"),
228 (TestParms, 0x0000_018A, "TPM_CC_TestParms"),
229 (Commit, 0x0000_018B, "TPM_CC_Commit"),
230 (PolicyPassword, 0x0000_018C, "TPM_CC_PolicyPassword"),
231 (ZGen2Phase, 0x0000_018D, "TPM_CC_ZGen_2Phase"),
232 (EcEphemeral, 0x0000_018E, "TPM_CC_EC_Ephemeral"),
233 (PolicyNvWritten, 0x0000_018F, "TPM_CC_PolicyNvWritten"),
234 (PolicyTemplate, 0x0000_0190, "TPM_CC_PolicyTemplate"),
235 (CreateLoaded, 0x0000_0191, "TPM_CC_CreateLoaded"),
236 (PolicyAuthorizeNv, 0x0000_0192, "TPM_CC_PolicyAuthorizeNV"),
237 (EncryptDecrypt2, 0x0000_0193, "TPM_CC_EncryptDecrypt2"),
238 (VendorTcgTest, 0x2000_0000, "TPM_CC_Vendor_TCG_Test"),
239 }
240}
241
242tpm_enum! {
243 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
244 pub enum TpmEccCurve(u16) {
245 (None, 0x0000, "TPM_ECC_NONE"),
246 (NistP192, 0x0001, "TPM_ECC_NIST_P192"),
247 (NistP224, 0x0002, "TPM_ECC_NIST_P224"),
248 (NistP256, 0x0003, "TPM_ECC_NIST_P256"),
249 (NistP384, 0x0004, "TPM_ECC_NIST_P384"),
250 (NistP521, 0x0005, "TPM_ECC_NIST_P521"),
251 }
252}
253
254pub const TPM_RC_VER1: u32 = 0x0100;
255pub const TPM_RC_FMT1: u32 = 0x0080;
256pub const TPM_RC_WARN: u32 = 0x0900;
257pub const TPM_RC_P_BIT: u32 = 1 << 6;
258pub const TPM_RC_N_SHIFT: u32 = 8;
259pub const TPM_RC_FMT1_ERROR_MASK: u32 = 0x003F;
260
261#[derive(Debug, PartialEq, Eq, Copy, Clone)]
262pub enum TpmRcIndex {
263 Parameter(u8),
264 Handle(u8),
265 Session(u8),
266}
267
268impl Display for TpmRcIndex {
269 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
270 match self {
271 TpmRcIndex::Parameter(i) => write!(f, "parameter[{i}]"),
272 TpmRcIndex::Handle(i) => write!(f, "handle[{i}]"),
273 TpmRcIndex::Session(i) => write!(f, "session[{i}]"),
274 }
275 }
276}
277
278tpm_enum! {
279 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
280 #[allow(clippy::upper_case_acronyms)]
281 pub enum TpmRcBase(u32) {
282 (Success, 0x0000, "TPM_RC_SUCCESS"),
283 (BadTag, 0x001E, "TPM_RC_BAD_TAG"),
284 (Initialize, TPM_RC_VER1, "TPM_RC_INITIALIZE"),
285 (Failure, TPM_RC_VER1 | 0x001, "TPM_RC_FAILURE"),
286 (Sequence, TPM_RC_VER1 | 0x003, "TPM_RC_SEQUENCE"),
287 (Private, TPM_RC_VER1 | 0x00B, "TPM_RC_PRIVATE"),
288 (Hmac, TPM_RC_VER1 | 0x019, "TPM_RC_HMAC"),
289 (Disabled, TPM_RC_VER1 | 0x020, "TPM_RC_DISABLED"),
290 (Exclusive, TPM_RC_VER1 | 0x021, "TPM_RC_EXCLUSIVE"),
291 (AuthType, TPM_RC_VER1 | 0x024, "TPM_RC_AUTH_TYPE"),
292 (AuthMissing, TPM_RC_VER1 | 0x025, "TPM_RC_AUTH_MISSING"),
293 (Policy, TPM_RC_VER1 | 0x026, "TPM_RC_POLICY"),
294 (Pcr, TPM_RC_VER1 | 0x027, "TPM_RC_PCR"),
295 (PcrChanged, TPM_RC_VER1 | 0x028, "TPM_RC_PCR_CHANGED"),
296 (Upgrade, TPM_RC_VER1 | 0x02D, "TPM_RC_UPGRADE"),
297 (TooManyContexts, TPM_RC_VER1 | 0x02E, "TPM_RC_TOO_MANY_CONTEXTS"),
298 (AuthUnavailable, TPM_RC_VER1 | 0x02F, "TPM_RC_AUTH_UNAVAILABLE"),
299 (Reboot, TPM_RC_VER1 | 0x030, "TPM_RC_REBOOT"),
300 (Unbalanced, TPM_RC_VER1 | 0x031, "TPM_RC_UNBALANCED"),
301 (CommandSize, TPM_RC_VER1 | 0x042, "TPM_RC_COMMAND_SIZE"),
302 (CommandCode, TPM_RC_VER1 | 0x043, "TPM_RC_COMMAND_CODE"),
303 (AuthSize, TPM_RC_VER1 | 0x044, "TPM_RC_AUTHSIZE"),
304 (AuthContext, TPM_RC_VER1 | 0x045, "TPM_RC_AUTH_CONTEXT"),
305 (NvRange, TPM_RC_VER1 | 0x046, "TPM_RC_NV_RANGE"),
306 (NvSize, TPM_RC_VER1 | 0x047, "TPM_RC_NV_SIZE"),
307 (NvLocked, TPM_RC_VER1 | 0x048, "TPM_RC_NV_LOCKED"),
308 (NvAuthorization, TPM_RC_VER1 | 0x049, "TPM_RC_NV_AUTHORIZATION"),
309 (NvUninitialized, TPM_RC_VER1 | 0x04A, "TPM_RC_NV_UNINITIALIZED"),
310 (NvSpace, TPM_RC_VER1 | 0x04B, "TPM_RC_NV_SPACE"),
311 (NvDefined, TPM_RC_VER1 | 0x04C, "TPM_RC_NV_DEFINED"),
312 (BadContext, TPM_RC_VER1 | 0x050, "TPM_RC_BAD_CONTEXT"),
313 (CpHash, TPM_RC_VER1 | 0x051, "TPM_RC_CPHASH"),
314 (Parent, TPM_RC_VER1 | 0x052, "TPM_RC_PARENT"),
315 (NeedsTest, TPM_RC_VER1 | 0x053, "TPM_RC_NEEDS_TEST"),
316 (NoResult, TPM_RC_VER1 | 0x054, "TPM_RC_NO_RESULT"),
317 (Sensitive, TPM_RC_VER1 | 0x055, "TPM_RC_SENSITIVE"),
318 (ReadOnly, TPM_RC_VER1 | 0x056, "TPM_RC_READ_ONLY"),
319 (Asymmetric, TPM_RC_FMT1 | 0x001, "TPM_RC_ASYMMETRIC"),
320 (Attributes, TPM_RC_FMT1 | 0x002, "TPM_RC_ATTRIBUTES"),
321 (Hash, TPM_RC_FMT1 | 0x003, "TPM_RC_HASH"),
322 (Value, TPM_RC_FMT1 | 0x004, "TPM_RC_VALUE"),
323 (Hierarchy, TPM_RC_FMT1 | 0x005, "TPM_RC_HIERARCHY"),
324 (KeySize, TPM_RC_FMT1 | 0x007, "TPM_RC_KEY_SIZE"),
325 (Mgf, TPM_RC_FMT1 | 0x008, "TPM_RC_MGF"),
326 (Mode, TPM_RC_FMT1 | 0x009, "TPM_RC_MODE"),
327 (Type, TPM_RC_FMT1 | 0x00A, "TPM_RC_TYPE"),
328 (Handle, TPM_RC_FMT1 | 0x00B, "TPM_RC_HANDLE"),
329 (Kdf, TPM_RC_FMT1 | 0x00C, "TPM_RC_KDF"),
330 (Range, TPM_RC_FMT1 | 0x00D, "TPM_RC_RANGE"),
331 (AuthFail, TPM_RC_FMT1 | 0x00E, "TPM_RC_AUTH_FAIL"),
332 (Nonce, TPM_RC_FMT1 | 0x00F, "TPM_RC_NONCE"),
333 (Pp, TPM_RC_FMT1 | 0x010, "TPM_RC_PP"),
334 (Scheme, TPM_RC_FMT1 | 0x012, "TPM_RC_SCHEME"),
335 (Size, TPM_RC_FMT1 | 0x015, "TPM_RC_SIZE"),
336 (Symmetric, TPM_RC_FMT1 | 0x016, "TPM_RC_SYMMETRIC"),
337 (Tag, TPM_RC_FMT1 | 0x017, "TPM_RC_TAG"),
338 (Selector, TPM_RC_FMT1 | 0x018, "TPM_RC_SELECTOR"),
339 (Insufficient, TPM_RC_FMT1 | 0x01A, "TPM_RC_INSUFFICIENT"),
340 (Signature, TPM_RC_FMT1 | 0x01B, "TPM_RC_SIGNATURE"),
341 (Key, TPM_RC_FMT1 | 0x01C, "TPM_RC_KEY"),
342 (PolicyFail, TPM_RC_FMT1 | 0x01D, "TPM_RC_POLICY_FAIL"),
343 (Integrity, TPM_RC_FMT1 | 0x01F, "TPM_RC_INTEGRITY"),
344 (Ticket, TPM_RC_FMT1 | 0x020, "TPM_RC_TICKET"),
345 (ReservedBits, TPM_RC_FMT1 | 0x021, "TPM_RC_RESERVED_BITS"),
346 (BadAuth, TPM_RC_FMT1 | 0x022, "TPM_RC_BAD_AUTH"),
347 (Expired, TPM_RC_FMT1 | 0x023, "TPM_RC_EXPIRED"),
348 (PolicyCc, TPM_RC_FMT1 | 0x024, "TPM_RC_POLICY_CC"),
349 (Binding, TPM_RC_FMT1 | 0x025, "TPM_RC_BINDING"),
350 (Curve, TPM_RC_FMT1 | 0x026, "TPM_RC_CURVE"),
351 (EccPoint, TPM_RC_FMT1 | 0x027, "TPM_RC_ECC_POINT"),
352 (FwLimited, TPM_RC_FMT1 | 0x028, "TPM_RC_FW_LIMITED"),
353 (SvnLimited, TPM_RC_FMT1 | 0x029, "TPM_RC_SVN_LIMITED"),
354 (Channel, TPM_RC_FMT1 | 0x030, "TPM_RC_CHANNEL"),
355 (ChannelKey, TPM_RC_FMT1 | 0x031, "TPM_RC_CHANNEL_KEY"),
356 (ContextGap, TPM_RC_WARN | 0x001, "TPM_RC_CONTEXT_GAP"),
357 (ObjectMemory, TPM_RC_WARN | 0x002, "TPM_RC_OBJECT_MEMORY"),
358 (SessionMemory, TPM_RC_WARN | 0x003, "TPM_RC_SESSION_MEMORY"),
359 (Memory, TPM_RC_WARN | 0x004, "TPM_RC_MEMORY"),
360 (TpmSessions, TPM_RC_WARN | 0x005, "TPM_RC_SESSION_HANDLES"),
361 (TpmTransients, TPM_RC_WARN | 0x006, "TPM_RC_OBJECT_HANDLES"),
362 (Locality, TPM_RC_WARN | 0x007, "TPM_RC_LOCALITY"),
363 (Yielded, TPM_RC_WARN | 0x008, "TPM_RC_YIELDED"),
364 (Canceled, TPM_RC_WARN | 0x009, "TPM_RC_CANCELED"),
365 (Testing, TPM_RC_WARN | 0x00A, "TPM_RC_TESTING"),
366 (ReferenceH0, TPM_RC_WARN | 0x010, "TPM_RC_REFERENCE_H0"),
367 (ReferenceH1, TPM_RC_WARN | 0x011, "TPM_RC_REFERENCE_H1"),
368 (ReferenceH2, TPM_RC_WARN | 0x012, "TPM_RC_REFERENCE_H2"),
369 (ReferenceH3, TPM_RC_WARN | 0x013, "TPM_RC_REFERENCE_H3"),
370 (ReferenceH4, TPM_RC_WARN | 0x014, "TPM_RC_REFERENCE_H4"),
371 (ReferenceH5, TPM_RC_WARN | 0x015, "TPM_RC_REFERENCE_H5"),
372 (ReferenceH6, TPM_RC_WARN | 0x016, "TPM_RC_REFERENCE_H6"),
373 (ReferenceS0, TPM_RC_WARN | 0x018, "TPM_RC_REFERENCE_S0"),
374 (ReferenceS1, TPM_RC_WARN | 0x019, "TPM_RC_REFERENCE_S1"),
375 (ReferenceS2, TPM_RC_WARN | 0x01A, "TPM_RC_REFERENCE_S2"),
376 (ReferenceS3, TPM_RC_WARN | 0x01B, "TPM_RC_REFERENCE_S3"),
377 (ReferenceS4, TPM_RC_WARN | 0x01C, "TPM_RC_REFERENCE_S4"),
378 (ReferenceS5, TPM_RC_WARN | 0x01D, "TPM_RC_REFERENCE_S5"),
379 (ReferenceS6, TPM_RC_WARN | 0x01E, "TPM_RC_REFERENCE_S6"),
380 (NvRate, TPM_RC_WARN | 0x020, "TPM_RC_NV_RATE"),
381 (Lockout, TPM_RC_WARN | 0x021, "TPM_RC_LOCKOUT"),
382 (Retry, TPM_RC_WARN | 0x022, "TPM_RC_RETRY"),
383 (NvUnavailable, TPM_RC_WARN | 0x023, "TPM_RC_NV_UNAVAILABLE"),
384 (NotUsed, 0xFFFF_FFFF, "TPM_RC_NOT_USED"),
385 }
386}
387
388#[must_use]
389#[derive(Debug, PartialEq, Eq, Copy, Clone)]
390pub struct TpmRc(u32);
391
392impl TpmRc {
393 pub fn base(self) -> Result<TpmRcBase, crate::TpmErrorKind> {
400 let value = self.0;
401 let base_code = if (value & TPM_RC_FMT1) != 0 {
402 TPM_RC_FMT1 | (value & TPM_RC_FMT1_ERROR_MASK)
403 } else {
404 value
405 };
406
407 TpmRcBase::try_from(base_code).map_err(|()| crate::TpmErrorKind::InternalError)
408 }
409
410 #[must_use]
412 pub fn index(self) -> Option<TpmRcIndex> {
413 let value = self.0;
414
415 if (value & TPM_RC_FMT1) == 0 {
416 return None;
417 }
418
419 let is_parameter = (value & TPM_RC_P_BIT) != 0;
420
421 let n = ((value >> TPM_RC_N_SHIFT) & 0b1111) as u8;
422 if n == 0 {
423 return None;
424 }
425
426 if is_parameter {
427 Some(TpmRcIndex::Parameter(n))
428 } else if n <= 7 {
429 Some(TpmRcIndex::Handle(n))
430 } else {
431 Some(TpmRcIndex::Session(n - 8))
432 }
433 }
434
435 #[must_use]
437 pub fn value(self) -> u32 {
438 self.0
439 }
440
441 #[must_use]
443 pub fn is_warning(self) -> bool {
444 (self.0 & TPM_RC_WARN) == TPM_RC_WARN
445 }
446
447 #[must_use]
449 pub fn is_error(self) -> bool {
450 !self.is_warning() && self.0 != 0
451 }
452}
453
454impl TryFrom<u32> for TpmRc {
455 type Error = crate::TpmErrorKind;
456
457 fn try_from(value: u32) -> Result<Self, Self::Error> {
458 let base_code = if (value & TPM_RC_FMT1) != 0 {
459 TPM_RC_FMT1 | (value & TPM_RC_FMT1_ERROR_MASK)
460 } else {
461 value
462 };
463
464 TpmRcBase::try_from(base_code).map_err(|()| crate::TpmErrorKind::InvalidDiscriminant {
465 type_name: "TpmRcBase",
466 value: u64::from(base_code),
467 })?;
468
469 Ok(TpmRc(value))
470 }
471}
472
473impl From<TpmRc> for u32 {
474 fn from(val: TpmRc) -> Self {
475 val.0
476 }
477}
478
479impl From<TpmRcBase> for TpmRc {
480 fn from(value: TpmRcBase) -> Self {
481 TpmRc(value as u32)
482 }
483}
484
485impl Display for TpmRc {
486 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
487 match self.base() {
488 Ok(base) => {
489 if let Some(index) = self.index() {
490 write!(f, "[{base}, {index}]")
491 } else {
492 write!(f, "{base}")
493 }
494 }
495 Err(_) => {
496 write!(f, "TPM_RC_UNKNOWN(0x{:08X})", self.0)
497 }
498 }
499 }
500}
501
502tpm_enum! {
503 #[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]
505 pub enum TpmRh(u32) {
506 (Srk, 0x4000_0000, "TPM_RH_SRK"),
507 (Owner, 0x4000_0001, "TPM_RH_OWNER"),
508 #[default]
509 (Null, 0x4000_0007, "TPM_RH_NULL"),
510 (Unassigned, 0x4000_0008, "TPM_RH_UNASSIGNED"),
511 (Password, 0x4000_0009, "TPM_RH_PW"),
512 (Lockout, 0x4000_000A, "TPM_RH_LOCKOUT"),
513 (Endorsement, 0x4000_000B, "TPM_RH_ENDORSEMENT"),
514 (Platform, 0x4000_000C, "TPM_RH_PLATFORM"),
515 (PlatformNv, 0x4000_000D, "TPM_RH_PLATFORM_NV"),
516 (Auth00, 0x4000_0010, "TPM_RH_AUTH_00"),
517 (AuthFF, 0x4000_010F, "TPM_RH_AUTH_FF"),
518 (TransientFirst, 0x8000_0000, "First transient handle"),
519 (PersistentFirst, 0x8100_0000, "First persistent handle"),
520 }
521}
522
523tpm_enum! {
524 #[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
526 pub enum TpmSe(u8) {
527 #[default]
529 (Hmac, 0x00, "TPM_SE_HMAC"),
530 (Policy, 0x01, "TPM_SE_POLICY"),
532 (Trial, 0x03, "TPM_SE_TRIAL"),
534 }
535}
536
537tpm_enum! {
538 #[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
540 pub enum TpmSt(u16) {
541 (RspCommand, 0x00C4, "TPM_ST_RSP_COMMAND"),
542 #[default]
543 (Null, 0x8000, "TPM_ST_NULL"),
544 (NoSessions, 0x8001, "TPM_ST_NO_SESSIONS"),
545 (Sessions, 0x8002, "TPM_ST_SESSIONS"),
546 (AttestNv, 0x8014, "TPM_ST_ATTEST_NV"),
547 (AttestCommandAudit, 0x8015, "TPM_ST_ATTEST_COMMAND_AUDIT"),
548 (AttestSessionAudit, 0x8016, "TPM_ST_ATTEST_SESSION_AUDIT"),
549 (AttestCertify, 0x8017, "TPM_ST_ATTEST_CERTIFY"),
550 (AttestQuote, 0x8018, "TPM_ST_ATTEST_QUOTE"),
551 (AttestTime, 0x8019, "TPM_ST_ATTEST_TIME"),
552 (AttestCreation, 0x801A, "TPM_ST_ATTEST_CREATION"),
553 (Creation, 0x8021, "TPM_ST_CREATION"),
554 (Verified, 0x8022, "TPM_ST_VERIFIED"),
555 (AuthSecret, 0x8023, "TPM_ST_AUTH_SECRET"),
556 (HashCheck, 0x8024, "TPM_ST_HASHCHECK"),
557 (AuthSigned, 0x8025, "TPM_ST_AUTH_SIGNED"),
558 (FuManifest, 0x8029, "TPM_ST_FU_MANIFEST"),
559 }
560}
561
562tpm_bitflags! {
563 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
565 pub struct TpmaAlgorithm(u32) {
566 const ASYMMETRIC = 0x0000_0001;
568 const SYMMETRIC = 0x0000_0002;
570 const HASH = 0x0000_0004;
572 const OBJECT = 0x0000_0008;
574 const SIGNING = 0x0000_0100;
576 const ENCRYPTING = 0x0000_0200;
578 const METHOD = 0x0000_0400;
580 const RSA_KEY_SIZES_1024 = 0x0001_0000;
582 const RSA_KEY_SIZES_2048 = 0x0002_0000;
584 const RSA_KEY_SIZES_3072 = 0x0004_0000;
586 const RSA_KEY_SIZES_4096 = 0x0008_0000;
588 }
589}
590
591tpm_bitflags! {
592 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
594 pub struct TpmaLocality(u8) {
595 const TPM_LOC_ZERO = 0x01;
596 const TPM_LOC_ONE = 0x02;
597 const TPM_LOC_TWO = 0x04;
598 const TPM_LOC_THREE = 0x08;
599 const TPM_LOC_FOUR = 0x10;
600 const EXTENDED = 0xE0;
601 }
602}
603
604tpm_bitflags! {
605 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
607 pub struct TpmaNv(u32) {
608 const PPWRITE = 0x0000_0001;
609 const OWNERWRITE = 0x0000_0002;
610 const AUTHWRITE = 0x0000_0004;
611 const POLICYWRITE = 0x0000_0008;
612 const TPM_NT_ORDINARY = 0x0000_0000;
613 const TPM_NT_COUNTER = 0x0000_0010;
614 const TPM_NT_BITS = 0x0000_0020;
615 const TPM_NT_EXTEND = 0x0000_0040;
616 const TPM_NT_PIN_FAIL = 0x0000_0080;
617 const TPM_NT_PIN_PASS = 0x0000_0090;
618 const POLICY_DELETE = 0x0000_0400;
619 const WRITELOCKED = 0x0000_0800;
620 const WRITEALL = 0x0000_1000;
621 const WRITEDEFINE = 0x0000_2000;
622 const WRITE_STCLEAR = 0x0000_4000;
623 const GLOBALLOCK = 0x0000_8000;
624 const PPREAD = 0x0001_0000;
625 const OWNERREAD = 0x0002_0000;
626 const AUTHREAD = 0x0004_0000;
627 const POLICYREAD = 0x0008_0000;
628 const NO_DA = 0x0200_0000;
629 const ORDERLY = 0x0400_0000;
630 const CLEAR_STCLEAR = 0x0800_0000;
631 const READLOCKED = 0x1000_0000;
632 const WRITTEN = 0x2000_0000;
633 const PLATFORMCREATE = 0x4000_0000;
634 const READ_STCLEAR = 0x8000_0000;
635 }
636}
637
638tpm_bitflags! {
639 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
641 pub struct TpmaObject(u32) {
642 const FIXED_TPM = 0x0000_0002;
644 const ST_CLEAR = 0x0000_0004;
646 const FIXED_PARENT = 0x0000_0010;
648 const SENSITIVE_DATA_ORIGIN = 0x0000_0020;
650 const USER_WITH_AUTH = 0x0000_0040;
652 const ADMIN_WITH_POLICY = 0x0000_0080;
654 const NO_DA = 0x0000_0400;
656 const ENCRYPTED_DUPLICATION = 0x0000_0800;
658 const RESTRICTED = 0x0001_0000;
660 const DECRYPT = 0x0002_0000;
662 const SIGN_ENCRYPT = 0x0004_0000;
664 }
665}
666
667tpm_bitflags! {
668 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
670 pub struct TpmaSession(u8) {
671 const CONTINUE_SESSION = 0x01;
672 const AUDIT_EXCLUSIVE = 0x02;
673 const AUDIT_RESET = 0x04;
674 const DECRYPT = 0x20;
675 const ENCRYPT = 0x40;
676 const AUDIT = 0x80;
677 }
678}
679
680tpm_bool! {
681 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
683 pub struct TpmiYesNo(bool);
684}
685
686tpml!(TpmlAlgProperty, TpmsAlgProperty, 64);
687tpml!(TpmlDigest, Tpm2bDigest, 8);
688tpml!(TpmlDigestValues, TpmtHa, 8);
689tpml!(TpmlHandle, u32, 128);
690tpml!(TpmlPcrSelection, TpmsPcrSelection, 8);
691
692pub const TPM_ST_GENERATED_VALUE: u32 = 0xFF54_4347;
693pub const TPM_PCR_SELECT_MAX: usize = 3;
694
695pub type TpmsPcrSelect = TpmBuffer<TPM_PCR_SELECT_MAX>;
696
697tpm_struct! {
698 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
699 pub struct TpmsAlgProperty {
700 pub alg: TpmAlgId,
701 pub alg_properties: TpmaAlgorithm,
702 }
703}
704
705#[derive(Debug, PartialEq, Eq, Clone)]
706pub struct TpmsAttest {
707 pub tag: TpmSt,
708 pub qualified_signer: Tpm2bName,
709 pub extra_data: Tpm2bData,
710 pub clock_info: TpmsClockInfo,
711 pub firmware_version: u64,
712 pub attested: TpmuAttest,
713}
714
715impl TpmTagged for TpmsAttest {
716 type Tag = TpmSt;
717 type Value = TpmuAttest;
718}
719
720impl TpmSized for TpmsAttest {
721 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
722 fn len(&self) -> usize {
723 size_of::<u32>()
724 + self.tag.len()
725 + self.qualified_signer.len()
726 + self.extra_data.len()
727 + self.clock_info.len()
728 + self.firmware_version.len()
729 + self.attested.len()
730 }
731}
732
733impl TpmBuild for TpmsAttest {
734 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
735 TPM_ST_GENERATED_VALUE.build(writer)?;
736 self.tag.build(writer)?;
737 self.qualified_signer.build(writer)?;
738 self.extra_data.build(writer)?;
739 self.clock_info.build(writer)?;
740 self.firmware_version.build(writer)?;
741 self.attested.build(writer)
742 }
743}
744
745impl<'a> TpmParse<'a> for TpmsAttest {
746 fn parse(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
747 let (magic, buf) = u32::parse(buf)?;
748 if magic != TPM_ST_GENERATED_VALUE {
749 return Err(TpmErrorKind::InvalidMagic {
750 expected: TPM_ST_GENERATED_VALUE,
751 got: magic,
752 });
753 }
754
755 let (tag, buf) = TpmSt::parse(buf)?;
756 let (qualified_signer, buf) = Tpm2bName::parse(buf)?;
757 let (extra_data, buf) = Tpm2bData::parse(buf)?;
758 let (clock_info, buf) = TpmsClockInfo::parse(buf)?;
759 let (firmware_version, buf) = u64::parse(buf)?;
760 let (attested, buf) = TpmuAttest::parse_tagged(tag, buf)?;
761
762 Ok((
763 Self {
764 tag,
765 qualified_signer,
766 extra_data,
767 clock_info,
768 firmware_version,
769 attested,
770 },
771 buf,
772 ))
773 }
774}
775
776impl Default for TpmsAttest {
777 fn default() -> Self {
778 Self {
779 tag: TpmSt::AttestQuote,
780 qualified_signer: Tpm2bName::default(),
781 extra_data: Tpm2bData::default(),
782 clock_info: TpmsClockInfo::default(),
783 firmware_version: 0,
784 attested: TpmuAttest::default(),
785 }
786 }
787}
788
789tpm_struct! {
790 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
791 pub struct TpmsAuthCommand {
792 pub session_handle: crate::TpmSession,
793 pub nonce: Tpm2bNonce,
794 pub session_attributes: TpmaSession,
795 pub hmac: Tpm2bAuth,
796 }
797}
798
799tpm_struct! {
800 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
801 pub struct TpmsAuthResponse {
802 pub nonce: Tpm2bNonce,
803 pub session_attributes: TpmaSession,
804 pub hmac: Tpm2bAuth,
805 }
806}
807
808#[derive(Debug, PartialEq, Eq, Clone)]
809pub struct TpmsCapabilityData {
810 pub capability: TpmCap,
811 pub data: TpmuCapabilities,
812}
813
814impl TpmTagged for TpmsCapabilityData {
815 type Tag = TpmCap;
816 type Value = ();
817}
818
819impl TpmSized for TpmsCapabilityData {
820 const SIZE: usize = size_of::<u32>() + TpmuCapabilities::SIZE;
821 fn len(&self) -> usize {
822 self.capability.len() + self.data.len()
823 }
824}
825
826impl TpmBuild for TpmsCapabilityData {
827 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
828 self.capability.build(writer)?;
829 self.data.build(writer)
830 }
831}
832
833impl<'a> TpmParse<'a> for TpmsCapabilityData {
834 fn parse(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
835 let (capability, buf) = TpmCap::parse(buf)?;
836 let (data, buf) = TpmuCapabilities::parse_tagged(capability, buf)?;
837 Ok((Self { capability, data }, buf))
838 }
839}
840
841tpm_struct! {
842 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
844 pub struct TpmsCertifyInfo {
845 pub name: Tpm2bName,
846 pub qualified_name: Tpm2bName,
847 }
848}
849
850tpm_struct! {
851 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
853 pub struct TpmsClockInfo {
854 pub clock: u64,
855 pub reset_count: u32,
856 pub restart_count: u32,
857 pub safe: TpmiYesNo,
858 }
859}
860
861tpm_struct! {
862 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
864 pub struct TpmsCommandAuditInfo {
865 pub audit_counter: u64,
866 pub digest_alg: TpmAlgId,
867 pub audit_digest: Tpm2bDigest,
868 pub command_digest: Tpm2bDigest,
869 }
870}
871
872tpm_struct! {
873 #[derive(Debug, PartialEq, Eq, Clone)]
874 pub struct TpmsContext {
875 pub sequence: u64,
876 pub saved_handle: crate::TpmTransient,
877 pub hierarchy: TpmRh,
878 pub context_blob: Tpm2b,
879 }
880}
881
882tpm_struct! {
883 #[derive(Debug, PartialEq, Eq, Clone, Default)]
884 pub struct TpmsContextData {
885 pub integrity: Tpm2bDigest,
886 pub encrypted: Tpm2bSensitive,
887 }
888}
889
890tpm_struct! {
891 #[derive(Debug, PartialEq, Eq, Clone, Default)]
892 pub struct TpmsCreationData {
893 pub pcr_select: TpmlPcrSelection,
894 pub pcr_digest: Tpm2bDigest,
895 pub locality: TpmaLocality,
896 pub parent_name_alg: TpmAlgId,
897 pub parent_name: Tpm2bName,
898 pub parent_qualified_name: Tpm2bName,
899 pub outside_info: Tpm2bData,
900 }
901}
902
903tpm_struct! {
904 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
906 pub struct TpmsCreationInfo {
907 pub object_name: Tpm2bName,
908 pub creation_hash: Tpm2bDigest,
909 }
910}
911
912tpm_struct! {
913 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
914 pub struct TpmsEccPoint {
915 pub x: Tpm2bEccParameter,
916 pub y: Tpm2bEccParameter,
917 }
918}
919
920tpm_struct! {
921 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
922 pub struct TpmsEmpty {}
923}
924
925tpm_struct! {
926 #[derive(Debug, PartialEq, Eq, Clone, Default)]
927 pub struct TpmsIdObject {
928 pub integrity_hmac: Tpm2bDigest,
929 pub enc_identity: Tpm2bDigest,
930 }
931}
932
933tpm_struct! {
934 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
935 pub struct TpmsKeyedhashParms {
936 pub scheme: TpmtScheme,
937 }
938}
939
940tpm_struct! {
941 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
942 pub struct TpmsNvCertifyInfo {
943 pub index_name: Tpm2bName,
944 pub offset: u16,
945 pub nv_contents: Tpm2bMaxNvBuffer,
946 }
947}
948
949tpm_struct! {
950 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
951 pub struct TpmsNvPublic {
952 pub nv_index: u32,
953 pub name_alg: TpmAlgId,
954 pub attributes: TpmaNv,
955 pub auth_policy: Tpm2bDigest,
956 pub data_size: u16,
957 }
958}
959
960#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
961pub struct TpmsPcrSelection {
962 pub hash: TpmAlgId,
963 pub pcr_select: TpmsPcrSelect,
964}
965
966impl TpmSized for TpmsPcrSelection {
967 const SIZE: usize = TpmAlgId::SIZE + 1 + TPM_PCR_SELECT_MAX;
968
969 fn len(&self) -> usize {
970 self.hash.len() + 1 + self.pcr_select.deref().len()
971 }
972}
973
974impl TpmBuild for TpmsPcrSelection {
975 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
976 self.hash.build(writer)?;
977 let size =
978 u8::try_from(self.pcr_select.deref().len()).map_err(|_| TpmErrorKind::ValueTooLarge)?;
979 size.build(writer)?;
980 writer.write_bytes(&self.pcr_select)
981 }
982}
983
984impl<'a> TpmParse<'a> for TpmsPcrSelection {
985 fn parse(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
986 let (hash, buf) = TpmAlgId::parse(buf)?;
987 let (size, buf) = u8::parse(buf)?;
988 let size = size as usize;
989
990 if size > TPM_PCR_SELECT_MAX {
991 return Err(TpmErrorKind::ValueTooLarge);
992 }
993 if buf.len() < size {
994 return Err(TpmErrorKind::Boundary);
995 }
996
997 let (pcr_bytes, buf) = buf.split_at(size);
998 let pcr_select = TpmBuffer::try_from(pcr_bytes)?;
999
1000 Ok((Self { hash, pcr_select }, buf))
1001 }
1002}
1003
1004tpm_struct! {
1005 #[derive(Debug, PartialEq, Eq, Clone, Default)]
1006 pub struct TpmsQuoteInfo {
1007 pub pcr_select: TpmlPcrSelection,
1008 pub pcr_digest: Tpm2bDigest,
1009 }
1010}
1011
1012tpm_struct! {
1013 #[derive(Debug, PartialEq, Eq, Clone, Default)]
1014 pub struct TpmsSensitiveCreate {
1015 pub user_auth: Tpm2bAuth,
1016 pub data: Tpm2bSensitiveData,
1017 }
1018}
1019
1020tpm_struct! {
1021 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
1022 pub struct TpmsSessionAuditInfo {
1023 pub exclusive_session: TpmiYesNo,
1024 pub session_digest: Tpm2bDigest,
1025 }
1026}
1027
1028tpm_struct! {
1029 #[derive(Debug, PartialEq, Eq, Clone, Default, Copy)]
1030 pub struct TpmsSymcipherParms {
1031 pub sym: TpmtSymDefObject,
1032 }
1033}
1034
1035tpm_struct! {
1036 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
1037 pub struct TpmsTimeAttestInfo {
1038 pub time: TpmsTimeInfo,
1039 pub firmware_version: u64,
1040 }
1041}
1042
1043tpm_struct! {
1044 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
1045 pub struct TpmsTimeInfo {
1046 pub time: u64,
1047 pub clock_info: TpmsClockInfo,
1048 }
1049}
1050
1051#[derive(Debug, PartialEq, Eq, Clone, Copy)]
1052pub enum TpmuSymMode {
1053 Aes(TpmAlgId),
1054 Sm4(TpmAlgId),
1055 Camellia(TpmAlgId),
1056 Xor,
1057 Null,
1058}
1059
1060impl TpmTagged for TpmuSymMode {
1061 type Tag = TpmAlgId;
1062 type Value = ();
1063}
1064
1065impl Default for TpmuSymMode {
1066 fn default() -> Self {
1067 Self::Null
1068 }
1069}
1070
1071impl TpmSized for TpmuSymMode {
1072 const SIZE: usize = core::mem::size_of::<u16>();
1073 fn len(&self) -> usize {
1074 match self {
1075 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) => val.len(),
1076 Self::Xor | Self::Null => 0,
1077 }
1078 }
1079}
1080
1081impl<'a> TpmParseTagged<'a> for TpmuSymMode {
1082 fn parse_tagged(tag: TpmAlgId, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1083 match tag {
1084 TpmAlgId::Aes => {
1085 let (val, buf) = TpmAlgId::parse(buf)?;
1086 Ok((Self::Aes(val), buf))
1087 }
1088 TpmAlgId::Sm4 => {
1089 let (val, buf) = TpmAlgId::parse(buf)?;
1090 Ok((Self::Sm4(val), buf))
1091 }
1092 TpmAlgId::Camellia => {
1093 let (val, buf) = TpmAlgId::parse(buf)?;
1094 Ok((Self::Camellia(val), buf))
1095 }
1096 TpmAlgId::Xor => Ok((Self::Xor, buf)),
1097 TpmAlgId::Null => Ok((Self::Null, buf)),
1098 _ => Err(TpmErrorKind::InvalidValue),
1099 }
1100 }
1101}
1102
1103impl TpmBuild for TpmuSymMode {
1104 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1105 match self {
1106 TpmuSymMode::Aes(val) | TpmuSymMode::Sm4(val) | TpmuSymMode::Camellia(val) => {
1107 val.build(writer)
1108 }
1109 TpmuSymMode::Xor | TpmuSymMode::Null => Ok(()),
1110 }
1111 }
1112}
1113
1114#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
1115pub struct TpmtHa {
1116 pub hash_alg: TpmAlgId,
1117 pub digest: TpmuHa,
1118}
1119
1120impl TpmTagged for TpmtHa {
1121 type Tag = TpmAlgId;
1122 type Value = TpmuHa;
1123}
1124
1125impl TpmSized for TpmtHa {
1126 const SIZE: usize = size_of::<u16>() + TpmuHa::SIZE;
1127 fn len(&self) -> usize {
1128 self.hash_alg.len() + self.digest.len()
1129 }
1130}
1131
1132impl TpmBuild for TpmtHa {
1133 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1134 self.hash_alg.build(writer)?;
1135 self.digest.build(writer)
1136 }
1137}
1138
1139impl<'a> TpmParse<'a> for TpmtHa {
1140 fn parse(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1141 let (hash_alg, buf) = TpmAlgId::parse(buf)?;
1142 let (digest, buf) = TpmuHa::parse_tagged(hash_alg, buf)?;
1143 Ok((Self { hash_alg, digest }, buf))
1144 }
1145}
1146
1147tpm_struct! {
1148 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
1150 pub struct TpmtKdfScheme {
1151 pub scheme: TpmAlgId,
1152 }
1153}
1154
1155#[derive(Debug, PartialEq, Eq, Clone)]
1156pub struct TpmtPublic {
1157 pub object_type: TpmAlgId,
1158 pub name_alg: TpmAlgId,
1159 pub object_attributes: TpmaObject,
1160 pub auth_policy: Tpm2bDigest,
1161 pub parameters: TpmuPublicParms,
1162 pub unique: TpmuPublicId,
1163}
1164
1165impl TpmTagged for TpmtPublic {
1166 type Tag = TpmAlgId;
1167 type Value = TpmuPublicParms;
1168}
1169
1170impl TpmSized for TpmtPublic {
1171 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
1172 fn len(&self) -> usize {
1173 self.object_type.len()
1174 + self.name_alg.len()
1175 + self.object_attributes.len()
1176 + self.auth_policy.len()
1177 + self.parameters.len()
1178 + self.unique.len()
1179 }
1180}
1181
1182impl TpmBuild for TpmtPublic {
1183 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1184 self.object_type.build(writer)?;
1185 self.name_alg.build(writer)?;
1186 self.object_attributes.build(writer)?;
1187 self.auth_policy.build(writer)?;
1188 self.parameters.build(writer)?;
1189 self.unique.build(writer)
1190 }
1191}
1192
1193impl<'a> TpmParse<'a> for TpmtPublic {
1194 fn parse(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1195 let (object_type, mut buf) = TpmAlgId::parse(buf)?;
1196 let (name_alg, rest) = TpmAlgId::parse(buf)?;
1197 buf = rest;
1198 let (object_attributes, rest) = TpmaObject::parse(buf)?;
1199 buf = rest;
1200 let (auth_policy, rest) = Tpm2bDigest::parse(buf)?;
1201 buf = rest;
1202 let (parameters, rest) = TpmuPublicParms::parse_tagged(object_type, buf)?;
1203 buf = rest;
1204 let (unique, rest) = TpmuPublicId::parse_tagged(object_type, buf)?;
1205 buf = rest;
1206
1207 let public_area = Self {
1208 object_type,
1209 name_alg,
1210 object_attributes,
1211 auth_policy,
1212 parameters,
1213 unique,
1214 };
1215
1216 Ok((public_area, buf))
1217 }
1218}
1219
1220impl Default for TpmtPublic {
1221 fn default() -> Self {
1222 Self {
1223 object_type: TpmAlgId::Null,
1224 name_alg: TpmAlgId::Sha256,
1225 object_attributes: TpmaObject::empty(),
1226 auth_policy: Tpm2bDigest::default(),
1227 parameters: TpmuPublicParms::Null,
1228 unique: TpmuPublicId::Null,
1229 }
1230 }
1231}
1232
1233tpm_struct! {
1234 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
1236 pub struct TpmtScheme {
1237 pub scheme: TpmAlgId,
1238 }
1239}
1240
1241#[derive(Debug, PartialEq, Eq, Clone, Default)]
1242pub struct TpmtSensitive {
1243 pub sensitive_type: TpmAlgId,
1244 pub auth_value: Tpm2bAuth,
1245 pub seed_value: Tpm2bDigest,
1246 pub sensitive: TpmuSensitiveComposite,
1247}
1248
1249impl TpmTagged for TpmtSensitive {
1250 type Tag = TpmAlgId;
1251 type Value = TpmuSensitiveComposite;
1252}
1253
1254impl TpmtSensitive {
1255 pub fn from_private_bytes(
1261 key_alg: TpmAlgId,
1262 private_bytes: &[u8],
1263 ) -> Result<Self, TpmErrorKind> {
1264 let sensitive = match key_alg {
1265 TpmAlgId::Rsa => {
1266 TpmuSensitiveComposite::Rsa(Tpm2bPrivateKeyRsa::try_from(private_bytes)?)
1267 }
1268 TpmAlgId::Ecc => {
1269 TpmuSensitiveComposite::Ecc(Tpm2bEccParameter::try_from(private_bytes)?)
1270 }
1271 TpmAlgId::KeyedHash => {
1272 TpmuSensitiveComposite::Bits(Tpm2bSensitiveData::try_from(private_bytes)?)
1273 }
1274 TpmAlgId::SymCipher => {
1275 TpmuSensitiveComposite::Sym(Tpm2bSymKey::try_from(private_bytes)?)
1276 }
1277 _ => return Err(TpmErrorKind::InvalidValue),
1278 };
1279
1280 Ok(Self {
1281 sensitive_type: key_alg,
1282 auth_value: Tpm2bAuth::default(),
1283 seed_value: Tpm2bDigest::default(),
1284 sensitive,
1285 })
1286 }
1287}
1288
1289impl TpmSized for TpmtSensitive {
1290 const SIZE: usize =
1291 size_of::<TpmAlgId>() + Tpm2bAuth::SIZE + Tpm2bDigest::SIZE + TpmuSensitiveComposite::SIZE;
1292 fn len(&self) -> usize {
1293 self.sensitive_type.len()
1294 + self.auth_value.len()
1295 + self.seed_value.len()
1296 + self.sensitive.len()
1297 }
1298}
1299
1300impl TpmBuild for TpmtSensitive {
1301 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1302 self.sensitive_type.build(writer)?;
1303 self.auth_value.build(writer)?;
1304 self.seed_value.build(writer)?;
1305 self.sensitive.build(writer)
1306 }
1307}
1308
1309impl<'a> TpmParse<'a> for TpmtSensitive {
1310 fn parse(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1311 let (sensitive_type, buf) = TpmAlgId::parse(buf)?;
1312 let (auth_value, buf) = Tpm2bAuth::parse(buf)?;
1313 let (seed_value, buf) = Tpm2bDigest::parse(buf)?;
1314 let (sensitive, buf) = TpmuSensitiveComposite::parse_tagged(sensitive_type, buf)?;
1315
1316 Ok((
1317 Self {
1318 sensitive_type,
1319 auth_value,
1320 seed_value,
1321 sensitive,
1322 },
1323 buf,
1324 ))
1325 }
1326}
1327
1328#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
1329pub struct TpmtSymDef {
1330 pub algorithm: TpmAlgId,
1331 pub key_bits: TpmuSymKeyBits,
1332 pub mode: TpmuSymMode,
1333}
1334
1335impl TpmTagged for TpmtSymDef {
1336 type Tag = TpmAlgId;
1337 type Value = TpmuSymKeyBits;
1338}
1339
1340impl TpmSized for TpmtSymDef {
1341 const SIZE: usize = TpmAlgId::SIZE + TpmuSymKeyBits::SIZE + TpmAlgId::SIZE;
1342 fn len(&self) -> usize {
1343 if self.algorithm == TpmAlgId::Null {
1344 self.algorithm.len()
1345 } else {
1346 self.algorithm.len() + self.key_bits.len() + self.mode.len()
1347 }
1348 }
1349}
1350
1351impl TpmBuild for TpmtSymDef {
1352 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1353 self.algorithm.build(writer)?;
1354 if self.algorithm != TpmAlgId::Null {
1355 self.key_bits.build(writer)?;
1356 self.mode.build(writer)?;
1357 }
1358 Ok(())
1359 }
1360}
1361
1362impl<'a> TpmParse<'a> for TpmtSymDef {
1363 fn parse(buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1364 let (algorithm, buf) = TpmAlgId::parse(buf)?;
1365 if algorithm == TpmAlgId::Null {
1366 Ok((
1367 Self {
1368 algorithm,
1369 key_bits: TpmuSymKeyBits::Null,
1370 mode: TpmuSymMode::Null,
1371 },
1372 buf,
1373 ))
1374 } else {
1375 let (key_bits, buf) = TpmuSymKeyBits::parse_tagged(algorithm, buf)?;
1376 let (mode, buf) = TpmuSymMode::parse_tagged(algorithm, buf)?;
1377 Ok((
1378 Self {
1379 algorithm,
1380 key_bits,
1381 mode,
1382 },
1383 buf,
1384 ))
1385 }
1386 }
1387}
1388
1389pub type TpmtSymDefObject = TpmtSymDef;
1390
1391tpm_struct! {
1392 #[derive(Debug, PartialEq, Eq, Clone, Default)]
1393 pub struct TpmtTkAuth {
1394 pub tag: TpmSt,
1395 pub hierarchy: TpmRh,
1396 pub digest: Tpm2bDigest,
1397 }
1398}
1399
1400tpm_struct! {
1401 #[derive(Debug, PartialEq, Eq, Clone, Default)]
1402 pub struct TpmtTkCreation {
1403 pub tag: TpmSt,
1404 pub hierarchy: TpmRh,
1405 pub digest: Tpm2bDigest,
1406 }
1407}
1408
1409tpm_struct! {
1410 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
1411 pub struct TpmtTkHashcheck {
1412 pub tag: TpmSt,
1413 pub hierarchy: TpmRh,
1414 pub digest: Tpm2bDigest,
1415 }
1416}
1417
1418#[allow(clippy::large_enum_variant)]
1419#[derive(Debug, PartialEq, Eq, Clone)]
1420pub enum TpmuAttest {
1421 Certify(TpmsCertifyInfo),
1422 Creation(TpmsCreationInfo),
1423 Quote(TpmsQuoteInfo),
1424 CommandAudit(TpmsCommandAuditInfo),
1425 SessionAudit(TpmsSessionAuditInfo),
1426 Time(TpmsTimeAttestInfo),
1427 Nv(TpmsNvCertifyInfo),
1428}
1429
1430impl TpmTagged for TpmuAttest {
1431 type Tag = TpmSt;
1432 type Value = ();
1433}
1434
1435impl TpmSized for TpmuAttest {
1436 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
1437 fn len(&self) -> usize {
1438 match self {
1439 Self::Certify(val) => val.len(),
1440 Self::Creation(val) => val.len(),
1441 Self::Quote(val) => val.len(),
1442 Self::CommandAudit(val) => val.len(),
1443 Self::SessionAudit(val) => val.len(),
1444 Self::Time(val) => val.len(),
1445 Self::Nv(val) => val.len(),
1446 }
1447 }
1448}
1449
1450impl TpmBuild for TpmuAttest {
1451 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1452 match self {
1453 Self::Certify(val) => val.build(writer),
1454 Self::Creation(val) => val.build(writer),
1455 Self::Quote(val) => val.build(writer),
1456 Self::CommandAudit(val) => val.build(writer),
1457 Self::SessionAudit(val) => val.build(writer),
1458 Self::Time(val) => val.build(writer),
1459 Self::Nv(val) => val.build(writer),
1460 }
1461 }
1462}
1463
1464impl<'a> TpmParseTagged<'a> for TpmuAttest {
1465 fn parse_tagged(tag: TpmSt, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1466 match tag {
1467 TpmSt::AttestCertify => {
1468 let (val, buf) = TpmsCertifyInfo::parse(buf)?;
1469 Ok((Self::Certify(val), buf))
1470 }
1471 TpmSt::AttestCreation => {
1472 let (val, buf) = TpmsCreationInfo::parse(buf)?;
1473 Ok((Self::Creation(val), buf))
1474 }
1475 TpmSt::AttestQuote => {
1476 let (val, buf) = TpmsQuoteInfo::parse(buf)?;
1477 Ok((Self::Quote(val), buf))
1478 }
1479 TpmSt::AttestCommandAudit => {
1480 let (val, buf) = TpmsCommandAuditInfo::parse(buf)?;
1481 Ok((Self::CommandAudit(val), buf))
1482 }
1483 TpmSt::AttestSessionAudit => {
1484 let (val, buf) = TpmsSessionAuditInfo::parse(buf)?;
1485 Ok((Self::SessionAudit(val), buf))
1486 }
1487 TpmSt::AttestTime => {
1488 let (val, buf) = TpmsTimeAttestInfo::parse(buf)?;
1489 Ok((Self::Time(val), buf))
1490 }
1491 TpmSt::AttestNv => {
1492 let (val, buf) = TpmsNvCertifyInfo::parse(buf)?;
1493 Ok((Self::Nv(val), buf))
1494 }
1495 _ => Err(TpmErrorKind::InvalidValue),
1496 }
1497 }
1498}
1499
1500impl Default for TpmuAttest {
1501 fn default() -> Self {
1502 Self::Quote(TpmsQuoteInfo::default())
1503 }
1504}
1505
1506#[derive(Debug, PartialEq, Eq, Clone)]
1507pub enum TpmuCapabilities {
1508 Algs(TpmlAlgProperty),
1509 Handles(TpmlHandle),
1510 Pcrs(TpmlPcrSelection),
1511}
1512
1513impl TpmTagged for TpmuCapabilities {
1514 type Tag = TpmCap;
1515 type Value = ();
1516}
1517
1518impl TpmSized for TpmuCapabilities {
1519 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
1520 fn len(&self) -> usize {
1521 match self {
1522 Self::Algs(algs) => algs.len(),
1523 Self::Handles(handles) => handles.len(),
1524 Self::Pcrs(pcrs) => pcrs.len(),
1525 }
1526 }
1527}
1528
1529impl TpmBuild for TpmuCapabilities {
1530 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1531 match self {
1532 TpmuCapabilities::Algs(algs) => algs.build(writer),
1533 TpmuCapabilities::Handles(handles) => handles.build(writer),
1534 TpmuCapabilities::Pcrs(pcrs) => pcrs.build(writer),
1535 }
1536 }
1537}
1538
1539impl<'a> TpmParseTagged<'a> for TpmuCapabilities {
1540 fn parse_tagged(tag: TpmCap, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1541 match tag {
1542 TpmCap::Algs => {
1543 let (algs, buf) = TpmlAlgProperty::parse(buf)?;
1544 Ok((TpmuCapabilities::Algs(algs), buf))
1545 }
1546 TpmCap::Handles => {
1547 let (handles, buf) = TpmlHandle::parse(buf)?;
1548 Ok((TpmuCapabilities::Handles(handles), buf))
1549 }
1550 TpmCap::Pcrs => {
1551 let (pcrs, buf) = TpmlPcrSelection::parse(buf)?;
1552 Ok((TpmuCapabilities::Pcrs(pcrs), buf))
1553 }
1554 _ => Err(TpmErrorKind::InvalidValue),
1555 }
1556 }
1557}
1558
1559#[derive(Debug, PartialEq, Eq, Clone, Copy)]
1560pub enum TpmuHa {
1561 Sha1([u8; 20]),
1562 Sha256([u8; 32]),
1563 Sha384([u8; 48]),
1564 Sha512([u8; 64]),
1565 Sm3_256([u8; 32]),
1566}
1567
1568impl TpmTagged for TpmuHa {
1569 type Tag = TpmAlgId;
1570 type Value = ();
1571}
1572
1573impl TpmBuild for TpmuHa {
1574 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1575 writer.write_bytes(self)
1576 }
1577}
1578
1579impl<'a> TpmParseTagged<'a> for TpmuHa {
1580 fn parse_tagged(tag: TpmAlgId, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1581 let digest_size = tpm_hash_size(&tag).ok_or(TpmErrorKind::InvalidValue)?;
1582 if buf.len() < digest_size {
1583 return Err(TpmErrorKind::Boundary);
1584 }
1585
1586 let (digest_bytes, buf) = buf.split_at(digest_size);
1587
1588 macro_rules! match_hash_alg_to_digest_variant {
1589 ($tag:expr, $bytes:expr) => {
1590 match $tag {
1591 TpmAlgId::Sha1 => {
1592 TpmuHa::Sha1($bytes.try_into().map_err(|_| TpmErrorKind::InternalError)?)
1593 }
1594 TpmAlgId::Sha256 => {
1595 TpmuHa::Sha256($bytes.try_into().map_err(|_| TpmErrorKind::InternalError)?)
1596 }
1597 TpmAlgId::Sha384 => {
1598 TpmuHa::Sha384($bytes.try_into().map_err(|_| TpmErrorKind::InternalError)?)
1599 }
1600 TpmAlgId::Sha512 => {
1601 TpmuHa::Sha512($bytes.try_into().map_err(|_| TpmErrorKind::InternalError)?)
1602 }
1603 TpmAlgId::Sm3_256 => {
1604 TpmuHa::Sm3_256($bytes.try_into().map_err(|_| TpmErrorKind::InternalError)?)
1605 }
1606 _ => return Err(TpmErrorKind::InvalidValue),
1607 }
1608 };
1609 }
1610
1611 let digest = match_hash_alg_to_digest_variant!(tag, digest_bytes);
1612
1613 Ok((digest, buf))
1614 }
1615}
1616
1617impl Default for TpmuHa {
1618 fn default() -> Self {
1619 Self::Sha256([0; 32])
1620 }
1621}
1622
1623impl TpmSized for TpmuHa {
1624 const SIZE: usize = 64;
1625 fn len(&self) -> usize {
1626 match self {
1627 Self::Sha1(d) => d.len(),
1628 Self::Sha256(d) | Self::Sm3_256(d) => d.len(),
1629 Self::Sha384(d) => d.len(),
1630 Self::Sha512(d) => d.len(),
1631 }
1632 }
1633}
1634
1635impl Deref for TpmuHa {
1636 type Target = [u8];
1637
1638 fn deref(&self) -> &Self::Target {
1639 match self {
1640 Self::Sha1(d) => d,
1641 Self::Sha256(d) | Self::Sm3_256(d) => d,
1642 Self::Sha384(d) => d,
1643 Self::Sha512(d) => d,
1644 }
1645 }
1646}
1647
1648#[allow(clippy::large_enum_variant)]
1649#[derive(Debug, PartialEq, Eq, Clone)]
1650pub enum TpmuPublicId {
1651 KeyedHash(Tpm2bDigest),
1652 SymCipher(Tpm2bSymKey),
1653 Rsa(Tpm2bPublicKeyRsa),
1654 Ecc(TpmsEccPoint),
1655 Null,
1656}
1657
1658impl TpmTagged for TpmuPublicId {
1659 type Tag = TpmAlgId;
1660 type Value = ();
1661}
1662
1663impl TpmSized for TpmuPublicId {
1664 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
1665 fn len(&self) -> usize {
1666 match self {
1667 Self::KeyedHash(data) => data.len(),
1668 Self::SymCipher(data) => data.len(),
1669 Self::Rsa(data) => data.len(),
1670 Self::Ecc(point) => point.len(),
1671 Self::Null => 0,
1672 }
1673 }
1674}
1675
1676impl TpmBuild for TpmuPublicId {
1677 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1678 match self {
1679 TpmuPublicId::KeyedHash(data) => data.build(writer),
1680 TpmuPublicId::SymCipher(data) => data.build(writer),
1681 TpmuPublicId::Rsa(data) => data.build(writer),
1682 TpmuPublicId::Ecc(point) => point.build(writer),
1683 TpmuPublicId::Null => Ok(()),
1684 }
1685 }
1686}
1687
1688impl<'a> TpmParseTagged<'a> for TpmuPublicId {
1689 fn parse_tagged(tag: TpmAlgId, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1696 match tag {
1697 TpmAlgId::KeyedHash => {
1698 let (val, rest) = Tpm2bDigest::parse(buf)?;
1699 Ok((Self::KeyedHash(val), rest))
1700 }
1701 TpmAlgId::SymCipher => {
1702 let (val, rest) = Tpm2bSymKey::parse(buf)?;
1703 Ok((Self::SymCipher(val), rest))
1704 }
1705 TpmAlgId::Rsa => {
1706 let (val, rest) = Tpm2bPublicKeyRsa::parse(buf)?;
1707 Ok((Self::Rsa(val), rest))
1708 }
1709 TpmAlgId::Ecc => {
1710 let (point, rest) = TpmsEccPoint::parse(buf)?;
1711 Ok((Self::Ecc(point), rest))
1712 }
1713 TpmAlgId::Null => Ok((Self::Null, buf)),
1714 _ => Err(TpmErrorKind::InvalidValue),
1715 }
1716 }
1717}
1718
1719impl Default for TpmuPublicId {
1720 fn default() -> Self {
1721 Self::Null
1722 }
1723}
1724
1725#[derive(Debug, PartialEq, Eq, Clone)]
1726pub enum TpmuPublicParms {
1727 KeyedHash {
1728 details: TpmsKeyedhashParms,
1729 },
1730 SymCipher {
1731 details: TpmsSymcipherParms,
1732 },
1733 Rsa {
1734 symmetric: TpmtSymDefObject,
1735 scheme: TpmtScheme,
1736 key_bits: u16,
1737 exponent: u32,
1738 },
1739 Ecc {
1740 symmetric: TpmtSymDefObject,
1741 scheme: TpmtScheme,
1742 curve_id: TpmEccCurve,
1743 kdf: TpmtKdfScheme,
1744 },
1745 Null,
1746}
1747
1748impl TpmTagged for TpmuPublicParms {
1749 type Tag = TpmAlgId;
1750 type Value = ();
1751}
1752
1753impl TpmSized for TpmuPublicParms {
1754 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
1755 fn len(&self) -> usize {
1756 match self {
1757 Self::KeyedHash { details } => details.len(),
1758 Self::SymCipher { details } => details.len(),
1759 Self::Rsa {
1760 symmetric,
1761 scheme,
1762 key_bits,
1763 exponent,
1764 } => symmetric.len() + scheme.len() + key_bits.len() + exponent.len(),
1765 Self::Ecc {
1766 symmetric,
1767 scheme,
1768 curve_id,
1769 kdf,
1770 } => symmetric.len() + scheme.len() + curve_id.len() + kdf.len(),
1771 Self::Null => 0,
1772 }
1773 }
1774}
1775
1776impl TpmBuild for TpmuPublicParms {
1777 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1778 match self {
1779 TpmuPublicParms::KeyedHash { details } => details.build(writer),
1780 TpmuPublicParms::SymCipher { details } => details.build(writer),
1781 TpmuPublicParms::Rsa {
1782 symmetric,
1783 scheme,
1784 key_bits,
1785 exponent,
1786 } => {
1787 symmetric.build(writer)?;
1788 scheme.build(writer)?;
1789 key_bits.build(writer)?;
1790 exponent.build(writer)
1791 }
1792 TpmuPublicParms::Ecc {
1793 symmetric,
1794 scheme,
1795 curve_id,
1796 kdf,
1797 } => {
1798 symmetric.build(writer)?;
1799 scheme.build(writer)?;
1800 (*curve_id as u16).build(writer)?;
1801 kdf.build(writer)
1802 }
1803 TpmuPublicParms::Null => Ok(()),
1804 }
1805 }
1806}
1807
1808impl<'a> TpmParseTagged<'a> for TpmuPublicParms {
1809 fn parse_tagged(tag: TpmAlgId, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1816 match tag {
1817 TpmAlgId::KeyedHash => {
1818 let (details, buf) = TpmsKeyedhashParms::parse(buf)?;
1819 Ok((Self::KeyedHash { details }, buf))
1820 }
1821 TpmAlgId::SymCipher => {
1822 let (details, buf) = TpmsSymcipherParms::parse(buf)?;
1823 Ok((Self::SymCipher { details }, buf))
1824 }
1825 TpmAlgId::Rsa => {
1826 let (symmetric, buf) = TpmtSymDefObject::parse(buf)?;
1827 let (scheme, buf) = TpmtScheme::parse(buf)?;
1828 let (key_bits, buf) = u16::parse(buf)?;
1829 let (exponent, buf) = u32::parse(buf)?;
1830 Ok((
1831 Self::Rsa {
1832 symmetric,
1833 scheme,
1834 key_bits,
1835 exponent,
1836 },
1837 buf,
1838 ))
1839 }
1840 TpmAlgId::Ecc => {
1841 let (symmetric, buf) = TpmtSymDefObject::parse(buf)?;
1842 let (scheme, buf) = TpmtScheme::parse(buf)?;
1843 let (curve_id_raw, buf) = u16::parse(buf)?;
1844 let curve_id = TpmEccCurve::try_from(curve_id_raw).map_err(|()| {
1845 TpmErrorKind::InvalidDiscriminant {
1846 type_name: "TpmEccCurve",
1847 value: u64::from(curve_id_raw),
1848 }
1849 })?;
1850 let (kdf, buf) = TpmtKdfScheme::parse(buf)?;
1851 Ok((
1852 Self::Ecc {
1853 symmetric,
1854 scheme,
1855 curve_id,
1856 kdf,
1857 },
1858 buf,
1859 ))
1860 }
1861 TpmAlgId::Null => Ok((Self::Null, buf)),
1862 _ => Err(TpmErrorKind::InvalidValue),
1863 }
1864 }
1865}
1866
1867#[allow(clippy::large_enum_variant)]
1868#[derive(Debug, PartialEq, Eq, Clone)]
1869pub enum TpmuSensitiveComposite {
1870 Rsa(Tpm2bPrivateKeyRsa),
1871 Ecc(Tpm2bEccParameter),
1872 Bits(Tpm2bSensitiveData),
1873 Sym(Tpm2bSymKey),
1874}
1875
1876impl TpmTagged for TpmuSensitiveComposite {
1877 type Tag = TpmAlgId;
1878 type Value = ();
1879}
1880
1881impl Default for TpmuSensitiveComposite {
1882 fn default() -> Self {
1883 Self::Rsa(Tpm2bPrivateKeyRsa::default())
1884 }
1885}
1886
1887impl TpmSized for TpmuSensitiveComposite {
1888 const SIZE: usize = TPM_MAX_COMMAND_SIZE;
1889 fn len(&self) -> usize {
1890 match self {
1891 Self::Rsa(val) => val.len(),
1892 Self::Ecc(val) => val.len(),
1893 Self::Bits(val) => val.len(),
1894 Self::Sym(val) => val.len(),
1895 }
1896 }
1897}
1898
1899impl TpmBuild for TpmuSensitiveComposite {
1900 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1901 match self {
1902 TpmuSensitiveComposite::Rsa(val) => val.build(writer),
1903 TpmuSensitiveComposite::Ecc(val) => val.build(writer),
1904 TpmuSensitiveComposite::Bits(val) => val.build(writer),
1905 TpmuSensitiveComposite::Sym(val) => val.build(writer),
1906 }
1907 }
1908}
1909
1910impl<'a> TpmParseTagged<'a> for TpmuSensitiveComposite {
1911 fn parse_tagged(tag: TpmAlgId, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1919 match tag {
1920 TpmAlgId::Rsa => {
1921 let (val, buf) = Tpm2bPrivateKeyRsa::parse(buf)?;
1922 Ok((Self::Rsa(val), buf))
1923 }
1924 TpmAlgId::Ecc => {
1925 let (val, buf) = Tpm2bEccParameter::parse(buf)?;
1926 Ok((Self::Ecc(val), buf))
1927 }
1928 TpmAlgId::KeyedHash => {
1929 let (val, buf) = Tpm2bSensitiveData::parse(buf)?;
1930 Ok((Self::Bits(val), buf))
1931 }
1932 TpmAlgId::SymCipher => {
1933 let (val, buf) = Tpm2bSymKey::parse(buf)?;
1934 Ok((Self::Sym(val), buf))
1935 }
1936 _ => Err(TpmErrorKind::InvalidValue),
1937 }
1938 }
1939}
1940
1941#[derive(Debug, PartialEq, Eq, Clone, Copy)]
1942pub enum TpmuSymKeyBits {
1943 Aes(u16),
1944 Sm4(u16),
1945 Camellia(u16),
1946 Null,
1947}
1948
1949impl TpmTagged for TpmuSymKeyBits {
1950 type Tag = TpmAlgId;
1951 type Value = ();
1952}
1953
1954impl Default for TpmuSymKeyBits {
1955 fn default() -> Self {
1956 Self::Null
1957 }
1958}
1959
1960impl TpmSized for TpmuSymKeyBits {
1961 const SIZE: usize = core::mem::size_of::<u16>();
1962 fn len(&self) -> usize {
1963 match self {
1964 Self::Aes(val) | Self::Sm4(val) | Self::Camellia(val) => val.len(),
1965 Self::Null => 0,
1966 }
1967 }
1968}
1969
1970impl<'a> TpmParseTagged<'a> for TpmuSymKeyBits {
1971 fn parse_tagged(tag: TpmAlgId, buf: &'a [u8]) -> TpmResult<(Self, &'a [u8])> {
1978 match tag {
1979 TpmAlgId::Aes => {
1980 let (val, buf) = u16::parse(buf)?;
1981 Ok((Self::Aes(val), buf))
1982 }
1983 TpmAlgId::Sm4 => {
1984 let (val, buf) = u16::parse(buf)?;
1985 Ok((Self::Sm4(val), buf))
1986 }
1987 TpmAlgId::Camellia => {
1988 let (val, buf) = u16::parse(buf)?;
1989 Ok((Self::Camellia(val), buf))
1990 }
1991 TpmAlgId::Null => Ok((Self::Null, buf)),
1992 _ => Err(TpmErrorKind::InvalidValue),
1993 }
1994 }
1995}
1996
1997impl TpmBuild for TpmuSymKeyBits {
1998 fn build(&self, writer: &mut TpmWriter) -> TpmResult<()> {
1999 match self {
2000 TpmuSymKeyBits::Aes(val) | TpmuSymKeyBits::Sm4(val) | TpmuSymKeyBits::Camellia(val) => {
2001 val.build(writer)
2002 }
2003 TpmuSymKeyBits::Null => Ok(()),
2004 }
2005 }
2006}
2007
2008tpm2b_struct!(
2009 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2010 Tpm2bPublic,
2011 TpmtPublic
2012);
2013tpm2b_struct!(
2014 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2015 Tpm2bTemplate,
2016 TpmtPublic
2017);
2018tpm2b_struct!(
2019 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2020 Tpm2bSensitive,
2021 TpmtSensitive
2022);
2023tpm2b_struct!(
2024 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2025 Tpm2bSensitiveCreate,
2026 TpmsSensitiveCreate
2027);
2028tpm2b_struct!(
2029 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2030 Tpm2bAttest,
2031 TpmsAttest
2032);
2033tpm2b_struct!(
2034 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2035 Tpm2bContextData,
2036 TpmsContextData
2037);
2038tpm2b_struct!(
2039 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2040 Tpm2bCreationData,
2041 TpmsCreationData
2042);
2043tpm2b_struct!(
2044 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2045 Tpm2bEccPoint,
2046 TpmsEccPoint
2047);
2048tpm2b_struct!(
2049 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2050 Tpm2bIdObject,
2051 TpmsIdObject
2052);
2053tpm2b_struct!(
2054 #[derive(Debug, PartialEq, Eq, Clone, Default)]
2055 Tpm2bNvPublic,
2056 TpmsNvPublic
2057);