error_codes.cc revision 469ec33d58271390c7a5b77030b5e92f4e982a5e
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
24namespace {
25
26// Masks out the P and N bits (see TPM 2.0 Part 2 Table 14).
27const trunks::TPM_RC kFormatOneErrorMask = 0x0BF;
28// Selects just the N bits that identify the subject index.
29const trunks::TPM_RC kFormatOneSubjectMask = 0x700;
30const trunks::TPM_RC kLayerMask = 0xFFFFF000;
31
32// Returns a known error code or the empty string if unknown.
33std::string GetErrorStringInternal(trunks::TPM_RC error) {
34  switch (error) {
35    case trunks::TPM_RC_SUCCESS: return "TPM_RC_SUCCESS";
36    case trunks::TPM_RC_BAD_TAG: return "TPM_RC_BAD_TAG";
37    case trunks::TPM_RC_INITIALIZE: return "TPM_RC_INITIALIZE";
38    case trunks::TPM_RC_FAILURE: return "TPM_RC_FAILURE";
39    case trunks::TPM_RC_SEQUENCE: return "TPM_RC_SEQUENCE";
40    case trunks::TPM_RC_PRIVATE: return "TPM_RC_PRIVATE";
41    case trunks::TPM_RC_HMAC: return "TPM_RC_HMAC";
42    case trunks::TPM_RC_DISABLED: return "TPM_RC_DISABLED";
43    case trunks::TPM_RC_EXCLUSIVE: return "TPM_RC_EXCLUSIVE";
44    case trunks::TPM_RC_AUTH_TYPE: return "TPM_RC_AUTH_TYPE";
45    case trunks::TPM_RC_AUTH_MISSING: return "TPM_RC_AUTH_MISSING";
46    case trunks::TPM_RC_POLICY: return "TPM_RC_POLICY";
47    case trunks::TPM_RC_PCR: return "TPM_RC_PCR";
48    case trunks::TPM_RC_PCR_CHANGED: return "TPM_RC_PCR_CHANGED";
49    case trunks::TPM_RC_UPGRADE: return "TPM_RC_UPGRADE";
50    case trunks::TPM_RC_TOO_MANY_CONTEXTS: return "TPM_RC_TOO_MANY_CONTEXTS";
51    case trunks::TPM_RC_AUTH_UNAVAILABLE: return "TPM_RC_AUTH_UNAVAILABLE";
52    case trunks::TPM_RC_REBOOT: return "TPM_RC_REBOOT";
53    case trunks::TPM_RC_UNBALANCED: return "TPM_RC_UNBALANCED";
54    case trunks::TPM_RC_COMMAND_SIZE: return "TPM_RC_COMMAND_SIZE";
55    case trunks::TPM_RC_COMMAND_CODE: return "TPM_RC_COMMAND_CODE";
56    case trunks::TPM_RC_AUTHSIZE: return "TPM_RC_AUTHSIZE";
57    case trunks::TPM_RC_AUTH_CONTEXT: return "TPM_RC_AUTH_CONTEXT";
58    case trunks::TPM_RC_NV_RANGE: return "TPM_RC_NV_RANGE";
59    case trunks::TPM_RC_NV_SIZE: return "TPM_RC_NV_SIZE";
60    case trunks::TPM_RC_NV_LOCKED: return "TPM_RC_NV_LOCKED";
61    case trunks::TPM_RC_NV_AUTHORIZATION: return "TPM_RC_NV_AUTHORIZATION";
62    case trunks::TPM_RC_NV_UNINITIALIZED: return "TPM_RC_NV_UNINITIALIZED";
63    case trunks::TPM_RC_NV_SPACE: return "TPM_RC_NV_SPACE";
64    case trunks::TPM_RC_NV_DEFINED: return "TPM_RC_NV_DEFINED";
65    case trunks::TPM_RC_BAD_CONTEXT: return "TPM_RC_BAD_CONTEXT";
66    case trunks::TPM_RC_CPHASH: return "TPM_RC_CPHASH";
67    case trunks::TPM_RC_PARENT: return "TPM_RC_PARENT";
68    case trunks::TPM_RC_NEEDS_TEST: return "TPM_RC_NEEDS_TEST";
69    case trunks::TPM_RC_NO_RESULT: return "TPM_RC_NO_RESULT";
70    case trunks::TPM_RC_SENSITIVE: return "TPM_RC_SENSITIVE";
71    case trunks::TPM_RC_ASYMMETRIC: return "TPM_RC_ASYMMETRIC";
72    case trunks::TPM_RC_ATTRIBUTES: return "TPM_RC_ATTRIBUTES";
73    case trunks::TPM_RC_HASH: return "TPM_RC_HASH";
74    case trunks::TPM_RC_VALUE: return "TPM_RC_VALUE";
75    case trunks::TPM_RC_HIERARCHY: return "TPM_RC_HIERARCHY";
76    case trunks::TPM_RC_KEY_SIZE: return "TPM_RC_KEY_SIZE";
77    case trunks::TPM_RC_MGF: return "TPM_RC_MGF";
78    case trunks::TPM_RC_MODE: return "TPM_RC_MODE";
79    case trunks::TPM_RC_TYPE: return "TPM_RC_TYPE";
80    case trunks::TPM_RC_HANDLE: return "TPM_RC_HANDLE";
81    case trunks::TPM_RC_KDF: return "TPM_RC_KDF";
82    case trunks::TPM_RC_RANGE: return "TPM_RC_RANGE";
83    case trunks::TPM_RC_AUTH_FAIL: return "TPM_RC_AUTH_FAIL";
84    case trunks::TPM_RC_NONCE: return "TPM_RC_NONCE";
85    case trunks::TPM_RC_PP: return "TPM_RC_PP";
86    case trunks::TPM_RC_SCHEME: return "TPM_RC_SCHEME";
87    case trunks::TPM_RC_SIZE: return "TPM_RC_SIZE";
88    case trunks::TPM_RC_SYMMETRIC: return "TPM_RC_SYMMETRIC";
89    case trunks::TPM_RC_TAG: return "TPM_RC_TAG";
90    case trunks::TPM_RC_SELECTOR: return "TPM_RC_SELECTOR";
91    case trunks::TPM_RC_INSUFFICIENT: return "TPM_RC_INSUFFICIENT";
92    case trunks::TPM_RC_SIGNATURE: return "TPM_RC_SIGNATURE";
93    case trunks::TPM_RC_KEY: return "TPM_RC_KEY";
94    case trunks::TPM_RC_POLICY_FAIL: return "TPM_RC_POLICY_FAIL";
95    case trunks::TPM_RC_INTEGRITY: return "TPM_RC_INTEGRITY";
96    case trunks::TPM_RC_TICKET: return "TPM_RC_TICKET";
97    case trunks::TPM_RC_RESERVED_BITS: return "TPM_RC_RESERVED_BITS";
98    case trunks::TPM_RC_BAD_AUTH: return "TPM_RC_BAD_AUTH";
99    case trunks::TPM_RC_EXPIRED: return "TPM_RC_EXPIRED";
100    case trunks::TPM_RC_POLICY_CC: return "TPM_RC_POLICY_CC";
101    case trunks::TPM_RC_BINDING: return "TPM_RC_BINDING";
102    case trunks::TPM_RC_CURVE: return "TPM_RC_CURVE";
103    case trunks::TPM_RC_ECC_POINT: return "TPM_RC_ECC_POINT";
104    case trunks::TPM_RC_CONTEXT_GAP: return "TPM_RC_CONTEXT_GAP";
105    case trunks::TPM_RC_OBJECT_MEMORY: return "TPM_RC_OBJECT_MEMORY";
106    case trunks::TPM_RC_SESSION_MEMORY: return "TPM_RC_SESSION_MEMORY";
107    case trunks::TPM_RC_MEMORY: return "TPM_RC_MEMORY";
108    case trunks::TPM_RC_SESSION_HANDLES: return "TPM_RC_SESSION_HANDLES";
109    case trunks::TPM_RC_OBJECT_HANDLES: return "TPM_RC_OBJECT_HANDLES";
110    case trunks::TPM_RC_LOCALITY: return "TPM_RC_LOCALITY";
111    case trunks::TPM_RC_YIELDED: return "TPM_RC_YIELDED";
112    case trunks::TPM_RC_CANCELED: return "TPM_RC_CANCELED";
113    case trunks::TPM_RC_TESTING: return "TPM_RC_TESTING";
114    case trunks::TPM_RC_REFERENCE_H0: return "TPM_RC_REFERENCE_H0";
115    case trunks::TPM_RC_REFERENCE_H1: return "TPM_RC_REFERENCE_H1";
116    case trunks::TPM_RC_REFERENCE_H2: return "TPM_RC_REFERENCE_H2";
117    case trunks::TPM_RC_REFERENCE_H3: return "TPM_RC_REFERENCE_H3";
118    case trunks::TPM_RC_REFERENCE_H4: return "TPM_RC_REFERENCE_H4";
119    case trunks::TPM_RC_REFERENCE_H5: return "TPM_RC_REFERENCE_H5";
120    case trunks::TPM_RC_REFERENCE_H6: return "TPM_RC_REFERENCE_H6";
121    case trunks::TPM_RC_REFERENCE_S0: return "TPM_RC_REFERENCE_S0";
122    case trunks::TPM_RC_REFERENCE_S1: return "TPM_RC_REFERENCE_S1";
123    case trunks::TPM_RC_REFERENCE_S2: return "TPM_RC_REFERENCE_S2";
124    case trunks::TPM_RC_REFERENCE_S3: return "TPM_RC_REFERENCE_S3";
125    case trunks::TPM_RC_REFERENCE_S4: return "TPM_RC_REFERENCE_S4";
126    case trunks::TPM_RC_REFERENCE_S5: return "TPM_RC_REFERENCE_S5";
127    case trunks::TPM_RC_REFERENCE_S6: return "TPM_RC_REFERENCE_S6";
128    case trunks::TPM_RC_NV_RATE: return "TPM_RC_NV_RATE";
129    case trunks::TPM_RC_LOCKOUT: return "TPM_RC_LOCKOUT";
130    case trunks::TPM_RC_RETRY: return "TPM_RC_RETRY";
131    case trunks::TPM_RC_NV_UNAVAILABLE: return "TPM_RC_NV_UNAVAILABLE";
132    case trunks::TPM_RC_NOT_USED: return "TPM_RC_NOT_USED";
133    case trunks::TRUNKS_RC_AUTHORIZATION_FAILED:
134      return "TRUNKS_RC_AUTHORIZATION_FAILED";
135    case trunks::TRUNKS_RC_ENCRYPTION_FAILED:
136      return "TRUNKS_RC_ENCRYPTION_FAILED";
137    case trunks::TRUNKS_RC_READ_ERROR: return "TRUNKS_RC_READ_ERROR";
138    case trunks::TRUNKS_RC_WRITE_ERROR: return "TRUNKS_RC_WRITE_ERROR";
139    case trunks::TRUNKS_RC_IPC_ERROR: return "TRUNKS_RC_IPC_ERROR";
140    case trunks::TRUNKS_RC_SESSION_SETUP_ERROR:
141      return "TRUNKS_RC_SESSION_SETUP_ERROR";
142    case trunks::TCTI_RC_TRY_AGAIN: return "TCTI_RC_TRY_AGAIN";
143    case trunks::TCTI_RC_GENERAL_FAILURE: return "TCTI_RC_GENERAL_FAILURE";
144    case trunks::TCTI_RC_BAD_CONTEXT: return "TCTI_RC_BAD_CONTEXT";
145    case trunks::TCTI_RC_WRONG_ABI_VERSION: return "TCTI_RC_WRONG_ABI_VERSION";
146    case trunks::TCTI_RC_NOT_IMPLEMENTED: return "TCTI_RC_NOT_IMPLEMENTED";
147    case trunks::TCTI_RC_BAD_PARAMETER: return "TCTI_RC_BAD_PARAMETER";
148    case trunks::TCTI_RC_INSUFFICIENT_BUFFER:
149      return "TCTI_RC_INSUFFICIENT_BUFFER";
150    case trunks::TCTI_RC_NO_CONNECTION: return "TCTI_RC_NO_CONNECTION";
151    case trunks::TCTI_RC_DRIVER_NOT_FOUND: return "TCTI_RC_DRIVER_NOT_FOUND";
152    case trunks::TCTI_RC_DRIVERINFO_NOT_FOUND:
153      return "TCTI_RC_DRIVERINFO_NOT_FOUND";
154    case trunks::TCTI_RC_NO_RESPONSE: return "TCTI_RC_NO_RESPONSE";
155    case trunks::TCTI_RC_BAD_VALUE: return "TCTI_RC_BAD_VALUE";
156    case trunks::SAPI_RC_INVALID_SESSIONS: return "SAPI_RC_INVALID_SESSIONS";
157    case trunks::SAPI_RC_ABI_MISMATCH: return "SAPI_RC_ABI_MISMATCH";
158    case trunks::SAPI_RC_INSUFFICIENT_BUFFER:
159      return "SAPI_RC_INSUFFICIENT_BUFFER";
160    case trunks::SAPI_RC_BAD_PARAMETER: return "SAPI_RC_BAD_PARAMETER";
161    case trunks::SAPI_RC_BAD_SEQUENCE: return "SAPI_RC_BAD_SEQUENCE";
162    case trunks::SAPI_RC_NO_DECRYPT_PARAM: return "SAPI_RC_NO_DECRYPT_PARAM";
163    case trunks::SAPI_RC_NO_ENCRYPT_PARAM: return "SAPI_RC_NO_ENCRYPT_PARAM";
164    case trunks::SAPI_RC_NO_RESPONSE_RECEIVED:
165      return "SAPI_RC_NO_RESPONSE_RECEIVED";
166    case trunks::SAPI_RC_BAD_SIZE: return "SAPI_RC_BAD_SIZE";
167    case trunks::SAPI_RC_CORRUPTED_DATA: return "SAPI_RC_CORRUPTED_DATA";
168    case trunks::SAPI_RC_INSUFFICIENT_CONTEXT:
169      return "SAPI_RC_INSUFFICIENT_CONTEXT";
170    case trunks::SAPI_RC_INSUFFICIENT_RESPONSE:
171      return "SAPI_RC_INSUFFICIENT_RESPONSE";
172    case trunks::SAPI_RC_INCOMPATIBLE_TCTI: return "SAPI_RC_INCOMPATIBLE_TCTI";
173    case trunks::SAPI_RC_MALFORMED_RESPONSE:
174      return "SAPI_RC_MALFORMED_RESPONSE";
175    case trunks::SAPI_RC_BAD_TCTI_STRUCTURE:
176      return "SAPI_RC_BAD_TCTI_STRUCTURE";
177    default: return std::string();
178  }
179  NOTREACHED();
180  return std::string();
181}
182
183bool IsFormatOne(trunks::TPM_RC error) {
184  return (error & kLayerMask) == 0 && (error & trunks::RC_FMT1) != 0;
185}
186
187}  // namespace
188
189namespace trunks {
190
191std::string GetErrorString(TPM_RC error) {
192  std::string error_string = GetErrorStringInternal(error);
193  if (!error_string.empty()) {
194    return error_string;
195  }
196  std::stringstream ss;
197  if ((error & kLayerMask) == kResourceManagerTpmErrorBase) {
198    error &= ~kLayerMask;
199    error_string = GetErrorStringInternal(error);
200    ss << "Resource Manager: ";
201  }
202  // Check if we have a TPM 'Format-One' response code.
203  if (IsFormatOne(error)) {
204    if (error & TPM_RC_P) {
205      ss << "Parameter ";
206    } else if (error & TPM_RC_S) {
207      ss << "Session ";
208    } else {
209      ss << "Handle ";
210    }
211    // Bits 8-10 specify which handle / parameter / session.
212    ss << ((error & kFormatOneSubjectMask) >> 8) << ": ";
213    // Mask out everything but the format bit and error number.
214    error_string = GetErrorStringInternal(error & kFormatOneErrorMask);
215    if (!error_string.empty()) {
216      ss << error_string;
217    }
218  }
219  if (error_string.empty()) {
220    ss << "Unknown error: " << error << " (0x" << std::hex << error << ")";
221  }
222  return ss.str();
223}
224
225TPM_RC GetFormatOneError(TPM_RC error) {
226  if (IsFormatOne(error)) {
227    return (error & kFormatOneErrorMask);
228  }
229  return error;
230}
231
232std::string CreateErrorResponse(TPM_RC error_code) {
233  const uint32_t kErrorResponseSize = 10;
234  std::string response;
235  CHECK_EQ(Serialize_TPM_ST(TPM_ST_NO_SESSIONS, &response), TPM_RC_SUCCESS);
236  CHECK_EQ(Serialize_UINT32(kErrorResponseSize, &response), TPM_RC_SUCCESS);
237  CHECK_EQ(Serialize_TPM_RC(error_code, &response), TPM_RC_SUCCESS);
238  return response;
239}
240
241}  // namespace trunks
242