Botan 3.6.0
Crypto and TLS for C&
tpm2_error.cpp
Go to the documentation of this file.
1/*
2* TPM 2 error handling
3* (C) 2024 Jack Lloyd
4* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH, financed by LANCOM Systems GmbH
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/tpm2_error.h>
10
11#include <botan/internal/fmt.h>
12#include <botan/internal/tpm2_util.h>
13
14#include <tss2/tss2_rc.h>
15
16namespace Botan::TPM2 {
17
19#if defined(BOTAN_TSS2_SUPPORTS_ERROR_DECODING)
20 TSS2_RC_INFO info;
21 const TSS2_RC decoding_rc = Tss2_RC_DecodeInfo(rc, &info);
22 if(decoding_rc != TSS2_RC_SUCCESS) [[unlikely]] {
23 throw Error(fmt("Decoding RC failed (was: {})", rc), decoding_rc);
24 }
25 return info.error;
26#else
27 // This fallback implementation is derived from the implementation of
28 // Tss2_RC_DecodeInfo in tpm2-tss 4.0.0.
29 const bool formatted = (rc & (1 << 7)) != 0;
30 if(formatted) {
31 return (rc & 0x3F) | TPM2_RC_FMT1;
32 } else {
33 return rc & 0xFFFF;
34 }
35#endif
36}
37
38namespace {
39
40std::string raw_rc_to_string(TSS2_RC rc) noexcept {
41 switch(rc) {
42 case TPM2_RC_SUCCESS:
43 return "TPM2_RC_SUCCESS";
44 case TPM2_RC_BAD_TAG:
45 return "TPM2_RC_BAD_TAG";
46 case TPM2_RC_INITIALIZE:
47 return "TPM2_RC_INITIALIZE";
48 case TPM2_RC_FAILURE:
49 return "TPM2_RC_FAILURE";
50 case TPM2_RC_SEQUENCE:
51 return "TPM2_RC_SEQUENCE";
52 case TPM2_RC_PRIVATE:
53 return "TPM2_RC_PRIVATE";
54 case TPM2_RC_HMAC:
55 return "TPM2_RC_HMAC";
56 case TPM2_RC_DISABLED:
57 return "TPM2_RC_DISABLED";
58 case TPM2_RC_EXCLUSIVE:
59 return "TPM2_RC_EXCLUSIVE";
60 case TPM2_RC_AUTH_TYPE:
61 return "TPM2_RC_AUTH_TYPE";
62 case TPM2_RC_AUTH_MISSING:
63 return "TPM2_RC_AUTH_MISSING";
64 case TPM2_RC_POLICY:
65 return "TPM2_RC_POLICY";
66 case TPM2_RC_PCR:
67 return "TPM2_RC_PCR";
68 case TPM2_RC_PCR_CHANGED:
69 return "TPM2_RC_PCR_CHANGED";
70 case TPM2_RC_UPGRADE:
71 return "TPM2_RC_UPGRADE";
72 case TPM2_RC_TOO_MANY_CONTEXTS:
73 return "TPM2_RC_TOO_MANY_CONTEXTS";
74 case TPM2_RC_AUTH_UNAVAILABLE:
75 return "TPM2_RC_AUTH_UNAVAILABLE";
76 case TPM2_RC_REBOOT:
77 return "TPM2_RC_REBOOT";
78 case TPM2_RC_UNBALANCED:
79 return "TPM2_RC_UNBALANCED";
80 case TPM2_RC_COMMAND_SIZE:
81 return "TPM2_RC_COMMAND_SIZE";
82 case TPM2_RC_COMMAND_CODE:
83 return "TPM2_RC_COMMAND_CODE";
84 case TPM2_RC_AUTHSIZE:
85 return "TPM2_RC_AUTHSIZE";
86 case TPM2_RC_AUTH_CONTEXT:
87 return "TPM2_RC_AUTH_CONTEXT";
88 case TPM2_RC_NV_RANGE:
89 return "TPM2_RC_NV_RANGE";
90 case TPM2_RC_NV_SIZE:
91 return "TPM2_RC_NV_SIZE";
92 case TPM2_RC_NV_LOCKED:
93 return "TPM2_RC_NV_LOCKED";
94 case TPM2_RC_NV_AUTHORIZATION:
95 return "TPM2_RC_NV_AUTHORIZATION";
96 case TPM2_RC_NV_UNINITIALIZED:
97 return "TPM2_RC_NV_UNINITIALIZED";
98 case TPM2_RC_NV_SPACE:
99 return "TPM2_RC_NV_SPACE";
100 case TPM2_RC_NV_DEFINED:
101 return "TPM2_RC_NV_DEFINED";
102 case TPM2_RC_BAD_CONTEXT:
103 return "TPM2_RC_BAD_CONTEXT";
104 case TPM2_RC_CPHASH:
105 return "TPM2_RC_CPHASH";
106 case TPM2_RC_PARENT:
107 return "TPM2_RC_PARENT";
108 case TPM2_RC_NEEDS_TEST:
109 return "TPM2_RC_NEEDS_TEST";
110 case TPM2_RC_NO_RESULT:
111 return "TPM2_RC_NO_RESULT";
112 case TPM2_RC_SENSITIVE:
113 return "TPM2_RC_SENSITIVE";
114 case TPM2_RC_MAX_FM0:
115 return "TPM2_RC_MAX_FM0";
116 case TPM2_RC_FMT1:
117 return "TPM2_RC_FMT1";
118 case TPM2_RC_ASYMMETRIC:
119 return "TPM2_RC_ASYMMETRIC";
120 case TPM2_RC_ATTRIBUTES:
121 return "TPM2_RC_ATTRIBUTES";
122 case TPM2_RC_HASH:
123 return "TPM2_RC_HASH";
124 case TPM2_RC_VALUE:
125 return "TPM2_RC_VALUE";
126 case TPM2_RC_HIERARCHY:
127 return "TPM2_RC_HIERARCHY";
128 case TPM2_RC_KEY_SIZE:
129 return "TPM2_RC_KEY_SIZE";
130 case TPM2_RC_MGF:
131 return "TPM2_RC_MGF";
132 case TPM2_RC_MODE:
133 return "TPM2_RC_MODE";
134 case TPM2_RC_TYPE:
135 return "TPM2_RC_TYPE";
136 case TPM2_RC_HANDLE:
137 return "TPM2_RC_HANDLE";
138 case TPM2_RC_KDF:
139 return "TPM2_RC_KDF";
140 case TPM2_RC_RANGE:
141 return "TPM2_RC_RANGE";
142 case TPM2_RC_AUTH_FAIL:
143 return "TPM2_RC_AUTH_FAIL";
144 case TPM2_RC_NONCE:
145 return "TPM2_RC_NONCE";
146 case TPM2_RC_PP:
147 return "TPM2_RC_PP";
148 case TPM2_RC_SCHEME:
149 return "TPM2_RC_SCHEME";
150 case TPM2_RC_SIZE:
151 return "TPM2_RC_SIZE";
152 case TPM2_RC_SYMMETRIC:
153 return "TPM2_RC_SYMMETRIC";
154 case TPM2_RC_TAG:
155 return "TPM2_RC_TAG";
156 case TPM2_RC_SELECTOR:
157 return "TPM2_RC_SELECTOR";
158 case TPM2_RC_INSUFFICIENT:
159 return "TPM2_RC_INSUFFICIENT";
160 case TPM2_RC_SIGNATURE:
161 return "TPM2_RC_SIGNATURE";
162 case TPM2_RC_KEY:
163 return "TPM2_RC_KEY";
164 case TPM2_RC_POLICY_FAIL:
165 return "TPM2_RC_POLICY_FAIL";
166 case TPM2_RC_INTEGRITY:
167 return "TPM2_RC_INTEGRITY";
168 case TPM2_RC_TICKET:
169 return "TPM2_RC_TICKET";
170 case TPM2_RC_RESERVED_BITS:
171 return "TPM2_RC_RESERVED_BITS";
172 case TPM2_RC_BAD_AUTH:
173 return "TPM2_RC_BAD_AUTH";
174 case TPM2_RC_EXPIRED:
175 return "TPM2_RC_EXPIRED";
176 case TPM2_RC_POLICY_CC:
177 return "TPM2_RC_POLICY_CC";
178 case TPM2_RC_BINDING:
179 return "TPM2_RC_BINDING";
180 case TPM2_RC_CURVE:
181 return "TPM2_RC_CURVE";
182 case TPM2_RC_ECC_POINT:
183 return "TPM2_RC_ECC_POINT";
184 case TPM2_RC_WARN:
185 return "TPM2_RC_WARN";
186 case TPM2_RC_CONTEXT_GAP:
187 return "TPM2_RC_CONTEXT_GAP";
188 case TPM2_RC_OBJECT_MEMORY:
189 return "TPM2_RC_OBJECT_MEMORY";
190 case TPM2_RC_SESSION_MEMORY:
191 return "TPM2_RC_SESSION_MEMORY";
192 case TPM2_RC_MEMORY:
193 return "TPM2_RC_MEMORY";
194 case TPM2_RC_SESSION_HANDLES:
195 return "TPM2_RC_SESSION_HANDLES";
196 case TPM2_RC_OBJECT_HANDLES:
197 return "TPM2_RC_OBJECT_HANDLES";
198 case TPM2_RC_LOCALITY:
199 return "TPM2_RC_LOCALITY";
200 case TPM2_RC_YIELDED:
201 return "TPM2_RC_YIELDED";
202 case TPM2_RC_CANCELED:
203 return "TPM2_RC_CANCELED";
204 case TPM2_RC_TESTING:
205 return "TPM2_RC_TESTING";
206 case TPM2_RC_REFERENCE_H0:
207 return "TPM2_RC_REFERENCE_H0";
208 case TPM2_RC_REFERENCE_H1:
209 return "TPM2_RC_REFERENCE_H1";
210 case TPM2_RC_REFERENCE_H2:
211 return "TPM2_RC_REFERENCE_H2";
212 case TPM2_RC_REFERENCE_H3:
213 return "TPM2_RC_REFERENCE_H3";
214 case TPM2_RC_REFERENCE_H4:
215 return "TPM2_RC_REFERENCE_H4";
216 case TPM2_RC_REFERENCE_H5:
217 return "TPM2_RC_REFERENCE_H5";
218 case TPM2_RC_REFERENCE_H6:
219 return "TPM2_RC_REFERENCE_H6";
220 case TPM2_RC_REFERENCE_S0:
221 return "TPM2_RC_REFERENCE_S0";
222 case TPM2_RC_REFERENCE_S1:
223 return "TPM2_RC_REFERENCE_S1";
224 case TPM2_RC_REFERENCE_S2:
225 return "TPM2_RC_REFERENCE_S2";
226 case TPM2_RC_REFERENCE_S3:
227 return "TPM2_RC_REFERENCE_S3";
228 case TPM2_RC_REFERENCE_S4:
229 return "TPM2_RC_REFERENCE_S4";
230 case TPM2_RC_REFERENCE_S5:
231 return "TPM2_RC_REFERENCE_S5";
232 case TPM2_RC_REFERENCE_S6:
233 return "TPM2_RC_REFERENCE_S6";
234 case TPM2_RC_NV_RATE:
235 return "TPM2_RC_NV_RATE";
236 case TPM2_RC_LOCKOUT:
237 return "TPM2_RC_LOCKOUT";
238 case TPM2_RC_RETRY:
239 return "TPM2_RC_RETRY";
240 case TPM2_RC_NV_UNAVAILABLE:
241 return "TPM2_RC_NV_UNAVAILABLE";
242
243 default:
244 return Botan::fmt("Unknown TSS2_RC: {}", rc);
245 }
246}
247
248} // namespace
249
250Error::Error(std::string_view location, TSS2_RC rc) :
251 Exception(fmt("TPM2 Exception in {}: Code {} - {} ({})",
252 location,
253 raw_rc_to_string(get_raw_rc(rc)),
254 rc,
255 Tss2_RC_Decode(rc))),
256 m_rc(rc) {}
257
258std::string Error::error_message() const {
259 return Tss2_RC_Decode(m_rc);
260}
261
262} // namespace Botan::TPM2
std::string error_message() const
Error(std::string_view location, TSS2_RC rc)
TSS2_RC get_raw_rc(TSS2_RC rc)
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
uint32_t TSS2_RC
Forward declaration of TSS2 type for convenience.
Definition tpm2_error.h:15