1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// SPDX-License-Identifier: MIT

#![deny(clippy::all)]
#![deny(clippy::pedantic)]

use core::convert::TryFrom;
use core::fmt;
use core::option::Option;
use strum_macros::FromRepr;

pub const RC_VER1: u16 = 0x0100;
pub const RC_FMT1: u16 = 0x0080;
pub const RC_WARN: u16 = 0x0900;

#[derive(FromRepr, Debug, PartialEq)]
#[repr(u16)]
pub enum ReturnCode {
    Success = 0x0000,
    BadTag = 0x001E,
    Initialize = RC_VER1,
    Failure = RC_VER1 + 0x001,
    Sequence = RC_VER1 + 0x003,
    Private = RC_VER1 + 0x00B,
    Hmac = RC_VER1 + 0x019,
    Disabled = RC_VER1 + 0x020,
    Exclusive = RC_VER1 + 0x021,
    AuthType = RC_VER1 + 0x024,
    AuthMissing = RC_VER1 + 0x025,
    Policy = RC_VER1 + 0x026,
    Pcr = RC_VER1 + 0x027,
    PcrChanged = RC_VER1 + 0x028,
    Upgrade = RC_VER1 + 0x02D,
    TooManyContexts = RC_VER1 + 0x02E,
    AuthUnavailable = RC_VER1 + 0x02F,
    Reboot = RC_VER1 + 0x030,
    Unbalanced = RC_VER1 + 0x031,
    CommandSize = RC_VER1 + 0x042,
    CommandCode = RC_VER1 + 0x043,
    AuthSize = RC_VER1 + 0x044,
    AuthContext = RC_VER1 + 0x045,
    NvRange = RC_VER1 + 0x046,
    NvSize = RC_VER1 + 0x047,
    NvLocked = RC_VER1 + 0x048,
    NvAuthorization = RC_VER1 + 0x049,
    NvUninitialized = RC_VER1 + 0x04A,
    NvSpace = RC_VER1 + 0x04B,
    NvDefined = RC_VER1 + 0x04C,
    BadContext = RC_VER1 + 0x050,
    CpHash = RC_VER1 + 0x051,
    Parent = RC_VER1 + 0x052,
    NeedsTest = RC_VER1 + 0x053,
    NoResult = RC_VER1 + 0x054,
    Sensitive = RC_VER1 + 0x055,
    Asymmetric = RC_FMT1 + 0x001,
    Attributes = RC_FMT1 + 0x002,
    Hash = RC_FMT1 + 0x003,
    Value = RC_FMT1 + 0x004,
    Hierarchy = RC_FMT1 + 0x005,
    KeySize = RC_FMT1 + 0x007,
    Mgf = RC_FMT1 + 0x008,
    Mode = RC_FMT1 + 0x009,
    Type = RC_FMT1 + 0x00A,
    Handle = RC_FMT1 + 0x00B,
    Kdf = RC_FMT1 + 0x00C,
    Range = RC_FMT1 + 0x00D,
    AuthFail = RC_FMT1 + 0x00E,
    Nonce = RC_FMT1 + 0x00F,
    Pp = RC_FMT1 + 0x010,
    Scheme = RC_FMT1 + 0x012,
    Size = RC_FMT1 + 0x015,
    Symmetric = RC_FMT1 + 0x016,
    Tag = RC_FMT1 + 0x017,
    Selector = RC_FMT1 + 0x018,
    Insufficient = RC_FMT1 + 0x01A,
    Signature = RC_FMT1 + 0x01B,
    Key = RC_FMT1 + 0x01C,
    PolicyFail = RC_FMT1 + 0x01D,
    Integrity = RC_FMT1 + 0x01F,
    Ticket = RC_FMT1 + 0x020,
    ReservedBits = RC_FMT1 + 0x021,
    BadAuth = RC_FMT1 + 0x022,
    Expired = RC_FMT1 + 0x023,
    PolicyCc = RC_FMT1 + 0x024,
    Binding = RC_FMT1 + 0x025,
    Curve = RC_FMT1 + 0x026,
    EccPoint = RC_FMT1 + 0x027,
    ContextGap = RC_WARN + 0x001,
    ObjectMemory = RC_WARN + 0x002,
    SessionMemory = RC_WARN + 0x003,
    Memory = RC_WARN + 0x004,
    SessionHandles = RC_WARN + 0x005,
    ObjectHandles = RC_WARN + 0x006,
    Locality = RC_WARN + 0x007,
    Yielded = RC_WARN + 0x008,
    Canceled = RC_WARN + 0x009,
    Testing = RC_WARN + 0x00A,
    ReferenceH0 = RC_WARN + 0x010,
    ReferenceH1 = RC_WARN + 0x011,
    ReferenceH2 = RC_WARN + 0x012,
    ReferenceH3 = RC_WARN + 0x013,
    ReferenceH4 = RC_WARN + 0x014,
    ReferenceH5 = RC_WARN + 0x015,
    ReferenceH6 = RC_WARN + 0x016,
    ReferenceS0 = RC_WARN + 0x018,
    ReferenceS1 = RC_WARN + 0x019,
    ReferenceS2 = RC_WARN + 0x01A,
    ReferenceS3 = RC_WARN + 0x01B,
    ReferenceS4 = RC_WARN + 0x01C,
    ReferenceS5 = RC_WARN + 0x01D,
    ReferenceS6 = RC_WARN + 0x01E,
    NvRate = RC_WARN + 0x020,
    Lockout = RC_WARN + 0x021,
    Retry = RC_WARN + 0x022,
    NvUnavailable = RC_WARN + 0x023,
    NotUsed = RC_WARN + 0x07F,
}

pub struct ReturnCodeError;

impl TryFrom<u16> for ReturnCode {
    type Error = ReturnCodeError;

    fn try_from(value: u16) -> Result<Self, Self::Error> {
        Self::from_repr(if value & RC_FMT1 != 0 {
            value & (0x3F + RC_FMT1)
        } else if value & RC_WARN != 0 {
            value & (0x7F + RC_WARN)
        } else if value & RC_VER1 != 0 {
            value & (0x7F + RC_VER1)
        } else {
            // RC_VER0
            value & 0x7F
        })
        .ok_or(ReturnCodeError)
    }
}

impl fmt::Display for ReturnCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Self::Success => write!(f, "TPM_RC_SUCCESS"),
            Self::BadTag => write!(f, "TPM_RC_BAD_TAG"),
            Self::Initialize => write!(f, "TPM_RC_INITIALIZE"),
            Self::Failure => write!(f, "TPM_RC_FAILURE"),
            Self::Sequence => write!(f, "TPM_RC_SEQUENCE"),
            Self::Private => write!(f, "TPM_RC_PRIVATE"),
            Self::Hmac => write!(f, "TPM_RC_HMAC"),
            Self::Disabled => write!(f, "TPM_RC_DISABLED"),
            Self::Exclusive => write!(f, "TPM_RC_EXCLUSIVE"),
            Self::AuthType => write!(f, "TPM_RC_AUTH_TYPE"),
            Self::AuthMissing => write!(f, "TPM_RC_AUTH_MISSING"),
            Self::Policy => write!(f, "TPM_RC_POLICY"),
            Self::Pcr => write!(f, "TPM_RC_PCR"),
            Self::PcrChanged => write!(f, "TPM_RC_PCR_CHANGED"),
            Self::Upgrade => write!(f, "TPM_RC_UPGRADE"),
            Self::TooManyContexts => write!(f, "TPM_RC_TOO_MANY_CONTEXTS"),
            Self::AuthUnavailable => write!(f, "TPM_RC_AUTH_UNAVAILABLE"),
            Self::Reboot => write!(f, "TPM_RC_REBOOT"),
            Self::Unbalanced => write!(f, "TPM_RC_UNBALANCED"),
            Self::CommandSize => write!(f, "TPM_RC_COMMAND_SIZE"),
            Self::CommandCode => write!(f, "TPM_RC_COMMAND_CODE"),
            Self::AuthSize => write!(f, "TPM_RC_AUTHSIZE"),
            Self::AuthContext => write!(f, "TPM_RC_AUTH_CONTEXT"),
            Self::NvRange => write!(f, "TPM_RC_NV_RANGE"),
            Self::NvSize => write!(f, "TPM_RC_NV_SIZE"),
            Self::NvLocked => write!(f, "TPM_RC_NV_LOCKED"),
            Self::NvAuthorization => write!(f, "TPM_RC_NV_AUTHORIZATION"),
            Self::NvUninitialized => write!(f, "TPM_RC_NV_UNINITIALIZED"),
            Self::NvSpace => write!(f, "TPM_RC_NV_SPACE"),
            Self::NvDefined => write!(f, "TPM_RC_NV_DEFINED"),
            Self::BadContext => write!(f, "TPM_RC_BAD_CONTEXT"),
            Self::CpHash => write!(f, "TPM_RC_CPHASH"),
            Self::Parent => write!(f, "TPM_RC_PARENT"),
            Self::NeedsTest => write!(f, "TPM_RC_NEEDS_TEST"),
            Self::NoResult => write!(f, "TPM_RC_NO_RESULT"),
            Self::Sensitive => write!(f, "TPM_RC_SENSITIVE"),
            Self::Asymmetric => write!(f, "TPM_RC_ASYMMETRIC"),
            Self::Attributes => write!(f, "TPM_RC_ATTRIBUTES"),
            Self::Hash => write!(f, "TPM_RC_HASH"),
            Self::Value => write!(f, "TPM_RC_VALUE"),
            Self::Hierarchy => write!(f, "TPM_RC_HIERARCHY"),
            Self::KeySize => write!(f, "TPM_RC_KEY_SIZE"),
            Self::Mgf => write!(f, "TPM_RC_MGF"),
            Self::Mode => write!(f, "TPM_RC_MODE"),
            Self::Type => write!(f, "TPM_RC_TYPE"),
            Self::Handle => write!(f, "TPM_RC_HANDLE"),
            Self::Kdf => write!(f, "TPM_RC_KDF"),
            Self::Range => write!(f, "TPM_RC_RANGE"),
            Self::AuthFail => write!(f, "TPM_RC_AUTH_FAIL"),
            Self::Nonce => write!(f, "TPM_RC_NONCE"),
            Self::Pp => write!(f, "TPM_RC_PP"),
            Self::Scheme => write!(f, "TPM_RC_SCHEME"),
            Self::Size => write!(f, "TPM_RC_SIZE"),
            Self::Symmetric => write!(f, "TPM_RC_SYMMETRIC"),
            Self::Tag => write!(f, "TPM_RC_TAG"),
            Self::Selector => write!(f, "TPM_RC_SELECTOR"),
            Self::Insufficient => write!(f, "TPM_RC_INSUFFICIENT"),
            Self::Signature => write!(f, "TPM_RC_SIGNATURE"),
            Self::Key => write!(f, "TPM_RC_KEY"),
            Self::PolicyFail => write!(f, "TPM_RC_POLICY_FAIL"),
            Self::Integrity => write!(f, "TPM_RC_INTEGRITY"),
            Self::Ticket => write!(f, "TPM_RC_TICKET"),
            Self::ReservedBits => write!(f, "TPM_RC_RESERVED_BITS"),
            Self::BadAuth => write!(f, "TPM_RC_BAD_AUTH"),
            Self::Expired => write!(f, "TPM_RC_EXPIRED"),
            Self::PolicyCc => write!(f, "TPM_RC_POLICY_CC"),
            Self::Binding => write!(f, "TPM_RC_BINDING"),
            Self::Curve => write!(f, "TPM_RC_CURVE"),
            Self::EccPoint => write!(f, "TPM_RC_ECC_POINT"),
            Self::ContextGap => write!(f, "TPM_RC_CONTEXT_GAP"),
            Self::ObjectMemory => write!(f, "TPM_RC_OBJECT_MEMORY"),
            Self::SessionMemory => write!(f, "TPM_RC_SESSION_MEMORY"),
            Self::Memory => write!(f, "TPM_RC_MEMORY"),
            Self::SessionHandles => write!(f, "TPM_RC_SESSION_HANDLES"),
            Self::ObjectHandles => write!(f, "TPM_RC_OBJECT_HANDLES"),
            Self::Locality => write!(f, "TPM_RC_LOCALITY"),
            Self::Yielded => write!(f, "TPM_RC_YIELDED"),
            Self::Canceled => write!(f, "TPM_RC_CANCELED"),
            Self::Testing => write!(f, "TPM_RC_TESTING"),
            Self::ReferenceH0 => write!(f, "TPM_RC_REFERENCE_H0"),
            Self::ReferenceH1 => write!(f, "TPM_RC_REFERENCE_H1"),
            Self::ReferenceH2 => write!(f, "TPM_RC_REFERENCE_H2"),
            Self::ReferenceH3 => write!(f, "TPM_RC_REFERENCE_H3"),
            Self::ReferenceH4 => write!(f, "TPM_RC_REFERENCE_H4"),
            Self::ReferenceH5 => write!(f, "TPM_RC_REFERENCE_H5"),
            Self::ReferenceH6 => write!(f, "TPM_RC_REFERENCE_H6"),
            Self::ReferenceS0 => write!(f, "TPM_RC_REFERENCE_S0"),
            Self::ReferenceS1 => write!(f, "TPM_RC_REFERENCE_S1"),
            Self::ReferenceS2 => write!(f, "TPM_RC_REFERENCE_S2"),
            Self::ReferenceS3 => write!(f, "TPM_RC_REFERENCE_S3"),
            Self::ReferenceS4 => write!(f, "TPM_RC_REFERENCE_S4"),
            Self::ReferenceS5 => write!(f, "TPM_RC_REFERENCE_S5"),
            Self::ReferenceS6 => write!(f, "TPM_RC_REFERENCE_S6"),
            Self::NvRate => write!(f, "TPM_RC_NV_RATE"),
            Self::Lockout => write!(f, "TPM_RC_LOCKOUT"),
            Self::Retry => write!(f, "TPM_RC_RETRY"),
            Self::NvUnavailable => write!(f, "TPM_RC_NV_UNAVAILABLE"),
            Self::NotUsed => write!(f, "TPM_RC_NOT_USED"),
        }
    }
}