1 //
2 // Copyright (C) 2014 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "trunks/error_codes.h"
18
19 #include <sstream>
20 #include <string>
21
22 #include <base/logging.h>
23
24 namespace {
25
26 // Masks out the P and N bits (see TPM 2.0 Part 2 Table 14).
27 const trunks::TPM_RC kFormatOneErrorMask = 0x0BF;
28 // Selects just the N bits that identify the subject index.
29 const trunks::TPM_RC kFormatOneSubjectMask = 0x700;
30 const trunks::TPM_RC kLayerMask = 0xFFFFF000;
31
32 // Returns a known error code or the empty string if unknown.
GetErrorStringInternal(trunks::TPM_RC error)33 std::string GetErrorStringInternal(trunks::TPM_RC error) {
34 switch (error) {
35 case trunks::TPM_RC_SUCCESS:
36 return "TPM_RC_SUCCESS";
37 case trunks::TPM_RC_BAD_TAG:
38 return "TPM_RC_BAD_TAG";
39 case trunks::TPM_RC_INITIALIZE:
40 return "TPM_RC_INITIALIZE";
41 case trunks::TPM_RC_FAILURE:
42 return "TPM_RC_FAILURE";
43 case trunks::TPM_RC_SEQUENCE:
44 return "TPM_RC_SEQUENCE";
45 case trunks::TPM_RC_PRIVATE:
46 return "TPM_RC_PRIVATE";
47 case trunks::TPM_RC_HMAC:
48 return "TPM_RC_HMAC";
49 case trunks::TPM_RC_DISABLED:
50 return "TPM_RC_DISABLED";
51 case trunks::TPM_RC_EXCLUSIVE:
52 return "TPM_RC_EXCLUSIVE";
53 case trunks::TPM_RC_AUTH_TYPE:
54 return "TPM_RC_AUTH_TYPE";
55 case trunks::TPM_RC_AUTH_MISSING:
56 return "TPM_RC_AUTH_MISSING";
57 case trunks::TPM_RC_POLICY:
58 return "TPM_RC_POLICY";
59 case trunks::TPM_RC_PCR:
60 return "TPM_RC_PCR";
61 case trunks::TPM_RC_PCR_CHANGED:
62 return "TPM_RC_PCR_CHANGED";
63 case trunks::TPM_RC_UPGRADE:
64 return "TPM_RC_UPGRADE";
65 case trunks::TPM_RC_TOO_MANY_CONTEXTS:
66 return "TPM_RC_TOO_MANY_CONTEXTS";
67 case trunks::TPM_RC_AUTH_UNAVAILABLE:
68 return "TPM_RC_AUTH_UNAVAILABLE";
69 case trunks::TPM_RC_REBOOT:
70 return "TPM_RC_REBOOT";
71 case trunks::TPM_RC_UNBALANCED:
72 return "TPM_RC_UNBALANCED";
73 case trunks::TPM_RC_COMMAND_SIZE:
74 return "TPM_RC_COMMAND_SIZE";
75 case trunks::TPM_RC_COMMAND_CODE:
76 return "TPM_RC_COMMAND_CODE";
77 case trunks::TPM_RC_AUTHSIZE:
78 return "TPM_RC_AUTHSIZE";
79 case trunks::TPM_RC_AUTH_CONTEXT:
80 return "TPM_RC_AUTH_CONTEXT";
81 case trunks::TPM_RC_NV_RANGE:
82 return "TPM_RC_NV_RANGE";
83 case trunks::TPM_RC_NV_SIZE:
84 return "TPM_RC_NV_SIZE";
85 case trunks::TPM_RC_NV_LOCKED:
86 return "TPM_RC_NV_LOCKED";
87 case trunks::TPM_RC_NV_AUTHORIZATION:
88 return "TPM_RC_NV_AUTHORIZATION";
89 case trunks::TPM_RC_NV_UNINITIALIZED:
90 return "TPM_RC_NV_UNINITIALIZED";
91 case trunks::TPM_RC_NV_SPACE:
92 return "TPM_RC_NV_SPACE";
93 case trunks::TPM_RC_NV_DEFINED:
94 return "TPM_RC_NV_DEFINED";
95 case trunks::TPM_RC_BAD_CONTEXT:
96 return "TPM_RC_BAD_CONTEXT";
97 case trunks::TPM_RC_CPHASH:
98 return "TPM_RC_CPHASH";
99 case trunks::TPM_RC_PARENT:
100 return "TPM_RC_PARENT";
101 case trunks::TPM_RC_NEEDS_TEST:
102 return "TPM_RC_NEEDS_TEST";
103 case trunks::TPM_RC_NO_RESULT:
104 return "TPM_RC_NO_RESULT";
105 case trunks::TPM_RC_SENSITIVE:
106 return "TPM_RC_SENSITIVE";
107 case trunks::TPM_RC_ASYMMETRIC:
108 return "TPM_RC_ASYMMETRIC";
109 case trunks::TPM_RC_ATTRIBUTES:
110 return "TPM_RC_ATTRIBUTES";
111 case trunks::TPM_RC_HASH:
112 return "TPM_RC_HASH";
113 case trunks::TPM_RC_VALUE:
114 return "TPM_RC_VALUE";
115 case trunks::TPM_RC_HIERARCHY:
116 return "TPM_RC_HIERARCHY";
117 case trunks::TPM_RC_KEY_SIZE:
118 return "TPM_RC_KEY_SIZE";
119 case trunks::TPM_RC_MGF:
120 return "TPM_RC_MGF";
121 case trunks::TPM_RC_MODE:
122 return "TPM_RC_MODE";
123 case trunks::TPM_RC_TYPE:
124 return "TPM_RC_TYPE";
125 case trunks::TPM_RC_HANDLE:
126 return "TPM_RC_HANDLE";
127 case trunks::TPM_RC_KDF:
128 return "TPM_RC_KDF";
129 case trunks::TPM_RC_RANGE:
130 return "TPM_RC_RANGE";
131 case trunks::TPM_RC_AUTH_FAIL:
132 return "TPM_RC_AUTH_FAIL";
133 case trunks::TPM_RC_NONCE:
134 return "TPM_RC_NONCE";
135 case trunks::TPM_RC_PP:
136 return "TPM_RC_PP";
137 case trunks::TPM_RC_SCHEME:
138 return "TPM_RC_SCHEME";
139 case trunks::TPM_RC_SIZE:
140 return "TPM_RC_SIZE";
141 case trunks::TPM_RC_SYMMETRIC:
142 return "TPM_RC_SYMMETRIC";
143 case trunks::TPM_RC_TAG:
144 return "TPM_RC_TAG";
145 case trunks::TPM_RC_SELECTOR:
146 return "TPM_RC_SELECTOR";
147 case trunks::TPM_RC_INSUFFICIENT:
148 return "TPM_RC_INSUFFICIENT";
149 case trunks::TPM_RC_SIGNATURE:
150 return "TPM_RC_SIGNATURE";
151 case trunks::TPM_RC_KEY:
152 return "TPM_RC_KEY";
153 case trunks::TPM_RC_POLICY_FAIL:
154 return "TPM_RC_POLICY_FAIL";
155 case trunks::TPM_RC_INTEGRITY:
156 return "TPM_RC_INTEGRITY";
157 case trunks::TPM_RC_TICKET:
158 return "TPM_RC_TICKET";
159 case trunks::TPM_RC_RESERVED_BITS:
160 return "TPM_RC_RESERVED_BITS";
161 case trunks::TPM_RC_BAD_AUTH:
162 return "TPM_RC_BAD_AUTH";
163 case trunks::TPM_RC_EXPIRED:
164 return "TPM_RC_EXPIRED";
165 case trunks::TPM_RC_POLICY_CC:
166 return "TPM_RC_POLICY_CC";
167 case trunks::TPM_RC_BINDING:
168 return "TPM_RC_BINDING";
169 case trunks::TPM_RC_CURVE:
170 return "TPM_RC_CURVE";
171 case trunks::TPM_RC_ECC_POINT:
172 return "TPM_RC_ECC_POINT";
173 case trunks::TPM_RC_CONTEXT_GAP:
174 return "TPM_RC_CONTEXT_GAP";
175 case trunks::TPM_RC_OBJECT_MEMORY:
176 return "TPM_RC_OBJECT_MEMORY";
177 case trunks::TPM_RC_SESSION_MEMORY:
178 return "TPM_RC_SESSION_MEMORY";
179 case trunks::TPM_RC_MEMORY:
180 return "TPM_RC_MEMORY";
181 case trunks::TPM_RC_SESSION_HANDLES:
182 return "TPM_RC_SESSION_HANDLES";
183 case trunks::TPM_RC_OBJECT_HANDLES:
184 return "TPM_RC_OBJECT_HANDLES";
185 case trunks::TPM_RC_LOCALITY:
186 return "TPM_RC_LOCALITY";
187 case trunks::TPM_RC_YIELDED:
188 return "TPM_RC_YIELDED";
189 case trunks::TPM_RC_CANCELED:
190 return "TPM_RC_CANCELED";
191 case trunks::TPM_RC_TESTING:
192 return "TPM_RC_TESTING";
193 case trunks::TPM_RC_REFERENCE_H0:
194 return "TPM_RC_REFERENCE_H0";
195 case trunks::TPM_RC_REFERENCE_H1:
196 return "TPM_RC_REFERENCE_H1";
197 case trunks::TPM_RC_REFERENCE_H2:
198 return "TPM_RC_REFERENCE_H2";
199 case trunks::TPM_RC_REFERENCE_H3:
200 return "TPM_RC_REFERENCE_H3";
201 case trunks::TPM_RC_REFERENCE_H4:
202 return "TPM_RC_REFERENCE_H4";
203 case trunks::TPM_RC_REFERENCE_H5:
204 return "TPM_RC_REFERENCE_H5";
205 case trunks::TPM_RC_REFERENCE_H6:
206 return "TPM_RC_REFERENCE_H6";
207 case trunks::TPM_RC_REFERENCE_S0:
208 return "TPM_RC_REFERENCE_S0";
209 case trunks::TPM_RC_REFERENCE_S1:
210 return "TPM_RC_REFERENCE_S1";
211 case trunks::TPM_RC_REFERENCE_S2:
212 return "TPM_RC_REFERENCE_S2";
213 case trunks::TPM_RC_REFERENCE_S3:
214 return "TPM_RC_REFERENCE_S3";
215 case trunks::TPM_RC_REFERENCE_S4:
216 return "TPM_RC_REFERENCE_S4";
217 case trunks::TPM_RC_REFERENCE_S5:
218 return "TPM_RC_REFERENCE_S5";
219 case trunks::TPM_RC_REFERENCE_S6:
220 return "TPM_RC_REFERENCE_S6";
221 case trunks::TPM_RC_NV_RATE:
222 return "TPM_RC_NV_RATE";
223 case trunks::TPM_RC_LOCKOUT:
224 return "TPM_RC_LOCKOUT";
225 case trunks::TPM_RC_RETRY:
226 return "TPM_RC_RETRY";
227 case trunks::TPM_RC_NV_UNAVAILABLE:
228 return "TPM_RC_NV_UNAVAILABLE";
229 case trunks::TPM_RC_NOT_USED:
230 return "TPM_RC_NOT_USED";
231 case trunks::TRUNKS_RC_AUTHORIZATION_FAILED:
232 return "TRUNKS_RC_AUTHORIZATION_FAILED";
233 case trunks::TRUNKS_RC_ENCRYPTION_FAILED:
234 return "TRUNKS_RC_ENCRYPTION_FAILED";
235 case trunks::TRUNKS_RC_READ_ERROR:
236 return "TRUNKS_RC_READ_ERROR";
237 case trunks::TRUNKS_RC_WRITE_ERROR:
238 return "TRUNKS_RC_WRITE_ERROR";
239 case trunks::TRUNKS_RC_IPC_ERROR:
240 return "TRUNKS_RC_IPC_ERROR";
241 case trunks::TRUNKS_RC_SESSION_SETUP_ERROR:
242 return "TRUNKS_RC_SESSION_SETUP_ERROR";
243 case trunks::TCTI_RC_TRY_AGAIN:
244 return "TCTI_RC_TRY_AGAIN";
245 case trunks::TCTI_RC_GENERAL_FAILURE:
246 return "TCTI_RC_GENERAL_FAILURE";
247 case trunks::TCTI_RC_BAD_CONTEXT:
248 return "TCTI_RC_BAD_CONTEXT";
249 case trunks::TCTI_RC_WRONG_ABI_VERSION:
250 return "TCTI_RC_WRONG_ABI_VERSION";
251 case trunks::TCTI_RC_NOT_IMPLEMENTED:
252 return "TCTI_RC_NOT_IMPLEMENTED";
253 case trunks::TCTI_RC_BAD_PARAMETER:
254 return "TCTI_RC_BAD_PARAMETER";
255 case trunks::TCTI_RC_INSUFFICIENT_BUFFER:
256 return "TCTI_RC_INSUFFICIENT_BUFFER";
257 case trunks::TCTI_RC_NO_CONNECTION:
258 return "TCTI_RC_NO_CONNECTION";
259 case trunks::TCTI_RC_DRIVER_NOT_FOUND:
260 return "TCTI_RC_DRIVER_NOT_FOUND";
261 case trunks::TCTI_RC_DRIVERINFO_NOT_FOUND:
262 return "TCTI_RC_DRIVERINFO_NOT_FOUND";
263 case trunks::TCTI_RC_NO_RESPONSE:
264 return "TCTI_RC_NO_RESPONSE";
265 case trunks::TCTI_RC_BAD_VALUE:
266 return "TCTI_RC_BAD_VALUE";
267 case trunks::SAPI_RC_INVALID_SESSIONS:
268 return "SAPI_RC_INVALID_SESSIONS";
269 case trunks::SAPI_RC_ABI_MISMATCH:
270 return "SAPI_RC_ABI_MISMATCH";
271 case trunks::SAPI_RC_INSUFFICIENT_BUFFER:
272 return "SAPI_RC_INSUFFICIENT_BUFFER";
273 case trunks::SAPI_RC_BAD_PARAMETER:
274 return "SAPI_RC_BAD_PARAMETER";
275 case trunks::SAPI_RC_BAD_SEQUENCE:
276 return "SAPI_RC_BAD_SEQUENCE";
277 case trunks::SAPI_RC_NO_DECRYPT_PARAM:
278 return "SAPI_RC_NO_DECRYPT_PARAM";
279 case trunks::SAPI_RC_NO_ENCRYPT_PARAM:
280 return "SAPI_RC_NO_ENCRYPT_PARAM";
281 case trunks::SAPI_RC_NO_RESPONSE_RECEIVED:
282 return "SAPI_RC_NO_RESPONSE_RECEIVED";
283 case trunks::SAPI_RC_BAD_SIZE:
284 return "SAPI_RC_BAD_SIZE";
285 case trunks::SAPI_RC_CORRUPTED_DATA:
286 return "SAPI_RC_CORRUPTED_DATA";
287 case trunks::SAPI_RC_INSUFFICIENT_CONTEXT:
288 return "SAPI_RC_INSUFFICIENT_CONTEXT";
289 case trunks::SAPI_RC_INSUFFICIENT_RESPONSE:
290 return "SAPI_RC_INSUFFICIENT_RESPONSE";
291 case trunks::SAPI_RC_INCOMPATIBLE_TCTI:
292 return "SAPI_RC_INCOMPATIBLE_TCTI";
293 case trunks::SAPI_RC_MALFORMED_RESPONSE:
294 return "SAPI_RC_MALFORMED_RESPONSE";
295 case trunks::SAPI_RC_BAD_TCTI_STRUCTURE:
296 return "SAPI_RC_BAD_TCTI_STRUCTURE";
297 default:
298 return std::string();
299 }
300 NOTREACHED();
301 return std::string();
302 }
303
IsFormatOne(trunks::TPM_RC error)304 bool IsFormatOne(trunks::TPM_RC error) {
305 return (error & kLayerMask) == 0 && (error & trunks::RC_FMT1) != 0;
306 }
307
308 } // namespace
309
310 namespace trunks {
311
GetErrorString(TPM_RC error)312 std::string GetErrorString(TPM_RC error) {
313 std::string error_string = GetErrorStringInternal(error);
314 if (!error_string.empty()) {
315 return error_string;
316 }
317 std::stringstream ss;
318 if ((error & kLayerMask) == kResourceManagerTpmErrorBase) {
319 error &= ~kLayerMask;
320 error_string = GetErrorStringInternal(error);
321 ss << "Resource Manager: ";
322 }
323 // Check if we have a TPM 'Format-One' response code.
324 if (IsFormatOne(error)) {
325 if (error & TPM_RC_P) {
326 ss << "Parameter ";
327 } else if (error & TPM_RC_S) {
328 ss << "Session ";
329 } else {
330 ss << "Handle ";
331 }
332 // Bits 8-10 specify which handle / parameter / session.
333 ss << ((error & kFormatOneSubjectMask) >> 8) << ": ";
334 // Mask out everything but the format bit and error number.
335 error_string = GetErrorStringInternal(error & kFormatOneErrorMask);
336 if (!error_string.empty()) {
337 ss << error_string;
338 }
339 }
340 if (error_string.empty()) {
341 ss << "Unknown error: " << error << " (0x" << std::hex << error << ")";
342 }
343 return ss.str();
344 }
345
GetFormatOneError(TPM_RC error)346 TPM_RC GetFormatOneError(TPM_RC error) {
347 if (IsFormatOne(error)) {
348 return (error & kFormatOneErrorMask);
349 }
350 return error;
351 }
352
CreateErrorResponse(TPM_RC error_code)353 std::string CreateErrorResponse(TPM_RC error_code) {
354 const uint32_t kErrorResponseSize = 10;
355 std::string response;
356 CHECK_EQ(Serialize_TPM_ST(TPM_ST_NO_SESSIONS, &response), TPM_RC_SUCCESS);
357 CHECK_EQ(Serialize_UINT32(kErrorResponseSize, &response), TPM_RC_SUCCESS);
358 CHECK_EQ(Serialize_TPM_RC(error_code, &response), TPM_RC_SUCCESS);
359 return response;
360 }
361
362 } // namespace trunks
363