tss_esapi/constants/
response_code.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Module for error types
5//!
6//! This module provides the error reporting framework for the crate. Error provenience is marked
7//! as a variant of an enum, distinguishing between errors coming from the TSS stack and those
8//! generated by this crate.
9use crate::tss2_esys::TSS2_RC;
10use bitfield::bitfield;
11
12bitfield! {
13    pub struct ResponseCode(TSS2_RC);
14    impl Debug;
15    format_selector, _: 7;
16}
17
18bitfield! {
19    #[derive(PartialEq, Eq, Copy, Clone)]
20    pub struct FormatZeroResponseCode(TSS2_RC);
21    impl Debug;
22    error_number, _: 6, 0;
23    format_selector, _: 7;
24    version, _: 8;
25    tcg_vendor_indicator, _: 10;
26    severity, _: 11;
27}
28
29impl std::fmt::Display for FormatZeroResponseCode {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        // Display response code as "Response code value: 0xdeadbeef"
32        write!(f, "Response code value: {:#x}", self.0)
33    }
34}
35
36impl std::error::Error for FormatZeroResponseCode {}
37
38bitfield! {
39    #[derive(PartialEq, Eq, Copy, Clone)]
40    pub struct FormatOneResponseCode(TSS2_RC);
41    impl Debug;
42    error_number, _: 5, 0;
43    parameter, _: 6;
44    format_selector, _: 7;
45    number, _: 11, 8;
46}
47
48impl std::fmt::Display for FormatOneResponseCode {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        // Display response code as "Response code value: 0xdeadbeef"
51        write!(f, "Response code value: {:#x}", self.0)
52    }
53}
54
55impl std::error::Error for FormatOneResponseCode {}
56
57/// Rust native representation of the TSS2 response codes as defined in the spec.
58#[allow(clippy::module_name_repetitions)]
59#[derive(Copy, Clone, PartialEq, Eq, Debug)]
60pub enum Tss2ResponseCode {
61    Success,
62    FormatZero(FormatZeroResponseCode),
63    FormatOne(FormatOneResponseCode),
64}
65
66impl Tss2ResponseCode {
67    /// Generate a `Tss2ResponseCode` from a TSS error
68    pub(crate) fn from_tss_rc(response_code: TSS2_RC) -> Self {
69        if response_code == 0 {
70            Tss2ResponseCode::Success
71        } else if ResponseCode(response_code).format_selector() {
72            // The response code is in Format-One.
73            Tss2ResponseCode::FormatOne(FormatOneResponseCode(response_code))
74        } else {
75            // The response code is in Format-Zero.
76            Tss2ResponseCode::FormatZero(FormatZeroResponseCode(response_code))
77        }
78    }
79
80    /// Check whether the response code is successful
81    pub fn is_success(self) -> bool {
82        self == Tss2ResponseCode::Success
83    }
84
85    fn is_warning(self) -> bool {
86        match self {
87            Tss2ResponseCode::Success => false,
88            Tss2ResponseCode::FormatZero(rc) => rc.severity(),
89            Tss2ResponseCode::FormatOne(_) => false,
90        }
91    }
92
93    fn error_number(self) -> u32 {
94        match self {
95            Tss2ResponseCode::Success => 0,
96            Tss2ResponseCode::FormatZero(rc) => rc.error_number(),
97            Tss2ResponseCode::FormatOne(rc) => rc.error_number(),
98        }
99    }
100
101    fn get_associated_number_message(self) -> String {
102        if let Tss2ResponseCode::FormatOne(rc) = self {
103            if rc.parameter() {
104                format!("associated with parameter number {}", rc.number())
105            } else if rc.number() <= 0b0111 {
106                format!("associated with handle number {}", rc.number())
107            } else {
108                format!("associated with session number {}", rc.number() - 8)
109            }
110        } else {
111            String::from("no associated message")
112        }
113    }
114
115    /// Get the error code as an enum variant.
116    pub fn kind(self) -> Option<Tss2ResponseCodeKind> {
117        match self {
118            Tss2ResponseCode::Success => Some(Tss2ResponseCodeKind::Success),
119            Tss2ResponseCode::FormatZero(rc) => {
120                if rc.tcg_vendor_indicator() {
121                    Some(Tss2ResponseCodeKind::TpmVendorSpecific)
122                } else if self.is_warning() {
123                    // Warnings
124                    match self.error_number() {
125                        0x001 => Some(Tss2ResponseCodeKind::ContextGap),
126                        0x002 => Some(Tss2ResponseCodeKind::ObjectMemory),
127                        0x003 => Some(Tss2ResponseCodeKind::SessionMemory),
128                        0x004 => Some(Tss2ResponseCodeKind::Memory),
129                        0x005 => Some(Tss2ResponseCodeKind::SessionHandles),
130                        0x006 => Some(Tss2ResponseCodeKind::ObjectHandles),
131                        0x007 => Some(Tss2ResponseCodeKind::Locality),
132                        0x008 => Some(Tss2ResponseCodeKind::Yielded),
133                        0x009 => Some(Tss2ResponseCodeKind::Canceled),
134                        0x00A => Some(Tss2ResponseCodeKind::Testing),
135                        0x010 => Some(Tss2ResponseCodeKind::ReferenceH0),
136                        0x011 => Some(Tss2ResponseCodeKind::ReferenceH1),
137                        0x012 => Some(Tss2ResponseCodeKind::ReferenceH2),
138                        0x013 => Some(Tss2ResponseCodeKind::ReferenceH3),
139                        0x014 => Some(Tss2ResponseCodeKind::ReferenceH4),
140                        0x015 => Some(Tss2ResponseCodeKind::ReferenceH5),
141                        0x016 => Some(Tss2ResponseCodeKind::ReferenceH6),
142                        0x018 => Some(Tss2ResponseCodeKind::ReferenceS0),
143                        0x019 => Some(Tss2ResponseCodeKind::ReferenceS1),
144                        0x01A => Some(Tss2ResponseCodeKind::ReferenceS2),
145                        0x01B => Some(Tss2ResponseCodeKind::ReferenceS3),
146                        0x01C => Some(Tss2ResponseCodeKind::ReferenceS4),
147                        0x01D => Some(Tss2ResponseCodeKind::ReferenceS5),
148                        0x01E => Some(Tss2ResponseCodeKind::ReferenceS6),
149                        0x020 => Some(Tss2ResponseCodeKind::NvRate),
150                        0x021 => Some(Tss2ResponseCodeKind::Lockout),
151                        0x022 => Some(Tss2ResponseCodeKind::Retry),
152                        0x023 => Some(Tss2ResponseCodeKind::NvUnavailable),
153                        _ => None,
154                    }
155                } else {
156                    // Errors
157                    match self.error_number() {
158                        0x000 => Some(Tss2ResponseCodeKind::Initialize),
159                        0x001 => Some(Tss2ResponseCodeKind::Failure),
160                        0x003 => Some(Tss2ResponseCodeKind::Sequence),
161                        0x00B => Some(Tss2ResponseCodeKind::Private),
162                        0x019 => Some(Tss2ResponseCodeKind::Hmac),
163                        0x020 => Some(Tss2ResponseCodeKind::Disabled),
164                        0x021 => Some(Tss2ResponseCodeKind::Exclusive),
165                        0x024 => Some(Tss2ResponseCodeKind::AuthType),
166                        0x025 => Some(Tss2ResponseCodeKind::AuthMissing),
167                        0x026 => Some(Tss2ResponseCodeKind::Policy),
168                        0x027 => Some(Tss2ResponseCodeKind::Pcr),
169                        0x028 => Some(Tss2ResponseCodeKind::PcrChanged),
170                        0x02D => Some(Tss2ResponseCodeKind::Upgrade),
171                        0x02E => Some(Tss2ResponseCodeKind::TooManyContexts),
172                        0x02F => Some(Tss2ResponseCodeKind::AuthUnavailable),
173                        0x030 => Some(Tss2ResponseCodeKind::Reboot),
174                        0x031 => Some(Tss2ResponseCodeKind::Unbalanced),
175                        0x042 => Some(Tss2ResponseCodeKind::CommandSize),
176                        0x043 => Some(Tss2ResponseCodeKind::CommandCode),
177                        0x044 => Some(Tss2ResponseCodeKind::AuthSize),
178                        0x045 => Some(Tss2ResponseCodeKind::AuthContext),
179                        0x046 => Some(Tss2ResponseCodeKind::NvRange),
180                        0x047 => Some(Tss2ResponseCodeKind::NvSize),
181                        0x048 => Some(Tss2ResponseCodeKind::NvLocked),
182                        0x049 => Some(Tss2ResponseCodeKind::NvAuthorization),
183                        0x04A => Some(Tss2ResponseCodeKind::NvUninitialized),
184                        0x04B => Some(Tss2ResponseCodeKind::NvSpace),
185                        0x04C => Some(Tss2ResponseCodeKind::NvDefined),
186                        0x050 => Some(Tss2ResponseCodeKind::BadContext),
187                        0x051 => Some(Tss2ResponseCodeKind::CpHash),
188                        0x052 => Some(Tss2ResponseCodeKind::Parent),
189                        0x053 => Some(Tss2ResponseCodeKind::NeedsTest),
190                        0x054 => Some(Tss2ResponseCodeKind::NoResult),
191                        0x055 => Some(Tss2ResponseCodeKind::Sensitive),
192                        _ => None,
193                    }
194                }
195            }
196            Tss2ResponseCode::FormatOne(_) => match self.error_number() {
197                0x001 => Some(Tss2ResponseCodeKind::Asymmetric),
198                0x002 => Some(Tss2ResponseCodeKind::Attributes),
199                0x003 => Some(Tss2ResponseCodeKind::Hash),
200                0x004 => Some(Tss2ResponseCodeKind::Value),
201                0x005 => Some(Tss2ResponseCodeKind::Hierarchy),
202                0x007 => Some(Tss2ResponseCodeKind::KeySize),
203                0x008 => Some(Tss2ResponseCodeKind::Mgf),
204                0x009 => Some(Tss2ResponseCodeKind::Mode),
205                0x00A => Some(Tss2ResponseCodeKind::Type),
206                0x00B => Some(Tss2ResponseCodeKind::Handle),
207                0x00C => Some(Tss2ResponseCodeKind::Kdf),
208                0x00D => Some(Tss2ResponseCodeKind::Range),
209                0x00E => Some(Tss2ResponseCodeKind::AuthFail),
210                0x00F => Some(Tss2ResponseCodeKind::Nonce),
211                0x010 => Some(Tss2ResponseCodeKind::Pp),
212                0x012 => Some(Tss2ResponseCodeKind::Scheme),
213                0x015 => Some(Tss2ResponseCodeKind::Size),
214                0x016 => Some(Tss2ResponseCodeKind::Symmetric),
215                0x017 => Some(Tss2ResponseCodeKind::Tag),
216                0x018 => Some(Tss2ResponseCodeKind::Selector),
217                0x01A => Some(Tss2ResponseCodeKind::Insufficient),
218                0x01B => Some(Tss2ResponseCodeKind::Signature),
219                0x01C => Some(Tss2ResponseCodeKind::Key),
220                0x01D => Some(Tss2ResponseCodeKind::PolicyFail),
221                0x01F => Some(Tss2ResponseCodeKind::Integrity),
222                0x020 => Some(Tss2ResponseCodeKind::Ticket),
223                0x021 => Some(Tss2ResponseCodeKind::ReservedBits),
224                0x022 => Some(Tss2ResponseCodeKind::BadAuth),
225                0x023 => Some(Tss2ResponseCodeKind::Expired),
226                0x024 => Some(Tss2ResponseCodeKind::PolicyCc),
227                0x025 => Some(Tss2ResponseCodeKind::Binding),
228                0x026 => Some(Tss2ResponseCodeKind::Curve),
229                0x027 => Some(Tss2ResponseCodeKind::EccPoint),
230                _ => None,
231            },
232        }
233    }
234}
235
236/// Rust enum representation of TSS 2 error codes.
237#[derive(PartialEq, Eq, Copy, Clone, Debug)]
238pub enum Tss2ResponseCodeKind {
239    // FormatZero errors
240    Success,
241    TpmVendorSpecific,
242    Initialize,
243    Failure,
244    Sequence,
245    Private,
246    Hmac,
247    Disabled,
248    Exclusive,
249    AuthType,
250    AuthMissing,
251    Policy,
252    Pcr,
253    PcrChanged,
254    Upgrade,
255    TooManyContexts,
256    AuthUnavailable,
257    Reboot,
258    Unbalanced,
259    CommandSize,
260    CommandCode,
261    AuthSize,
262    AuthContext,
263    NvRange,
264    NvSize,
265    NvLocked,
266    NvAuthorization,
267    NvUninitialized,
268    NvSpace,
269    NvDefined,
270    BadContext,
271    CpHash,
272    Parent,
273    NeedsTest,
274    NoResult,
275    Sensitive,
276    // FormatOne errors
277    Asymmetric,
278    Attributes,
279    Hash,
280    Value,
281    Hierarchy,
282    KeySize,
283    Mgf,
284    Mode,
285    Type,
286    Handle,
287    Kdf,
288    Range,
289    AuthFail,
290    Nonce,
291    Pp,
292    Scheme,
293    Size,
294    Symmetric,
295    Tag,
296    Selector,
297    Insufficient,
298    Signature,
299    Key,
300    PolicyFail,
301    Integrity,
302    Ticket,
303    ReservedBits,
304    BadAuth,
305    Expired,
306    PolicyCc,
307    Binding,
308    Curve,
309    EccPoint,
310    // Warnings
311    ContextGap,
312    ObjectMemory,
313    SessionMemory,
314    Memory,
315    SessionHandles,
316    ObjectHandles,
317    Locality,
318    Yielded,
319    Canceled,
320    Testing,
321    ReferenceH0,
322    ReferenceH1,
323    ReferenceH2,
324    ReferenceH3,
325    ReferenceH4,
326    ReferenceH5,
327    ReferenceH6,
328    ReferenceS0,
329    ReferenceS1,
330    ReferenceS2,
331    ReferenceS3,
332    ReferenceS4,
333    ReferenceS5,
334    ReferenceS6,
335    NvRate,
336    Lockout,
337    Retry,
338    NvUnavailable,
339}
340
341impl std::fmt::Display for Tss2ResponseCode {
342    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343        let kind = self.kind();
344        if kind.is_none() {
345            return write!(f, "response code not recognized");
346        }
347        match self.kind().unwrap() { // should not panic, given the check above
348            Tss2ResponseCodeKind::Success => write!(f, "success"),
349            Tss2ResponseCodeKind::TpmVendorSpecific => write!(f, "vendor specific error: {}", self.error_number()),
350            // Format Zero
351            Tss2ResponseCodeKind::Initialize => write!(f, "TPM not initialized by TPM2_Startup or already initialized"),
352            Tss2ResponseCodeKind::Failure => write!(f, "commands not being accepted because of a TPM failure. NOTE: This may be returned by TPM2_GetTestResult() as the testResultparameter"),
353            Tss2ResponseCodeKind::Sequence => write!(f, "improper use of a sequence handle"),
354            Tss2ResponseCodeKind::Private => write!(f, "not currently used"),
355            Tss2ResponseCodeKind::Hmac => write!(f, "not currently used"),
356            Tss2ResponseCodeKind::Disabled => write!(f, "the command is disabled"),
357            Tss2ResponseCodeKind::Exclusive => write!(f, "command failed because audit sequence required exclusivity"),
358            Tss2ResponseCodeKind::AuthType => write!(f, "authorization handle is not correct for command"),
359            Tss2ResponseCodeKind::AuthMissing => write!(f, "command requires an authorization session for handle and it is not present"),
360            Tss2ResponseCodeKind::Policy => write!(f, "policy failure in math operation or an invalid authPolicy value"),
361            Tss2ResponseCodeKind::Pcr => write!(f, "PCR check fail"),
362            Tss2ResponseCodeKind::PcrChanged => write!(f, "PCR have changed since checked"),
363            Tss2ResponseCodeKind::Upgrade => write!(f, "for all commands other than TPM2_FieldUpgradeData(), this code indicates that the TPM is in field upgrade mode; for TPM2_FieldUpgradeData(), this code indicates that the TPM is not in field upgrade mode"),
364            Tss2ResponseCodeKind::TooManyContexts => write!(f, "context ID counter is at maximum"),
365            Tss2ResponseCodeKind::AuthUnavailable => write!(f, "authValue or authPolicy is not available for selected entity"),
366            Tss2ResponseCodeKind::Reboot => write!(f, "a _TPM_Init and Startup(CLEAR) is required before the TPM can resume operation"),
367            Tss2ResponseCodeKind::Unbalanced => write!(f, "the protection algorithms (hash and symmetric) are not reasonably balanced. The digest size of the hash must be larger than the key size of the symmetric algorithm"),
368            Tss2ResponseCodeKind::CommandSize => write!(f, "command commandSizevalue is inconsistent with contents of the command buffer; either the size is not the same as the octets loaded by the hardware interface layer or the value is not large enough to hold a command header"),
369            Tss2ResponseCodeKind::CommandCode => write!(f, "command code not supported"),
370            Tss2ResponseCodeKind::AuthSize => write!(f, "the value of authorizationSizeis out of range or the number of octets in the Authorization Area is greater than required"),
371            Tss2ResponseCodeKind::AuthContext => write!(f, "use of an authorization session with a context command or another command that cannot have an authorization session"),
372            Tss2ResponseCodeKind::NvRange => write!(f, "NV offset+size is out of range"),
373            Tss2ResponseCodeKind::NvSize => write!(f, "Requested allocation size is larger than allowed"),
374            Tss2ResponseCodeKind::NvLocked => write!(f, "NV access locked"),
375            Tss2ResponseCodeKind::NvAuthorization => write!(f, "NV access authorization fails in command actions (this failure does not affect lockout.action)"),
376            Tss2ResponseCodeKind::NvUninitialized => write!(f, "an NV Index is used before being initialized or the state saved by TPM2_Shutdown(STATE) could not be restored"),
377            Tss2ResponseCodeKind::NvSpace => write!(f, "insufficient space for NV allocation"),
378            Tss2ResponseCodeKind::NvDefined => write!(f, "NV Index or persistent object already defined"),
379            Tss2ResponseCodeKind::BadContext => write!(f, "context in TPM2_ContextLoad() is not valid"),
380            Tss2ResponseCodeKind::CpHash => write!(f, "cpHash value already set or not correct for use"),
381            Tss2ResponseCodeKind::Parent => write!(f, "handle for parent is not a valid parent"),
382            Tss2ResponseCodeKind::NeedsTest => write!(f, "some function needs testing."),
383            Tss2ResponseCodeKind::NoResult => write!(f, "returned when an internal function cannot process a request due to an unspecified problem. This code is usually related to invalid parameters that are not properly filtered by the input unmarshaling code."),
384            Tss2ResponseCodeKind::Sensitive => write!(f, "the sensitive area did not unmarshal correctly after decryption – this code is used in lieu of the other unmarshaling errors so that an attacker cannot determine where the unmarshaling error occurred"),
385            // Warnings
386            Tss2ResponseCodeKind::ContextGap => write!(f, "gap for context ID is too large"),
387            Tss2ResponseCodeKind::ObjectMemory => write!(f, "out of memory for object contexts"),
388            Tss2ResponseCodeKind::SessionMemory => write!(f, "out of memory for session contexts"),
389            Tss2ResponseCodeKind::Memory => write!(f, "out of shared object/session memory or need space for internal operations"),
390            Tss2ResponseCodeKind::SessionHandles => write!(f, "out of session handles – a session must be flushed before a new session may be created"),
391            Tss2ResponseCodeKind::ObjectHandles => write!(f, "out of object handles – the handle space for objects is depleted and a reboot is required. NOTE 1: This cannot occur on the reference implementation. NOTE 2: There is no reason why an implementation would implement a design that would delete handle space. Platform specifications are encouraged to forbid it."),
392            Tss2ResponseCodeKind::Locality => write!(f, "bad locality"),
393            Tss2ResponseCodeKind::Yielded => write!(f, "the TPM has suspended operation on the command; forward progress was made and the command may be retried. See TPM 2.0 Part 1, “Multi-tasking.” NOTE: This cannot occur on the reference implementation."),
394            Tss2ResponseCodeKind::Canceled => write!(f, "the command was canceled"),
395            Tss2ResponseCodeKind::Testing => write!(f, "TPM is performing self-tests"),
396            Tss2ResponseCodeKind::ReferenceH0 => write!(f, "the 1st handle in the handle area references a transient object or session that is not loaded"),
397            Tss2ResponseCodeKind::ReferenceH1 => write!(f, "the 2nd handle in the handle area references a transient object or session that is not loaded"),
398            Tss2ResponseCodeKind::ReferenceH2 => write!(f, "the 3rd handle in the handle area references a transient object or session that is not loaded"),
399            Tss2ResponseCodeKind::ReferenceH3 => write!(f, "the 4th handle in the handle area references a transient object or session that is not loaded"),
400            Tss2ResponseCodeKind::ReferenceH4 => write!(f, "the 5th handle in the handle area references a transient object or session that is not loaded"),
401            Tss2ResponseCodeKind::ReferenceH5 => write!(f, "the 6th handle in the handle area references a transient object or session that is not loaded"),
402            Tss2ResponseCodeKind::ReferenceH6 => write!(f, "the 7th handle in the handle area references a transient object or session that is not loaded"),
403            Tss2ResponseCodeKind::ReferenceS0 => write!(f, "the 1st authorization session handle references a session that is not loaded"),
404            Tss2ResponseCodeKind::ReferenceS1 => write!(f, "the 2nd authorization session handle references a session that is not loaded"),
405            Tss2ResponseCodeKind::ReferenceS2 => write!(f, "the 3rd authorization session handle references a session that is not loaded"),
406            Tss2ResponseCodeKind::ReferenceS3 => write!(f, "the 4th authorization session handle references a session that is not loaded"),
407            Tss2ResponseCodeKind::ReferenceS4 => write!(f, "the 5th session handle references a session that is not loaded"),
408            Tss2ResponseCodeKind::ReferenceS5 => write!(f, "the 6th session handle references a session that is not loaded"),
409            Tss2ResponseCodeKind::ReferenceS6 => write!(f, "the 7th authorization session handle references a session that is not loaded"),
410            Tss2ResponseCodeKind::NvRate => write!(f, "the TPM is rate-limiting accesses to prevent wearout of NV"),
411            Tss2ResponseCodeKind::Lockout => write!(f, "authorizations for objects subject to DA protection are not allowed at this time because the TPM is in DA lockout mode"),
412            Tss2ResponseCodeKind::Retry => write!(f, "the TPM was not able to start the command"),
413            Tss2ResponseCodeKind::NvUnavailable => write!(f, "the command may require writing of NV and NV is not current accessible"),
414            // Format-One
415            Tss2ResponseCodeKind::Asymmetric => write!(f, "asymmetric algorithm not supported or not correct ({})", self.get_associated_number_message()),
416            Tss2ResponseCodeKind::Attributes => write!(f, "inconsistent attributes ({})", self.get_associated_number_message()),
417            Tss2ResponseCodeKind::Hash => write!(f, "hash algorithm not supported or not appropriate ({})", self.get_associated_number_message()),
418            Tss2ResponseCodeKind::Value => write!(f, "value is out of range or is not correct for the context ({})", self.get_associated_number_message()),
419            Tss2ResponseCodeKind::Hierarchy => write!(f, "hierarchy is not enabled or is not correct for the use ({})", self.get_associated_number_message()),
420            Tss2ResponseCodeKind::KeySize => write!(f, "key size is not supported ({})", self.get_associated_number_message()),
421            Tss2ResponseCodeKind::Mgf => write!(f, "mask generation function not supported ({})", self.get_associated_number_message()),
422            Tss2ResponseCodeKind::Mode => write!(f, "mode of operation not supported ({})", self.get_associated_number_message()),
423            Tss2ResponseCodeKind::Type => write!(f, "the type of the value is not appropriate for the use ({})", self.get_associated_number_message()),
424            Tss2ResponseCodeKind::Handle => write!(f, "the handle is not correct for the use ({})", self.get_associated_number_message()),
425            Tss2ResponseCodeKind::Kdf => write!(f, "unsupported key derivation function or function not appropriate for use ({})", self.get_associated_number_message()),
426            Tss2ResponseCodeKind::Range => write!(f, "value was out of allowed range. ({})", self.get_associated_number_message()),
427            Tss2ResponseCodeKind::AuthFail => write!(f, "the authorization HMAC check failed and DA counter incremented ({})", self.get_associated_number_message()),
428            Tss2ResponseCodeKind::Nonce => write!(f, "invalid nonce size or nonce value mismatch ({})", self.get_associated_number_message()),
429            Tss2ResponseCodeKind::Pp => write!(f, "authorization requires assertion of PP ({})", self.get_associated_number_message()),
430            Tss2ResponseCodeKind::Scheme => write!(f, "unsupported or incompatible scheme ({})", self.get_associated_number_message()),
431            Tss2ResponseCodeKind::Size => write!(f, "structure is the wrong size ({})", self.get_associated_number_message()),
432            Tss2ResponseCodeKind::Symmetric => write!(f, "unsupported symmetric algorithm or key size, or not appropriate for instance ({})", self.get_associated_number_message()),
433            Tss2ResponseCodeKind::Tag => write!(f, "incorrect structure tag ({})", self.get_associated_number_message()),
434            Tss2ResponseCodeKind::Selector => write!(f, "union selector is incorrect ({})", self.get_associated_number_message()),
435            Tss2ResponseCodeKind::Insufficient => write!(f, "the TPM was unable to unmarshal a value because there were not enough octets in the input buffer ({})", self.get_associated_number_message()),
436            Tss2ResponseCodeKind::Signature => write!(f, "the signature is not valid ({})", self.get_associated_number_message()),
437            Tss2ResponseCodeKind::Key => write!(f, "key fields are not compatible with the selected use ({})", self.get_associated_number_message()),
438            Tss2ResponseCodeKind::PolicyFail => write!(f, "a policy check failed ({})", self.get_associated_number_message()),
439            Tss2ResponseCodeKind::Integrity => write!(f, "integrity check failed ({})", self.get_associated_number_message()),
440            Tss2ResponseCodeKind::Ticket => write!(f, "invalid ticket  ({})", self.get_associated_number_message()),
441            Tss2ResponseCodeKind::ReservedBits => write!(f, "reserved bits not set to zero as required ({})", self.get_associated_number_message()),
442            Tss2ResponseCodeKind::BadAuth => write!(f, "authorization failure without DA implications ({})", self.get_associated_number_message()),
443            Tss2ResponseCodeKind::Expired => write!(f, "the policy has expired ({})", self.get_associated_number_message()),
444            Tss2ResponseCodeKind::PolicyCc => write!(f, "the command Code in the policy is not the command Code of the command or the command code in a policy command references a command that is not implemented ({})", self.get_associated_number_message()),
445            Tss2ResponseCodeKind::Binding => write!(f, "public and sensitive portions of an object are not cryptographically bound ({})", self.get_associated_number_message()),
446            Tss2ResponseCodeKind::Curve => write!(f, "curve not supported ({})", self.get_associated_number_message()),
447            Tss2ResponseCodeKind::EccPoint => write!(f, "point is not on the required curve ({})", self.get_associated_number_message()),
448        }
449    }
450}
451
452impl From<TSS2_RC> for Tss2ResponseCode {
453    fn from(rc: TSS2_RC) -> Self {
454        Tss2ResponseCode::from_tss_rc(rc)
455    }
456}
457
458impl std::error::Error for Tss2ResponseCode {
459    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
460        match self {
461            Tss2ResponseCode::FormatOne(response_code) => Some(response_code),
462            Tss2ResponseCode::FormatZero(response_code) => Some(response_code),
463            Tss2ResponseCode::Success => None,
464        }
465    }
466}